refactor(frontend): make SessionUser fields non-null and normalize claims at boundary
This commit is contained in:
@@ -35,10 +35,10 @@
|
|||||||
<span
|
<span
|
||||||
class="grid h-7 w-7 place-items-center rounded-full bg-neutral-700 text-xs font-semibold uppercase"
|
class="grid h-7 w-7 place-items-center rounded-full bg-neutral-700 text-xs font-semibold uppercase"
|
||||||
>
|
>
|
||||||
{(user.name ?? user.email ?? '?').charAt(0)}
|
{user.name.charAt(0)}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="hidden sm:inline">{user.name ?? user.email}</span>
|
<span class="hidden sm:inline">{user.name}</span>
|
||||||
</a>
|
</a>
|
||||||
<form method="POST" action="/logout">
|
<form method="POST" action="/logout">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -70,17 +70,32 @@ export async function decodeSession(token: string | undefined): Promise<Session
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function claimString(value: unknown): string | undefined {
|
||||||
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toSessionUser(claims: Record<string, unknown>, fallback?: SessionUser): SessionUser {
|
||||||
|
const sub = claimString(claims.sub) ?? fallback?.sub ?? '';
|
||||||
|
return {
|
||||||
|
sub,
|
||||||
|
name:
|
||||||
|
claimString(claims.name) ??
|
||||||
|
claimString(claims.preferred_username) ??
|
||||||
|
fallback?.name ??
|
||||||
|
claimString(claims.email) ??
|
||||||
|
sub,
|
||||||
|
email: claimString(claims.email) ?? fallback?.email ?? '',
|
||||||
|
picture: claimString(claims.picture) ?? fallback?.picture ?? ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export async function refreshSession(session: Session): Promise<Session | null> {
|
export async function refreshSession(session: Session): Promise<Session | null> {
|
||||||
if (!session.refreshToken) return null;
|
if (!session.refreshToken) return null;
|
||||||
try {
|
try {
|
||||||
const config = await getOidcConfig();
|
const config = await getOidcConfig();
|
||||||
const tokens = await client.refreshTokenGrant(config, session.refreshToken);
|
const tokens = await client.refreshTokenGrant(config, session.refreshToken);
|
||||||
const claims = tokens.claims();
|
|
||||||
return {
|
return {
|
||||||
sub: session.sub,
|
...toSessionUser(tokens.claims() ?? {}, session),
|
||||||
name: (claims?.name as string | undefined) ?? session.name,
|
|
||||||
email: (claims?.email as string | undefined) ?? session.email,
|
|
||||||
picture: (claims?.picture as string | undefined) ?? session.picture,
|
|
||||||
accessToken: tokens.access_token,
|
accessToken: tokens.access_token,
|
||||||
refreshToken: tokens.refresh_token ?? session.refreshToken,
|
refreshToken: tokens.refresh_token ?? session.refreshToken,
|
||||||
idToken: tokens.id_token ?? session.idToken,
|
idToken: tokens.id_token ?? session.idToken,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export interface SessionUser {
|
export interface SessionUser {
|
||||||
sub: string;
|
sub: string;
|
||||||
name?: string;
|
name: string;
|
||||||
email?: string;
|
email: string;
|
||||||
picture?: string;
|
picture: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
getOidcConfig,
|
getOidcConfig,
|
||||||
encodeSession,
|
encodeSession,
|
||||||
sessionCookieOptions,
|
sessionCookieOptions,
|
||||||
|
toSessionUser,
|
||||||
type Session,
|
type Session,
|
||||||
SESSION_COOKIE,
|
SESSION_COOKIE,
|
||||||
STATE_COOKIE,
|
STATE_COOKIE,
|
||||||
@@ -44,10 +45,7 @@ export const GET: RequestHandler = async ({ url, cookies }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const session: Session = {
|
const session: Session = {
|
||||||
sub: String(claims.sub),
|
...toSessionUser(claims),
|
||||||
name: claims.name as string | undefined,
|
|
||||||
email: claims.email as string | undefined,
|
|
||||||
picture: claims.picture as string | undefined,
|
|
||||||
accessToken: tokens.access_token,
|
accessToken: tokens.access_token,
|
||||||
refreshToken: tokens.refresh_token,
|
refreshToken: tokens.refresh_token,
|
||||||
idToken: tokens.id_token,
|
idToken: tokens.id_token,
|
||||||
|
|||||||
Reference in New Issue
Block a user