diff --git a/internal/server/auth/method/github/server.go b/internal/server/auth/method/github/server.go index 4a4887e848..f997eeace5 100644 --- a/internal/server/auth/method/github/server.go +++ b/internal/server/auth/method/github/server.go @@ -32,10 +32,11 @@ type OAuth2Client interface { } const ( - storageMetadataGithubEmail = "io.flipt.auth.github.email" - storageMetadataGithubName = "io.flipt.auth.github.name" - storageMetadataGithubPicture = "io.flipt.auth.github.picture" - storageMetadataGithubSub = "io.flipt.auth.github.sub" + storageMetadataGithubEmail = "io.flipt.auth.github.email" + storageMetadataGithubName = "io.flipt.auth.github.name" + storageMetadataGithubPicture = "io.flipt.auth.github.picture" + storageMetadataGithubSub = "io.flipt.auth.github.sub" + storageMetadataGitHubPreferredUsername = "io.flipt.auth.github.preferred_username" ) // Server is an Github server side handler. @@ -140,6 +141,7 @@ func (s *Server) Callback(ctx context.Context, r *auth.CallbackRequest) (*auth.C Name string `json:"name,omitempty"` Email string `json:"email,omitempty"` AvatarURL string `json:"avatar_url,omitempty"` + Login string `json:"login,omitempty"` ID uint64 `json:"id,omitempty"` } @@ -165,6 +167,10 @@ func (s *Server) Callback(ctx context.Context, r *auth.CallbackRequest) (*auth.C metadata[storageMetadataGithubSub] = fmt.Sprintf("%d", githubUserResponse.ID) } + if githubUserResponse.Login != "" { + metadata[storageMetadataGitHubPreferredUsername] = githubUserResponse.Login + } + clientToken, a, err := s.store.CreateAuthentication(ctx, &storageauth.CreateAuthenticationRequest{ Method: auth.Method_METHOD_GITHUB, ExpiresAt: timestamppb.New(time.Now().UTC().Add(s.config.Session.TokenLifetime)), diff --git a/internal/server/auth/method/oidc/server.go b/internal/server/auth/method/oidc/server.go index 5e3b228c12..a4d7e931d5 100644 --- a/internal/server/auth/method/oidc/server.go +++ b/internal/server/auth/method/oidc/server.go @@ -19,13 +19,14 @@ import ( ) const ( - storageMetadataOIDCProviderKey = "io.flipt.auth.oidc.provider" - storageMetadataIDEmailKey = "io.flipt.auth.oidc.email" - storageMetadataIDEmailVerifiedKey = "io.flipt.auth.oidc.email_verified" - storageMetadataIDNameKey = "io.flipt.auth.oidc.name" - storageMetadataIDProfileKey = "io.flipt.auth.oidc.profile" - storageMetadataIDPictureKey = "io.flipt.auth.oidc.picture" - storageMetadataIDSubKey = "io.flipt.auth.oidc.sub" + storageMetadataOIDCProvider = "io.flipt.auth.oidc.provider" + storageMetadataOIDCEmail = "io.flipt.auth.oidc.email" + storageMetadataOIDCEmailVerified = "io.flipt.auth.oidc.email_verified" + storageMetadataOIDCName = "io.flipt.auth.oidc.name" + storageMetadataOIDCProfile = "io.flipt.auth.oidc.profile" + storageMetadataOIDCPicture = "io.flipt.auth.oidc.picture" + storageMetadataOIDCSub = "io.flipt.auth.oidc.sub" + storageMetadataOIDCPreferredUsername = "io.flipt.auth.oidc.preferred_username" ) // errProviderNotFound is returned when a provider is requested which @@ -133,7 +134,7 @@ func (s *Server) Callback(ctx context.Context, req *auth.CallbackRequest) (_ *au } metadata := map[string]string{ - storageMetadataOIDCProviderKey: req.Provider, + storageMetadataOIDCProvider: req.Provider, } // Extract custom claims @@ -230,13 +231,13 @@ func (c claims) addToMetadata(m map[string]string) { } } - set(storageMetadataIDEmailKey, c.Email) - set(storageMetadataIDNameKey, c.Name) - set(storageMetadataIDProfileKey, c.Profile) - set(storageMetadataIDPictureKey, c.Picture) - set(storageMetadataIDSubKey, c.Sub) + set(storageMetadataOIDCEmail, c.Email) + set(storageMetadataOIDCName, c.Name) + set(storageMetadataOIDCProfile, c.Profile) + set(storageMetadataOIDCPicture, c.Picture) + set(storageMetadataOIDCSub, c.Sub) if c.Verified != nil { - m[storageMetadataIDEmailVerifiedKey] = fmt.Sprintf("%v", *c.Verified) + m[storageMetadataOIDCEmailVerified] = fmt.Sprintf("%v", *c.Verified) } } diff --git a/magefile.go b/magefile.go index bc673ef774..9e4cf7eced 100644 --- a/magefile.go +++ b/magefile.go @@ -137,12 +137,13 @@ type Go mg.Namespace // Keeping these aliases for backwards compatibility for now var Aliases = map[string]interface{}{ - "dev": Go.Run, - "test": Go.Test, - "bench": Go.Bench, - "lint": Go.Lint, - "fmt": Go.Fmt, - "proto": Go.Proto, + "dev": Go.Run, + "test": Go.Test, + "bench": Go.Bench, + "lint": Go.Lint, + "fmt": Go.Fmt, + "proto": Go.Proto, + "ui:dev": UI.Run, } // Runs Go benchmarking tests diff --git a/ui/src/components/header/ReadOnly.tsx b/ui/src/components/header/ReadOnly.tsx index 03a5efeb5f..66fcda287d 100644 --- a/ui/src/components/header/ReadOnly.tsx +++ b/ui/src/components/header/ReadOnly.tsx @@ -8,6 +8,7 @@ import { import { useSelector } from 'react-redux'; import { selectConfig } from '~/app/meta/metaSlice'; import { Icon } from '~/types/Icon'; +import { titleCase } from '~/utils/helpers'; const storageTypes: Record = { local: DocumentIcon, @@ -27,10 +28,12 @@ export default function ReadOnly() { return ( {StorageIcon && ( - diff --git a/ui/src/components/header/UserProfile.tsx b/ui/src/components/header/UserProfile.tsx index f6eea8c818..054a2e06c8 100644 --- a/ui/src/components/header/UserProfile.tsx +++ b/ui/src/components/header/UserProfile.tsx @@ -19,19 +19,27 @@ export default function UserProfile(props: UserProfileProps) { const { clearSession } = useSession(); let name: string | undefined; + let login: string | undefined; let imgURL: string | undefined; if (metadata) { + // TODO: dry this up if ('io.flipt.auth.github.name' in metadata) { name = metadata['io.flipt.auth.github.name'] ?? 'User'; if (metadata['io.flipt.auth.github.picture']) { imgURL = metadata['io.flipt.auth.github.picture']; } + if (metadata['io.flipt.auth.github.preferred_username']) { + login = metadata['io.flipt.auth.github.preferred_username']; + } } else if ('io.flipt.auth.oidc.name' in metadata) { name = metadata['io.flipt.auth.oidc.name'] ?? 'User'; if (metadata['io.flipt.auth.oidc.picture']) { imgURL = metadata['io.flipt.auth.oidc.picture']; } + if (metadata['io.flipt.auth.oidc.preferred_username']) { + login = metadata['io.flipt.auth.oidc.preferred_username']; + } } } @@ -49,11 +57,11 @@ export default function UserProfile(props: UserProfileProps) { return (
- + Open user menu {imgURL && ( {name} + + {({ active }) => ( + + {name} + {login && ( + {login} + )} + + )} + {({ active }) => ( word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); +} + export function stringAsKey(str: string) { return str.toLowerCase().split(/\s+/).join('-');