feat(users): allow profile picture change for external providers (#4275)

This commit is contained in:
Meier Lukas
2025-10-13 23:52:17 +02:00
committed by GitHub
parent 35a8ac820f
commit 5c86930220
4 changed files with 25 additions and 35 deletions

View File

@@ -92,38 +92,24 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => {
});
}, [mutate, user.id, openConfirmModal, tManageAvatar]);
const isCredentialsUser = user.provider === "credentials";
return (
<Box pos="relative">
<Menu
opened={opened}
keepMounted
onChange={isCredentialsUser ? toggle : undefined}
position="bottom-start"
withArrow
>
<Menu opened={opened} keepMounted onChange={toggle} position="bottom-start" withArrow>
<Menu.Target>
<UnstyledButton
component={isCredentialsUser ? undefined : "div"}
style={{ cursor: !isCredentialsUser ? "default" : undefined }}
onClick={isCredentialsUser ? toggle : undefined}
>
<UnstyledButton onClick={toggle}>
<UserAvatar user={user} size={200} />
{isCredentialsUser && (
<Button
component="div"
pos="absolute"
bottom={0}
left={0}
size="compact-md"
fw="normal"
variant="default"
leftSection={<IconPencil size={18} stroke={1.5} />}
>
{t("common.action.edit")}
</Button>
)}
<Button
component="div"
pos="absolute"
bottom={0}
left={0}
size="compact-md"
fw="normal"
variant="default"
leftSection={<IconPencil size={18} stroke={1.5} />}
>
{t("common.action.edit")}
</Button>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>

View File

@@ -146,13 +146,6 @@ export const userRouter = createTRPCRouter({
});
}
if (user.provider !== "credentials") {
throw new TRPCError({
code: "FORBIDDEN",
message: "Profile image can not be changed for users with external providers",
});
}
await ctx.db
.update(users)
.set({

View File

@@ -20,6 +20,7 @@ export const createSignInEventHandler = (db: Database): Exclude<NextAuthConfig["
where: eq(users.id, user.id),
columns: {
name: true,
image: true,
colorScheme: true,
},
});
@@ -59,6 +60,15 @@ export const createSignInEventHandler = (db: Database): Exclude<NextAuthConfig["
`Username for user of oidc provider has changed. user=${user.id} old='${dbUser.name}' new='${profileUsername}'`,
);
}
if (
typeof profile.picture === "string" &&
dbUser.image !== profile.picture &&
!dbUser.image?.startsWith("data:")
) {
await db.update(users).set({ image: profile.picture }).where(eq(users.id, user.id));
logger.info(`Profile picture for user of oidc provider has changed. user=${user.id}'`);
}
}
logger.info(`User '${dbUser.name}' logged in at ${dayjs().format()}`);

View File

@@ -61,6 +61,7 @@ export const OidcProvider = (headers: ReadonlyHeaders | null): OIDCConfig<Profil
id: profile.sub,
name,
email: profile.email,
image: typeof profile.picture === "string" ? profile.picture : null,
provider: "oidc",
};
},