Serveur TypeScript (Fastify 5) permettant de déposer des fichiers médias
dans des dossiers nommés, via une page web de glisser-déposer.
- Authentification OpenID Connect gérée côté serveur (Authorization Code +
PKCE, client confidentiel, openid-client) ; session via cookie chiffré
(@fastify/secure-session).
- Configuration dans un fichier JSON (schéma fourni) ; l'environnement ne
porte que le pointeur MEDIADROP_CONFIG.
- Cibles de dépôt nommées : liste { name, label, dir }, sélection par
?target=, première cible par défaut.
- Upload multipart en streaming : nom de fichier dérivé côté serveur (pas
de path traversal), liste blanche de types MIME, plafond de taille.
- TypeScript strict, ESLint + Prettier sans warning, 46 tests Vitest.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||
import { describe, expect, it, vi } from 'vitest';
|
||
|
||
import { UnauthorizedError } from '../src/errors.js';
|
||
import { getSessionUser, requireSession, type SessionUser } from '../src/session.js';
|
||
|
||
function requestWithSessionUser(user: SessionUser | undefined): FastifyRequest {
|
||
return {
|
||
session: { get: (key: string) => (key === 'user' ? user : undefined) },
|
||
} as unknown as FastifyRequest;
|
||
}
|
||
|
||
const reply = {} as FastifyReply;
|
||
|
||
describe('getSessionUser', () => {
|
||
it('renvoie null quand il n’y a pas de session', () => {
|
||
expect(getSessionUser(requestWithSessionUser(undefined))).toBeNull();
|
||
});
|
||
|
||
it('renvoie null quand la session est expirée', () => {
|
||
const user: SessionUser = { sub: 'u1', name: 'Alice', expiresAt: Date.now() - 1000 };
|
||
expect(getSessionUser(requestWithSessionUser(user))).toBeNull();
|
||
});
|
||
|
||
it('renvoie l’utilisateur quand la session est valide', () => {
|
||
const user: SessionUser = { sub: 'u1', name: 'Alice', expiresAt: Date.now() + 60_000 };
|
||
expect(getSessionUser(requestWithSessionUser(user))).toEqual(user);
|
||
});
|
||
});
|
||
|
||
describe('requireSession', () => {
|
||
it('appelle done(UnauthorizedError) sans session', () => {
|
||
const done = vi.fn();
|
||
requireSession(requestWithSessionUser(undefined), reply, done);
|
||
expect(done).toHaveBeenCalledTimes(1);
|
||
expect(done.mock.calls[0]?.[0]).toBeInstanceOf(UnauthorizedError);
|
||
});
|
||
|
||
it('appelle done() avec une session valide', () => {
|
||
const done = vi.fn();
|
||
const user: SessionUser = { sub: 'u1', name: 'Alice', expiresAt: Date.now() + 60_000 };
|
||
requireSession(requestWithSessionUser(user), reply, done);
|
||
expect(done).toHaveBeenCalledWith();
|
||
});
|
||
});
|