kundencenter/apps/api/test/helpers.ts
2026-09-27 00:51:32 +02:00

23 lines
1.7 KiB
TypeScript

import type { FastifyInstance } from 'fastify';
import { randomUUID } from 'node:crypto';
import { hash } from '@node-rs/argon2';
import * as OTPAuth from 'otpauth';
import { run } from '../src/core/db.js';
export interface Client { cookie: string; csrf: string }
export async function makeUser(o: { email: string; kind?: 'customer' | 'staff'; staffRole?: string; password?: string }) {
const id = randomUUID();
await run("INSERT INTO users (id,email,name,password_hash,kind,staff_role,status) VALUES (?,?,?,?,?,?, 'active')", [id, o.email, o.email, await hash(o.password ?? 'correct-horse-battery'), o.kind ?? 'customer', o.staffRole ?? null]);
return id;
}
export async function login(app: FastifyInstance, email: string, password = 'correct-horse-battery'): Promise<{ res: any; client: Client }> {
const res = await app.inject({ method: 'POST', url: '/v1/auth/login', payload: { email, password } });
const cookie = (res.cookies[0] ? `${res.cookies[0].name}=${res.cookies[0].value}` : '');
const body = res.json();
return { res, client: { cookie, csrf: body.csrf } };
}
export const call = (app: FastifyInstance, c: Client, method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', url: string, payload?: unknown) =>
app.inject({ method, url: `/v1${url}`, payload: payload as never, headers: { cookie: c.cookie, 'x-csrf-token': c.csrf } });
export const code = (secret: string) => new OTPAuth.TOTP({ secret: OTPAuth.Secret.fromBase32(secret), digits: 6, period: 30 }).generate();
/** Nächster gültiger Code (für zweiten Schritt innerhalb desselben Tests, da Wiederverwendung verboten ist). */
export const nextCode = (secret: string) => new OTPAuth.TOTP({ secret: OTPAuth.Secret.fromBase32(secret), digits: 6, period: 30 }).generate({ timestamp: Date.now() + 30000 });