import { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import cookieParser from 'cookie-parser'; import request from 'supertest'; import { App } from 'supertest/types.js'; import { AppModule } from './../src/app.module.js'; import { ServiceLayerClient } from './../src/service-layer/service-layer.client.js'; import { SessionStore } from './../src/service-layer/session.store.js'; // El Service Layer se reemplaza por uno falso que acepta cualquier login (y registra la sesión en el // almacén real): lo que se comprueba es la cookie de sesión que la API entrega al navegador, no SAP. describe('Cookie de sesión (e2e)', () => { let app: INestApplication; async function crear(cookieSecure: boolean) { process.env.SL_URL = 'https://localhost:50000/b1s/v1'; process.env.SL_COMPANY_DB = 'TEST'; process.env.DB_TYPE = 'MSSQL'; process.env.COOKIE_SECURE = String(cookieSecure); const modulo = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(ServiceLayerClient) .useFactory({ inject: [SessionStore], factory: (sesiones: SessionStore) => ({ login: async () => sesiones.crear({ b1Session: 'b', userName: 'u', companyDb: 'X', version: '1', timeoutMinutes: 30 }), logout: async () => undefined, }), }) .compile(); app = modulo.createNestApplication(); app.setGlobalPrefix('api'); app.use(cookieParser()); await app.init(); } const loguear = async () => { const r = await request(app.getHttpServer()).post('/api/auth/login').send({ userName: 'u', password: 'p' }).expect(200); return (r.headers['set-cookie'] as unknown as string[]).find((c) => c.startsWith('dp_sid=')) ?? ''; }; afterEach(async () => { await app.close(); delete process.env.COOKIE_SECURE; }); it('con COOKIE_SECURE=true la cookie es HttpOnly, Secure, SameSite=Strict y de toda la aplicación', async () => { await crear(true); const cookie = await loguear(); expect(cookie).toMatch(/^dp_sid=[0-9a-f]{64};/); expect(cookie).toContain('HttpOnly'); expect(cookie).toContain('Secure'); expect(cookie).toContain('SameSite=Strict'); expect(cookie).toContain('Path=/'); }); it('con COOKIE_SECURE=false (desarrollo por HTTP) no lleva Secure, pero sigue HttpOnly y Strict', async () => { await crear(false); const cookie = await loguear(); expect(cookie).toContain('HttpOnly'); expect(cookie).toContain('SameSite=Strict'); expect(cookie).not.toContain('Secure'); }); it('con esa cookie el navegador queda autenticado; sin ella, no', async () => { await crear(true); const cookie = await loguear(); await request(app.getHttpServer()).get('/api/auth/me').expect(401); await request(app.getHttpServer()).get('/api/auth/me').set('Cookie', cookie.split(';')[0]).expect(200); }); });