Neuer User-JWT-Pfad GET/POST /api/v1/me/{export,delete} — gespiegelte
DSGVO-Logik aus dem Service-Key-Pfad, aber gegen die eigene User-ID
gated. buildUserExport extrahiert in dsgvo.ts und wird von beiden
Routern geteilt.
/account-Page zeigt User-ID, Logout, JSON-Daten-Export (Download als
Blob), und einen rot-markierten Account-Delete-Knopf mit "LÖSCHEN"-
Confirmation. Logout im Header verlinkt jetzt auf /account statt
direkt clear() — der User sieht zuerst, was an seinem Account hängt.
Andere mana-Apps werden nicht mit gelöscht — der UI-Hinweistext zeigt
auf die spätere Verein-DSGVO-Sammelanfrage über mana-admin.
48 API-Tests grün (+2 neue auth-gate-Tests für /me), web type-check
374 files 0 errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
31 lines
916 B
TypeScript
31 lines
916 B
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { Hono } from 'hono';
|
|
|
|
import { meRouter } from '../src/routes/me.ts';
|
|
import type { CardsDb } from '../src/db/connection.ts';
|
|
|
|
/**
|
|
* Auth-Gate-Test ohne echte DB. Der Stub-DB kann keine Drizzle-
|
|
* Queries beantworten — wir prüfen nur, dass die Route den
|
|
* authMiddleware-Pfad ehrt.
|
|
*/
|
|
function buildApp() {
|
|
const app = new Hono();
|
|
const stub = {} as CardsDb;
|
|
app.route('/api/v1/me', meRouter({ db: stub }));
|
|
return { app };
|
|
}
|
|
|
|
describe('meRouter — auth-gate', () => {
|
|
it('GET /export ohne X-User-Id ist 401', async () => {
|
|
const { app } = buildApp();
|
|
const res = await app.request('/api/v1/me/export');
|
|
expect(res.status).toBe(401);
|
|
});
|
|
|
|
it('POST /delete ohne X-User-Id ist 401', async () => {
|
|
const { app } = buildApp();
|
|
const res = await app.request('/api/v1/me/delete', { method: 'POST' });
|
|
expect(res.status).toBe(401);
|
|
});
|
|
});
|