diff --git a/Dockerfile b/Dockerfile index 3d335ef..75b7bde 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,4 +39,4 @@ COPY --from=builder /app/dist ./dist ENV NODE_ENV=production EXPOSE 3004 ENTRYPOINT ["dumb-init", "--"] -CMD ["sh", "-c", "cd packages/admin-db && npx prisma migrate deploy && cd /app && node dist/main.js"] +CMD ["sh", "-c", "cd packages/admin-db && npx prisma migrate deploy && if [ \"$RUN_SEED\" = \"true\" ]; then echo 'Seeding admin database...' && npx tsx prisma/seed.ts; fi && cd /app && node dist/main.js"] diff --git a/packages/admin-db/prisma/migrations/20260415000000_add_support_ticket_attachments/migration.sql b/packages/admin-db/prisma/migrations/20260415000000_add_support_ticket_attachments/migration.sql new file mode 100644 index 0000000..c75ee57 --- /dev/null +++ b/packages/admin-db/prisma/migrations/20260415000000_add_support_ticket_attachments/migration.sql @@ -0,0 +1,24 @@ +-- CreateTable: support_ticket_attachments +CREATE TABLE "support_ticket_attachments" ( + "id" TEXT NOT NULL, + "ticketId" TEXT NOT NULL, + "commentId" TEXT, + "fileName" TEXT NOT NULL, + "originalName" TEXT NOT NULL, + "mimeType" TEXT NOT NULL, + "sizeBytes" INTEGER NOT NULL, + "uploadedBy" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "support_ticket_attachments_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "support_ticket_attachments_ticketId_idx" ON "support_ticket_attachments"("ticketId"); +CREATE INDEX "support_ticket_attachments_commentId_idx" ON "support_ticket_attachments"("commentId"); + +-- AddForeignKey +ALTER TABLE "support_ticket_attachments" ADD CONSTRAINT "support_ticket_attachments_ticketId_fkey" + FOREIGN KEY ("ticketId") REFERENCES "support_tickets"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "support_ticket_attachments" ADD CONSTRAINT "support_ticket_attachments_commentId_fkey" + FOREIGN KEY ("commentId") REFERENCES "support_ticket_comments"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index accc86f..70881a9 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -6,6 +6,7 @@ import { import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import * as bcrypt from 'bcrypt'; +import { randomUUID } from 'crypto'; import { AdminPrismaService } from '../prisma/admin-prisma.service'; @Injectable() @@ -119,6 +120,7 @@ export class AuthService { sub: adminId, email, type: 'super_admin', + jti: randomUUID(), }); const refreshSecret = this.config.get( @@ -131,7 +133,7 @@ export class AuthService { ); const refreshToken = this.jwt.sign( - { sub: adminId, email, type: 'super_admin' }, + { sub: adminId, email, type: 'super_admin', jti: randomUUID() }, { secret: refreshSecret, expiresIn: refreshExpiresIn as any, diff --git a/src/impersonate/impersonate.service.ts b/src/impersonate/impersonate.service.ts index 4077922..720ca63 100644 --- a/src/impersonate/impersonate.service.ts +++ b/src/impersonate/impersonate.service.ts @@ -15,7 +15,7 @@ export class ImpersonateService { private readonly audit: AuditService, ) { // Use the MAIN API's JWT secret so the token works with the tenant API - this.mainJwtSecret = this.config.get('JWT_SECRET', 'dev-jwt-secret-not-for-production'); + this.mainJwtSecret = this.config.get('MAIN_API_JWT_SECRET', 'your-secret-key'); } async startImpersonation(tenantId: string, adminId: string, adminName: string) {