retrotoon-studio/server/auth.logout.test.ts
Ubuntu 20a643c4ce fix: audit complet et pipeline fonctionnel RetroToon Studio
Corrections critiques:
- Fix titre HTML {{project_title}} -> %VITE_APP_TITLE%
- Suppression vitePluginManusRuntime (360KB -> 4KB index.html)
- Upload vidéo: multer au lieu du parsing binary maison (anti-corruption)
- Extraction audio ffmpeg + sauvegarde sourceAudioUrl en DB
- Page /login dédiée + correction redirect auth
- Test moteurs IA: vrai HEAD request avec latence
- Suppression spam logs [Auth] Missing session cookie
- Fix fuite passwordHash dans auth.me
- Cookie sameSite: none -> lax (CSRF)

Sécurité:
- Endpoints admin protégés par adminProcedure (role=admin requis)
- Sidebar admin masquée pour non-admins
- AdminPanel: page accès refusé pour non-admins
- Bootstrap admin optimisé (skip rehash si identique)

Fonctionnalités:
- Export vidéo MP4 réel via ffmpeg local (H.264 + AAC audio)
- Download parallèle par batch de 20 (export 10x plus rapide)
- Détection de scènes réelle via ffmpeg scene detect
- Analyse arrière-plans via Gemini Vision (remplace Math.random)
- Gemini: conservation du role system + support image_url
- Suppression thinking.budget_tokens:128 (LLM config)
- Thumbnails de frames dans la timeline
- Toast export avec bouton télécharger
- Endpoint extraction audio à la demande

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 01:37:08 +00:00

62 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { appRouter } from "./routers";
import { COOKIE_NAME } from "../shared/const";
import type { TrpcContext } from "./_core/context";
type CookieCall = {
name: string;
options: Record<string, unknown>;
};
type AuthenticatedUser = NonNullable<TrpcContext["user"]>;
function createAuthContext(): { ctx: TrpcContext; clearedCookies: CookieCall[] } {
const clearedCookies: CookieCall[] = [];
const user: AuthenticatedUser = {
id: 1,
openId: "sample-user",
email: "sample@example.com",
name: "Sample User",
loginMethod: "manus",
role: "user",
createdAt: new Date(),
updatedAt: new Date(),
lastSignedIn: new Date(),
};
const ctx: TrpcContext = {
user,
req: {
protocol: "https",
headers: {},
} as TrpcContext["req"],
res: {
clearCookie: (name: string, options: Record<string, unknown>) => {
clearedCookies.push({ name, options });
},
} as TrpcContext["res"],
};
return { ctx, clearedCookies };
}
describe("auth.logout", () => {
it("clears the session cookie and reports success", async () => {
const { ctx, clearedCookies } = createAuthContext();
const caller = appRouter.createCaller(ctx);
const result = await caller.auth.logout();
expect(result).toEqual({ success: true });
expect(clearedCookies).toHaveLength(1);
expect(clearedCookies[0]?.name).toBe(COOKIE_NAME);
expect(clearedCookies[0]?.options).toMatchObject({
maxAge: -1,
secure: true,
sameSite: "lax",
httpOnly: true,
path: "/",
});
});
});