60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
/**
|
|
* The payloads of the tokens the server signs, and their guards.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import { isRole, type Role } from "../../shared/user.ts";
|
|
|
|
/** What a session token carries. */
|
|
export interface AuthPayload {
|
|
/** The user's id. */
|
|
userId: string;
|
|
/** The user's name when the token was issued. */
|
|
username: string;
|
|
/**
|
|
* The user's role; the live one replaces it once the token is authenticated.
|
|
*/
|
|
role: Role;
|
|
/** When the token expires, in seconds since the epoch. */
|
|
exp: number;
|
|
/** When the token was issued, in seconds since the epoch. */
|
|
iat?: number;
|
|
}
|
|
|
|
/**
|
|
* Checks whether `obj` is an {@link AuthPayload}, and not a purpose-scoped
|
|
* token's payload.
|
|
*/
|
|
export function isAuthPayload(obj: unknown): obj is AuthPayload {
|
|
return !!obj &&
|
|
typeof obj === "object" &&
|
|
// Purpose-scoped tokens (password reset, media) are never session tokens.
|
|
!("purpose" in obj) &&
|
|
"userId" in obj && typeof obj.userId === "string" &&
|
|
"username" in obj && typeof obj.username === "string" &&
|
|
"role" in obj && isRole(obj.role) &&
|
|
"exp" in obj && typeof obj.exp === "number";
|
|
}
|
|
|
|
/** What a password reset token carries. */
|
|
export interface PasswordResetPayload {
|
|
/** The token's purpose, which makes it a reset token. */
|
|
purpose: "password-reset";
|
|
/** The id of the user whose password it resets. */
|
|
userId: string;
|
|
/** When the token expires, in seconds since the epoch. */
|
|
exp: number;
|
|
}
|
|
|
|
/** Checks whether `obj` is a {@link PasswordResetPayload}. */
|
|
export function isPasswordResetPayload(
|
|
obj: unknown,
|
|
): obj is PasswordResetPayload {
|
|
return !!obj && typeof obj === "object" &&
|
|
"purpose" in obj &&
|
|
(obj as Record<string, unknown>).purpose === "password-reset" &&
|
|
"userId" in obj &&
|
|
typeof (obj as Record<string, unknown>).userId === "string";
|
|
}
|