feat: Add profile pictures to OAuth users (#3855)

This supports GitHub and OIDC login for profile pictures!
This commit is contained in:
Kyle Carberry
2022-09-04 11:44:27 -05:00
committed by GitHub
parent 67c4605370
commit 05e2806ff3
23 changed files with 139 additions and 33 deletions
+1
View File
@@ -458,6 +458,7 @@ export interface User {
readonly status: UserStatus
readonly organization_ids: string[]
readonly roles: Role[]
readonly avatar_url: string
}
// From codersdk/users.go
@@ -51,6 +51,7 @@ describe("NavbarView", () => {
const mockUser = {
...MockUser,
username: "bryan",
avatar_url: "",
}
// When
+11 -2
View File
@@ -5,8 +5,17 @@ import { firstLetter } from "../../util/firstLetter"
export interface UserAvatarProps {
className?: string
username: string
avatarURL: string
}
export const UserAvatar: FC<UserAvatarProps> = ({ username, className }) => {
return <Avatar className={className}>{firstLetter(username)}</Avatar>
export const UserAvatar: FC<UserAvatarProps> = ({ username, className, avatarURL }) => {
return (
<Avatar className={className}>
{avatarURL ? (
<img alt={`${username}'s Avatar`} src={avatarURL} width="100%" />
) : (
firstLetter(username)
)}
</Avatar>
)
}
@@ -13,6 +13,7 @@ export const AuditLogExample = Template.bind({})
AuditLogExample.args = {
Avatar: {
username: MockUser.username,
avatarURL: "",
},
caption: MockUserAgent.ip_address,
primaryText: MockUser.email,
@@ -25,6 +26,7 @@ export const AuditLogEmptyUserExample = Template.bind({})
AuditLogEmptyUserExample.args = {
Avatar: {
username: MockUser.username,
avatarURL: "",
},
caption: MockUserAgent.ip_address,
primaryText: "Deleted User",
@@ -7,6 +7,7 @@ namespace Helpers {
export const Props: UserCellProps = {
Avatar: {
username: MockUser.username,
avatarURL: "",
},
caption: MockUserAgent.ip_address,
primaryText: MockUser.username,
@@ -37,7 +37,7 @@ export const UserDropdown: React.FC<React.PropsWithChildren<UserDropdownProps>>
>
<div className={styles.inner}>
<Badge overlap="circle">
<UserAvatar username={user.username} />
<UserAvatar username={user.username} avatarURL={user.avatar_url} />
</Badge>
{anchorEl ? <CloseDropdown /> : <OpenDropdown />}
</div>
@@ -38,7 +38,11 @@ export const UserDropdownContent: FC<UserDropdownContentProps> = ({
<div className={styles.userInfo}>
<div className={styles.root}>
<div className={styles.avatarContainer}>
<UserAvatar className={styles.avatar} username={user.username} />
<UserAvatar
className={styles.avatar}
username={user.username}
avatarURL={user.avatar_url}
/>
</div>
<Typography className={styles.userName}>{user.username}</Typography>
<Typography className={styles.userEmail}>{user.email}</Typography>
@@ -72,7 +72,20 @@ export const UsersTableBody: FC<React.PropsWithChildren<UsersTableBodyProps>> =
return (
<TableRow key={user.id}>
<TableCell>
<AvatarData title={user.username} subtitle={user.email} highlightTitle />
<AvatarData
title={user.username}
subtitle={user.email}
highlightTitle
avatar={
user.avatar_url ? (
<img
className={styles.avatar}
alt={`${user.username}'s Avatar`}
src={user.avatar_url}
/>
) : null
}
/>
</TableCell>
<TableCell
className={combineClasses([
@@ -139,4 +152,9 @@ const useStyles = makeStyles((theme) => ({
suspended: {
color: theme.palette.text.secondary,
},
avatar: {
width: theme.spacing(4.5),
height: theme.spacing(4.5),
borderRadius: "100%",
},
}))
@@ -37,6 +37,7 @@ describe("AccountPage", () => {
status: "active",
organization_ids: ["123"],
roles: [],
avatar_url: "",
...data,
}),
)
+4
View File
@@ -70,6 +70,7 @@ export const MockUser: TypesGen.User = {
status: "active",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [MockOwnerRole],
avatar_url: "https://github.com/coder.png",
}
export const MockUserAdmin: TypesGen.User = {
@@ -80,6 +81,7 @@ export const MockUserAdmin: TypesGen.User = {
status: "active",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [MockUserAdminRole],
avatar_url: "",
}
export const MockUser2: TypesGen.User = {
@@ -90,6 +92,7 @@ export const MockUser2: TypesGen.User = {
status: "active",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [],
avatar_url: "",
}
export const SuspendedMockUser: TypesGen.User = {
@@ -100,6 +103,7 @@ export const SuspendedMockUser: TypesGen.User = {
status: "suspended",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [],
avatar_url: "",
}
export const MockOrganization: TypesGen.Organization = {