import { NestFactory, Reflector } from '@nestjs/core'; import { AppModule } from './app.module'; import { ModulesGuard } from './common/guards/modules.guard'; import * as session from 'express-session'; import * as passport from 'passport'; import { PrismaSessionStore } from '@quixo3/prisma-session-store'; import { PrismaPostgresService } from 'prisma/postgres/prisma-postgres.service'; const SESSION_TOKEN_DURATION_MINUTES = 180 async function bootstrap() { BigInt.prototype['toJSON'] = function () { return Number(this) }; const app = await NestFactory.create(AppModule); const prisma_postgres = app.get(PrismaPostgresService); const reflector = app.get(Reflector); app.useGlobalGuards( new ModulesGuard(reflector), ); // Authentication and session app.use(session({ secret: process.env.SESSION_SECRET || 'dev-only-secret-change-in-production', resave: false, saveUninitialized: false, rolling: true, cookie: { maxAge: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, // property maxAge requires milliseconds httpOnly: true, }, store: new PrismaSessionStore(prisma_postgres, { sessionModelName: 'sessions', checkPeriod: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, //ms dbRecordIdIsSessionId: true, dbRecordIdFunction: undefined, }) })) app.use(passport.initialize()); app.use(passport.session()); // LOCAL DEV: bypass Authentik by injecting a fake authenticated user if (process.env.DEV_BYPASS_AUTH === 'true') { console.log('⚠ DEV_BYPASS_AUTH enabled — all requests authenticated as louis@targo.ca'); app.use((req, _res, next) => { if (!req.user) { req.user = { first_name: 'Louis', last_name: 'Paul', email: 'louis@targo.ca', role: 'ADMIN', user_module_access: ['timesheets', 'timesheets_approval', 'employee_list', 'employee_management', 'personal_profile', 'dashboard'], }; req.isAuthenticated = () => true; } next(); }); } // Enable CORS app.enableCors({ origin: true, // allow all origins in dev credentials: true, }); await app.listen(process.env.PORT ?? 3000); } bootstrap();