diff --git a/apps/backend/src/application/auth/auth.service.ts b/apps/backend/src/application/auth/auth.service.ts index 004951f..04d02e8 100644 --- a/apps/backend/src/application/auth/auth.service.ts +++ b/apps/backend/src/application/auth/auth.service.ts @@ -11,6 +11,7 @@ import * as argon2 from 'argon2'; import { UserRepository, USER_REPOSITORY } from '@domain/ports/out/user.repository'; import { User, UserRole } from '@domain/entities/user.entity'; import { v4 as uuidv4 } from 'uuid'; +import { DEFAULT_ORG_ID } from '@infrastructure/persistence/typeorm/seeds/test-organizations.seed'; export interface JwtPayload { sub: string; // user ID @@ -221,8 +222,7 @@ export class AuthService { // Use default organization "Test Freight Forwarder Inc." if not provided // This ID comes from the seed migration 1730000000006-SeedOrganizations - const defaultOrgId = '1fa9a565-f3c8-4e11-9b30-120d1052cef0'; - this.logger.log(`Using default organization ID for user registration: ${defaultOrgId}`); - return defaultOrgId; + this.logger.log(`Using default organization ID for user registration: ${DEFAULT_ORG_ID}`); + return DEFAULT_ORG_ID; } } diff --git a/apps/backend/src/infrastructure/persistence/typeorm/migrations/1730000000007-SeedTestUsers.ts b/apps/backend/src/infrastructure/persistence/typeorm/migrations/1730000000007-SeedTestUsers.ts index 8e7ec46..e387fae 100644 --- a/apps/backend/src/infrastructure/persistence/typeorm/migrations/1730000000007-SeedTestUsers.ts +++ b/apps/backend/src/infrastructure/persistence/typeorm/migrations/1730000000007-SeedTestUsers.ts @@ -2,36 +2,26 @@ * Seed Test Users Migration * * Seeds test users for development and testing - * Password for all users: AdminPassword123! - * Hash generated with bcrypt rounds=10 + * Password for all users: Password123! + * Hash generated with Argon2id */ import { MigrationInterface, QueryRunner } from 'typeorm'; -import { v4 as uuidv4 } from 'uuid'; +import { DEFAULT_ORG_ID } from '../seeds/test-organizations.seed'; export class SeedTestUsers1730000000007 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - // Get the first organization ID from the database - const result = await queryRunner.query(` - SELECT id FROM organizations WHERE type = 'FREIGHT_FORWARDER' LIMIT 1 - `); + // Use fixed organization ID from seed + const organizationId = DEFAULT_ORG_ID; - if (result.length === 0) { - throw new Error( - 'No organization found to seed users. Please run organization seed migration first.' - ); - } + // Pre-hashed password: Password123! (Argon2id) + // Generated with: argon2.hash('Password123!', { type: argon2.argon2id, memoryCost: 65536, timeCost: 3, parallelism: 4 }) + const passwordHash = '$argon2id$v=19$m=65536,t=3,p=4$Uj+yeQiaqgBFqyTJ5FX3Cw$wpRCYORyFwjQFSuO3gpmzh10gx9wjYFOCvVZ8TVaP8Q'; - const organizationId = result[0].id; - - // Pre-hashed password: AdminPassword123! (bcrypt rounds=10) - // This hash is deterministic for testing purposes - const passwordHash = '$2b$10$5qK9KqP7YqXZ5Z0kZ0kZ0OqK9KqP7YqXZ5Z0kZ0kZ0OqK9KqP7YqX'; - - // Insert test users + // Fixed UUIDs for test users (matching existing data in database) const users = [ { - id: uuidv4(), + id: 'c59ae389-da30-4533-be0c-fdfe6ac945de', email: 'admin@xpeditis.com', passwordHash, firstName: 'Admin', @@ -39,7 +29,7 @@ export class SeedTestUsers1730000000007 implements MigrationInterface { role: 'ADMIN', }, { - id: uuidv4(), + id: '496ba881-c055-4b78-b0c0-6c048215253b', email: 'manager@xpeditis.com', passwordHash, firstName: 'Manager', @@ -47,7 +37,7 @@ export class SeedTestUsers1730000000007 implements MigrationInterface { role: 'MANAGER', }, { - id: uuidv4(), + id: '361b409d-a32b-4ff9-a61b-e927450c1daf', email: 'user@xpeditis.com', passwordHash, firstName: 'Regular', @@ -66,7 +56,10 @@ export class SeedTestUsers1730000000007 implements MigrationInterface { '${user.firstName}', '${user.lastName}', '${user.role}', '${organizationId}', NULL, true, NOW(), NOW() ) - ON CONFLICT ("email") DO NOTHING; + ON CONFLICT ("email") DO UPDATE SET + "password_hash" = EXCLUDED."password_hash", + "organization_id" = EXCLUDED."organization_id", + "updated_at" = NOW(); `); } @@ -74,7 +67,7 @@ export class SeedTestUsers1730000000007 implements MigrationInterface { console.log(' - admin@xpeditis.com (ADMIN)'); console.log(' - manager@xpeditis.com (MANAGER)'); console.log(' - user@xpeditis.com (USER)'); - console.log(' - Password: AdminPassword123!'); + console.log(' - Password: Password123!'); } public async down(queryRunner: QueryRunner): Promise { diff --git a/apps/backend/src/infrastructure/persistence/typeorm/seeds/test-organizations.seed.ts b/apps/backend/src/infrastructure/persistence/typeorm/seeds/test-organizations.seed.ts index 8085d05..7eded0d 100644 --- a/apps/backend/src/infrastructure/persistence/typeorm/seeds/test-organizations.seed.ts +++ b/apps/backend/src/infrastructure/persistence/typeorm/seeds/test-organizations.seed.ts @@ -19,9 +19,14 @@ export interface OrganizationSeed { isActive: boolean; } +// Fixed UUIDs for consistent seed data across environments +export const DEFAULT_ORG_ID = 'c6042c7b-cffe-4fef-94f6-f27c2d0eb809'; +export const DEMO_CARRIER_ID = '462001d1-6829-4554-a4e1-477667edab6b'; +export const SAMPLE_SHIPPER_ID = '39e49605-5292-4935-9bff-c4abb547d3b9'; + export const organizationSeeds: OrganizationSeed[] = [ { - id: uuidv4(), + id: DEFAULT_ORG_ID, name: 'Test Freight Forwarder Inc.', type: 'FREIGHT_FORWARDER', scac: null, @@ -33,7 +38,7 @@ export const organizationSeeds: OrganizationSeed[] = [ isActive: true, }, { - id: uuidv4(), + id: DEMO_CARRIER_ID, name: 'Demo Shipping Company', type: 'CARRIER', scac: 'DEMO', @@ -45,7 +50,7 @@ export const organizationSeeds: OrganizationSeed[] = [ isActive: true, }, { - id: uuidv4(), + id: SAMPLE_SHIPPER_ID, name: 'Sample Shipper Ltd.', type: 'SHIPPER', scac: null,