export type TLoginSessionPrimaryAuthenticationMethod = 'magic_link' | 'passkey' | 'password' | 'saml'; export type TLoginSessionMfaFactor = 'backup_code' | 'passkey' | 'totp'; export interface ILoginSessionAuthenticationEvidence { primaryMethod: TLoginSessionPrimaryAuthenticationMethod; primaryAuthenticatedAt: number; mfaFactor: TLoginSessionMfaFactor | null; mfaAuthenticatedAt: number | null; } export interface ILoginSession { id: string; data: { userId: string; validUntil: number; invalidated: boolean; /** * Closed, server-derived authentication evidence used for freshness and * privileged step-up decisions. Refreshing a session must not advance * either authentication timestamp. */ authentication: ILoginSessionAuthenticationEvidence; refreshTokenHash?: string | null; rotatedRefreshTokenHashes?: string[] | null; /** * Hash of the single outstanding opaque transfer token. * * This field, `transferTokenExpiresAt`, and `transferTargetHash` describe * one transfer grant and must be set, replaced, and cleared together in a * single atomic persistence operation. */ transferTokenHash?: string | null; /** * Absolute expiry time, in Unix epoch milliseconds, for the outstanding * transfer grant. */ transferTokenExpiresAt?: number | null; /** * Server-derived binding hash of the canonical, authorized * `ITransferTarget.appUrl` for the outstanding transfer grant. * * Implementations must never persist the raw target URL in login-session * data. This field must be set, replaced, and cleared atomically with * `transferTokenHash` and `transferTokenExpiresAt`. */ transferTargetHash?: string | null; /** * a device id that can be used to share the login session * in different contexts on the same device */ deviceId?: string | null; /** * Device metadata for session display */ deviceInfo?: { deviceName: string; browser: string; os: string; ip: string; } | null; /** * When this session was created */ createdAt: number; /** * Last time this session was active (e.g., refreshed) */ lastActive: number; }; }