Skip to content

src/auth-session.ts

42 lines · 1.4 KB · TypeScript
Raw
/** In-flight OpenID+PKCE login state in package storage, for about 30 minutes. */

import { packageStorage } from 'kody:runtime'

export type AuthSession = {
	authSessionId: string
	codeVerifier: string
	locale: string
	serial: string
	withUsername: boolean
	createdAt: string
}

const PREFIX = 'auth-session:'
const LATEST = 'auth-session:latest'
const MAX_AGE_MS = 30 * 60 * 1000

export async function saveAuthSession(session: AuthSession): Promise<void> {
	await packageStorage().set(`${PREFIX}${session.authSessionId}`, session)
	await packageStorage().set(LATEST, session.authSessionId)
}

export async function loadAuthSession(authSessionId?: string): Promise<AuthSession | null> {
	const id = authSessionId?.trim() || String((await packageStorage().get(LATEST)) ?? '')
	if (!id) return null
	const raw = await packageStorage().get(`${PREFIX}${id}`)
	if (raw == null) return null
	const session = (typeof raw === 'string' ? JSON.parse(raw) : raw) as AuthSession
	if (!session?.codeVerifier || !session.serial) return null
	if (Date.now() - Date.parse(session.createdAt) > MAX_AGE_MS) {
		await deleteAuthSession(id)
		return null
	}
	return session
}

export async function deleteAuthSession(authSessionId: string): Promise<void> {
	await packageStorage().delete(`${PREFIX}${authSessionId}`)
	if ((await packageStorage().get(LATEST)) === authSessionId) {
		await packageStorage().delete(LATEST)
	}
}