Initial commit: Kalendartool (Next.js, Prisma, Docker)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
45
lib/invites/tokens.ts
Normal file
45
lib/invites/tokens.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user