Files
kalendartool/lib/invites/tokens.ts

45 lines
1.4 KiB
TypeScript

/**
* Invite-System (plan.md Abschnitt 3 und 9).
*
* - Token wird zufaellig und nicht erratbar erzeugt (crypto.randomBytes).
* - In der Datenbank liegt NUR der SHA-256-Hash des Tokens.
* - Der Klartext-Token wird genau einmal beim Erstellen zurueckgegeben.
*/
import { createHash, randomBytes } from 'node:crypto';
/** Laenge des rohen Tokens in Bytes (256 Bit Entropie -> nicht erratbar). */
const TOKEN_BYTE_LENGTH = 32;
/** Invite-Links laufen standardmaessig nach 7 Tagen ab. */
export const INVITE_DEFAULT_TTL_DAYS = 7;
/** Erzeugt einen neuen, nicht erratbaren Invite-Token (Klartext). */
export function generateInviteToken(): string {
return randomBytes(TOKEN_BYTE_LENGTH).toString('base64url');
}
/** Berechnet den SHA-256-Hash eines Tokens fuer die Datenbank. */
export function hashInviteToken(token: string): string {
return createHash('sha256').update(token).digest('hex');
}
/** Standard-Ablaufzeit fuer neue Invites. */
export function defaultInviteExpiry(now: Date = new Date()): Date {
const expiry = new Date(now);
expiry.setDate(expiry.getDate() + INVITE_DEFAULT_TTL_DAYS);
return expiry;
}
/** Ist ein Invite gueltig (nicht abgelaufen, nicht verwendet)? */
export function isInviteUsable(
invite: { expiresAt: Date | null; usedAt: Date | null },
now: Date = new Date(),
): boolean {
if (invite.usedAt !== null) {
return false;
}
if (invite.expiresAt !== null && invite.expiresAt <= now) {
return false;
}
return true;
}