@@ -144,63 +144,24 @@ export async function runSeed(): Promise<void> {
144144
145145 console . log ( `[Seed] Will seed: ${ tablesToSeedNames . join ( ', ' ) } ` ) ;
146146
147- // Resolve admin credentials with environment-sensitive defaults
148- const isProd = process . env . NODE_ENV === 'production' ;
149-
147+ // Resolve admin credentials - always use predefined defaults unless explicitly configured
150148 const envAdminEmail = process . env . SEED_ADMIN_EMAIL ;
151149 const envAdminPassword = process . env . SEED_ADMIN_PASSWORD ;
152150
153- let adminEmail : string ;
154- let adminPassword : string ;
155- let credentialsAutoGenerated = false ;
156-
157- if ( isProd ) {
158- if ( ! envAdminEmail || ! envAdminPassword ) {
159- // Auto-generate secure credentials in production if not provided
160- // Generate a secure random password (32 chars with mixed case, numbers, symbols)
161- const generateSecurePassword = ( ) => {
162- const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*' ;
163- const randomValues = new Uint8Array ( 32 ) ;
164- crypto . getRandomValues ( randomValues ) ;
165- return Array . from ( randomValues , ( v ) => chars [ v % chars . length ] ) . join ( '' ) ;
166- } ;
167-
168- adminEmail = envAdminEmail || `admin-${ crypto . randomUUID ( ) . slice ( 0 , 8 ) } @auto.generated` ;
169- adminPassword = envAdminPassword || generateSecurePassword ( ) ;
170- credentialsAutoGenerated = true ;
171-
172- // Log the auto-generated credentials prominently
173- console . log ( '' ) ;
174- console . log ( '╔══════════════════════════════════════════════════════════════════════════════╗' ) ;
175- console . log ( '║ ⚠️ AUTO-GENERATED ADMIN CREDENTIALS (SAVE THESE NOW!) ║' ) ;
176- console . log ( '╠══════════════════════════════════════════════════════════════════════════════╣' ) ;
177- console . log ( '║ ║' ) ;
178- console . log ( `║ Email: ${ adminEmail . padEnd ( 64 ) } ║` ) ;
179- console . log ( `║ Password: ${ adminPassword . padEnd ( 64 ) } ║` ) ;
180- console . log ( '║ ║' ) ;
181- console . log ( '║ These credentials will only be shown ONCE. ║' ) ;
182- console . log ( '║ To set custom credentials, configure these environment variables: ║' ) ;
183- console . log ( '║ - SEED_ADMIN_EMAIL ║' ) ;
184- console . log ( '║ - SEED_ADMIN_PASSWORD ║' ) ;
185- console . log ( '║ ║' ) ;
186- console . log ( '╚══════════════════════════════════════════════════════════════════════════════╝' ) ;
187- console . log ( '' ) ;
188- } else {
189- adminEmail = envAdminEmail ;
190- adminPassword = envAdminPassword ;
191-
192- // Warn if using the insecure default password in production
193- if ( envAdminPassword === 'Passw0rd123!' ) {
194- console . warn ( '' ) ;
195- console . warn ( '⚠️ WARNING: Using insecure default password in production!' ) ;
196- console . warn ( ' Please set SEED_ADMIN_PASSWORD to a strong, unique password.' ) ;
197- console . warn ( '' ) ;
198- }
199- }
200- } else {
201- // In non-production, allow safe defaults for developer convenience
202- adminEmail = envAdminEmail || '[email protected] ' ; 203- adminPassword = envAdminPassword || 'Passw0rd123!' ;
151+ // Always use predefined defaults unless explicitly configured
152+ // This ensures consistent admin credentials across all environments (dev, build, production)
153+ const adminEmail = envAdminEmail || '[email protected] ' ; 154+ const adminPassword = envAdminPassword || 'Passw0rd123!' ;
155+
156+ // Warn if using defaults in production
157+ if ( process . env . NODE_ENV === 'production' && ( ! envAdminEmail || ! envAdminPassword ) ) {
158+ console . warn ( '' ) ;
159+ console . warn ( '⚠️ WARNING: Using default admin credentials in production!' ) ;
160+ console . warn ( ' Email: [email protected] ' ) ; 161+ console . warn ( ' Password: Passw0rd123!' ) ;
162+ console . warn ( '' ) ;
163+ console . warn ( ' Set SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD for secure credentials.' ) ;
164+ console . warn ( '' ) ;
204165 }
205166
206167 const hashedPassword = await bcrypt . hash ( adminPassword , 10 ) ;
@@ -431,6 +392,46 @@ export async function runSeed(): Promise<void> {
431392 }
432393 }
433394
395+ // ============================================
396+ // MIGRATION: Fix auto-generated admin emails
397+ // One-time migration for existing deployments that have admin-*@auto .generated
398+ // ============================================
399+ const existingDemoAdmin = await db . select ( ) . from ( users ) . where ( eq ( users . email , '[email protected] ' ) ) . limit ( 1 ) ; 400+
401+ if ( existingDemoAdmin . length === 0 ) {
402+ // No demo admin exists - check for auto-generated admin to migrate
403+ const autoGeneratedAdmin = await db
404+ . select ( )
405+ . from ( users )
406+ . where ( sql `email LIKE 'admin-%@auto.generated'` )
407+ . limit ( 1 ) ;
408+
409+ if ( autoGeneratedAdmin . length > 0 ) {
410+ console . log ( '[Seed] 🔄 Found auto-generated admin account, migrating to predefined credentials...' ) ;
411+
412+ // Update the user's email and password
413+ await db
414+ . update ( users )
415+ . set ( {
416+ 417+ passwordHash : hashedPassword
418+ } )
419+ . where ( eq ( users . id , autoGeneratedAdmin [ 0 ] . id ) ) ;
420+
421+ // Update the associated account
422+ await db
423+ . update ( accounts )
424+ . set ( {
425+ 426+ providerAccountId :
'[email protected] ' , 427+ passwordHash : hashedPassword
428+ } )
429+ . where ( eq ( accounts . userId , autoGeneratedAdmin [ 0 ] . id ) ) ;
430+
431+ console . log ( '[Seed] ✓ Migrated auto-generated admin to [email protected] with default password' ) ; 432+ }
433+ }
434+
434435 // ============================================
435436 // DEMO MODE: Seed additional tables
436437 // ============================================
0 commit comments