feat(02-01): Prisma schema expansion, RLS migration, and PrismaModule

- Add User, Role enum, PasswordResetToken, LdapConfig, LdapFieldMapping models
- Expand Tenant model with isActive, users relation, ldapConfig relation
- Create RLS migration with tenant isolation policies on all tenant-scoped tables
- Create PrismaModule (global), PrismaService, and forTenant extension
- Add JWT_SECRET, TESSERA_ADMIN_*, TESSERA_FORCE_CHANGE env vars to docker-compose
- Install @nestjs/jwt, @nestjs/passport, passport, argon2, class-validator deps
This commit is contained in:
2026-06-18 13:22:38 +02:00
parent dddc39f570
commit d0b36c8f22
11 changed files with 651 additions and 21 deletions
@@ -0,0 +1,24 @@
import { PrismaClient } from '@prisma/client';
/**
* Creates a tenant-scoped Prisma client that sets the app.current_tenant
* PostgreSQL session variable before every query via RLS.
*
* Uses parameterized set_config to prevent SQL injection (T-02-05).
*/
export function forTenant(prisma: PrismaClient, tenantId: string) {
return prisma.$extends({
query: {
$allOperations({ args, query }) {
return (prisma as any).$transaction(async (tx: any) => {
// Use parameterized query to avoid SQL injection
await tx.$executeRawUnsafe(
`SELECT set_config('app.current_tenant', $1, true)`,
tenantId,
);
return query(args);
});
},
},
});
}
+9
View File
@@ -0,0 +1,9 @@
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
+9
View File
@@ -0,0 +1,9 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}