@spfn/auth 0.1.0-alpha.0 → 0.1.0-alpha.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +320 -12
  3. package/dist/adapters/nextjs/api.d.ts +446 -0
  4. package/dist/adapters/nextjs/api.js +3279 -0
  5. package/dist/adapters/nextjs/api.js.map +1 -0
  6. package/dist/adapters/nextjs/server.d.ts +246 -0
  7. package/dist/adapters/nextjs/server.js +3645 -0
  8. package/dist/adapters/nextjs/server.js.map +1 -0
  9. package/dist/client.d.ts +2 -0
  10. package/dist/client.js +1 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/index.d.ts +14 -0
  13. package/dist/index.js +9098 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/api/auth-codes-verify.d.ts +37 -0
  16. package/dist/lib/api/auth-codes-verify.js +2949 -0
  17. package/dist/lib/api/auth-codes-verify.js.map +1 -0
  18. package/dist/lib/api/auth-codes.d.ts +37 -0
  19. package/dist/lib/api/auth-codes.js +2949 -0
  20. package/dist/lib/api/auth-codes.js.map +1 -0
  21. package/dist/lib/api/auth-exists.d.ts +38 -0
  22. package/dist/lib/api/auth-exists.js +2949 -0
  23. package/dist/lib/api/auth-exists.js.map +1 -0
  24. package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
  25. package/dist/lib/api/auth-invitations-accept.js +2883 -0
  26. package/dist/lib/api/auth-invitations-accept.js.map +1 -0
  27. package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
  28. package/dist/lib/api/auth-invitations-cancel.js +2883 -0
  29. package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
  30. package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
  31. package/dist/lib/api/auth-invitations-delete.js +2883 -0
  32. package/dist/lib/api/auth-invitations-delete.js.map +1 -0
  33. package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
  34. package/dist/lib/api/auth-invitations-resend.js +2883 -0
  35. package/dist/lib/api/auth-invitations-resend.js.map +1 -0
  36. package/dist/lib/api/auth-invitations.d.ts +109 -0
  37. package/dist/lib/api/auth-invitations.js +2887 -0
  38. package/dist/lib/api/auth-invitations.js.map +1 -0
  39. package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
  40. package/dist/lib/api/auth-keys-rotate.js +2949 -0
  41. package/dist/lib/api/auth-keys-rotate.js.map +1 -0
  42. package/dist/lib/api/auth-login.d.ts +39 -0
  43. package/dist/lib/api/auth-login.js +2949 -0
  44. package/dist/lib/api/auth-login.js.map +1 -0
  45. package/dist/lib/api/auth-logout.d.ts +36 -0
  46. package/dist/lib/api/auth-logout.js +2949 -0
  47. package/dist/lib/api/auth-logout.js.map +1 -0
  48. package/dist/lib/api/auth-me.d.ts +50 -0
  49. package/dist/lib/api/auth-me.js +2949 -0
  50. package/dist/lib/api/auth-me.js.map +1 -0
  51. package/dist/lib/api/auth-password.d.ts +36 -0
  52. package/dist/lib/api/auth-password.js +2949 -0
  53. package/dist/lib/api/auth-password.js.map +1 -0
  54. package/dist/lib/api/auth-register.d.ts +38 -0
  55. package/dist/lib/api/auth-register.js +2949 -0
  56. package/dist/lib/api/auth-register.js.map +1 -0
  57. package/dist/lib/api/index.d.ts +356 -0
  58. package/dist/lib/api/index.js +3261 -0
  59. package/dist/lib/api/index.js.map +1 -0
  60. package/dist/lib/config.d.ts +70 -0
  61. package/dist/lib/config.js +64 -0
  62. package/dist/lib/config.js.map +1 -0
  63. package/dist/lib/contracts/auth.d.ts +302 -0
  64. package/dist/lib/contracts/auth.js +2951 -0
  65. package/dist/lib/contracts/auth.js.map +1 -0
  66. package/dist/lib/contracts/index.d.ts +3 -0
  67. package/dist/lib/contracts/index.js +3190 -0
  68. package/dist/lib/contracts/index.js.map +1 -0
  69. package/dist/lib/contracts/invitation.d.ts +243 -0
  70. package/dist/lib/contracts/invitation.js +2883 -0
  71. package/dist/lib/contracts/invitation.js.map +1 -0
  72. package/dist/lib/crypto.d.ts +76 -0
  73. package/dist/lib/crypto.js +127 -0
  74. package/dist/lib/crypto.js.map +1 -0
  75. package/dist/lib/index.d.ts +4 -0
  76. package/dist/lib/index.js +313 -0
  77. package/dist/lib/index.js.map +1 -0
  78. package/dist/lib/session.d.ts +68 -0
  79. package/dist/lib/session.js +126 -0
  80. package/dist/lib/session.js.map +1 -0
  81. package/dist/lib/types/api.d.ts +45 -0
  82. package/dist/lib/types/api.js +1 -0
  83. package/dist/lib/types/api.js.map +1 -0
  84. package/dist/lib/types/index.d.ts +3 -0
  85. package/dist/lib/types/index.js +2647 -0
  86. package/dist/lib/types/index.js.map +1 -0
  87. package/dist/lib/types/schemas.d.ts +45 -0
  88. package/dist/lib/types/schemas.js +2647 -0
  89. package/dist/lib/types/schemas.js.map +1 -0
  90. package/dist/lib.d.ts +2 -0
  91. package/dist/lib.js +1 -0
  92. package/dist/lib.js.map +1 -0
  93. package/dist/plugin.d.ts +12 -0
  94. package/dist/plugin.js +9081 -0
  95. package/dist/plugin.js.map +1 -0
  96. package/dist/server/entities/index.d.ts +11 -0
  97. package/dist/server/entities/index.js +395 -0
  98. package/dist/server/entities/index.js.map +1 -0
  99. package/dist/server/entities/invitations.d.ts +241 -0
  100. package/dist/server/entities/invitations.js +184 -0
  101. package/dist/server/entities/invitations.js.map +1 -0
  102. package/dist/server/entities/permissions.d.ts +196 -0
  103. package/dist/server/entities/permissions.js +49 -0
  104. package/dist/server/entities/permissions.js.map +1 -0
  105. package/dist/server/entities/role-permissions.d.ts +107 -0
  106. package/dist/server/entities/role-permissions.js +115 -0
  107. package/dist/server/entities/role-permissions.js.map +1 -0
  108. package/dist/server/entities/roles.d.ts +196 -0
  109. package/dist/server/entities/roles.js +50 -0
  110. package/dist/server/entities/roles.js.map +1 -0
  111. package/dist/server/entities/schema.d.ts +14 -0
  112. package/dist/server/entities/schema.js +7 -0
  113. package/dist/server/entities/schema.js.map +1 -0
  114. package/dist/server/entities/user-permissions.d.ts +163 -0
  115. package/dist/server/entities/user-permissions.js +193 -0
  116. package/dist/server/entities/user-permissions.js.map +1 -0
  117. package/dist/server/entities/user-public-keys.d.ts +227 -0
  118. package/dist/server/entities/user-public-keys.js +156 -0
  119. package/dist/server/entities/user-public-keys.js.map +1 -0
  120. package/dist/server/entities/user-social-accounts.d.ts +189 -0
  121. package/dist/server/entities/user-social-accounts.js +149 -0
  122. package/dist/server/entities/user-social-accounts.js.map +1 -0
  123. package/dist/server/entities/users.d.ts +235 -0
  124. package/dist/server/entities/users.js +117 -0
  125. package/dist/server/entities/users.js.map +1 -0
  126. package/dist/server/entities/verification-codes.d.ts +191 -0
  127. package/dist/server/entities/verification-codes.js +49 -0
  128. package/dist/server/entities/verification-codes.js.map +1 -0
  129. package/dist/server/routes/auth/index.d.ts +10 -0
  130. package/dist/server/routes/auth/index.js +4458 -0
  131. package/dist/server/routes/auth/index.js.map +1 -0
  132. package/dist/server/routes/index.d.ts +6 -0
  133. package/dist/server/routes/index.js +6582 -0
  134. package/dist/server/routes/index.js.map +1 -0
  135. package/dist/server/routes/invitations/index.d.ts +10 -0
  136. package/dist/server/routes/invitations/index.js +4395 -0
  137. package/dist/server/routes/invitations/index.js.map +1 -0
  138. package/dist/server.d.ts +1272 -0
  139. package/dist/server.js +2274 -0
  140. package/dist/server.js.map +1 -0
  141. package/migrations/0000_complex_swordsman.sql +167 -0
  142. package/migrations/meta/0000_snapshot.json +1397 -0
  143. package/migrations/meta/_journal.json +13 -0
  144. package/package.json +59 -24
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 INFLIKE Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -203,6 +203,256 @@ app.bind(myProtectedRoute, [authenticate], async (c) => {
203
203
 
204
204
  ---
205
205
 
206
+ ## Next.js Integration
207
+
208
+ The `@spfn/auth/nextjs` adapter provides seamless authentication integration for Next.js applications with automatic JWT injection and session management.
209
+
210
+ ### Features
211
+
212
+ - **Automatic JWT Generation** - Generates JWT from HttpOnly cookie sessions
213
+ - **Server-Side Interceptor** - Auto-inject JWT in server components and API routes
214
+ - **Client-Side Proxy** - Auto-inject JWT for browser requests via `/api/actions`
215
+ - **High-Level Auth API** - Simple wrappers with automatic key generation
216
+ - **Session Helpers** - Server-side session management utilities
217
+
218
+ ### Installation
219
+
220
+ ```typescript
221
+ import { authApi } from '@spfn/auth/nextjs';
222
+ ```
223
+
224
+ ### 1. High-Level Auth API
225
+
226
+ The `authApi` object provides simplified authentication functions with automatic key generation and session management:
227
+
228
+ ```typescript
229
+ import { authApi } from '@spfn/auth/nextjs';
230
+
231
+ // ✅ Register (automatic key generation + session)
232
+ const result = await authApi.register({
233
+ email: 'user@example.com',
234
+ password: 'SecurePass123!',
235
+ verificationToken: '...' // from verification code
236
+ });
237
+ // → Automatically generates keypair, stores in session cookie
238
+
239
+ // ✅ Login (automatic key generation + rotation)
240
+ const result = await authApi.login({
241
+ email: 'user@example.com',
242
+ password: 'SecurePass123!'
243
+ });
244
+ // → Automatically generates new keypair, rotates old key
245
+
246
+ // ✅ Logout (revokes current key)
247
+ await authApi.logout();
248
+
249
+ // ✅ Rotate Key (before 90-day expiry)
250
+ await authApi.rotateKey();
251
+ ```
252
+
253
+ **No manual key generation needed!** The `authApi` handles:
254
+ - ES256 keypair generation
255
+ - Public key registration with server
256
+ - Private key storage in encrypted HttpOnly cookies
257
+ - Automatic key rotation on login
258
+
259
+ ### 2. Server-Side JWT Injection
260
+
261
+ For server components and API routes, use the `createAuthInterceptor`:
262
+
263
+ ```typescript
264
+ // app/api/protected/route.ts
265
+ import { UniversalClient } from '@spfn/core/client';
266
+ import { createAuthInterceptor } from '@spfn/auth/nextjs';
267
+
268
+ // Create client with auth interceptor
269
+ const client = new UniversalClient({
270
+ baseURL: process.env.SPFN_API_URL!,
271
+ requestInterceptor: createAuthInterceptor()
272
+ });
273
+
274
+ export async function GET() {
275
+ // JWT is automatically injected from session cookie
276
+ const data = await client.call(someContract);
277
+ return Response.json(data);
278
+ }
279
+ ```
280
+
281
+ **How it works:**
282
+ 1. Reads `session` HttpOnly cookie
283
+ 2. Unseals session to get `privateKey`, `keyId`, `userId`
284
+ 3. Generates JWT signed with `privateKey`
285
+ 4. Adds `Authorization: Bearer <jwt>` header automatically
286
+
287
+ ### 3. Client-Side Proxy Setup
288
+
289
+ For browser requests, set up the Next.js API Route proxy:
290
+
291
+ ```typescript
292
+ // app/api/actions/[...path]/route.ts
293
+ export {
294
+ GET,
295
+ POST,
296
+ PUT,
297
+ DELETE,
298
+ PATCH
299
+ } from '@spfn/auth/nextjs/proxy';
300
+ ```
301
+
302
+ Then use `UniversalClient` from browser:
303
+
304
+ ```typescript
305
+ 'use client';
306
+ import { UniversalClient } from '@spfn/core/client';
307
+
308
+ const client = new UniversalClient({
309
+ baseURL: '/api/actions' // Proxy endpoint
310
+ });
311
+
312
+ // Browser → /api/actions/user/profile → SPFN API (with JWT injected)
313
+ const user = await client.call(getUserContract);
314
+ ```
315
+
316
+ **How it works:**
317
+ 1. Browser makes request to `/api/actions/*`
318
+ 2. Proxy reads `session` cookie (server-side only)
319
+ 3. Generates JWT from session
320
+ 4. Forwards request to SPFN API with `Authorization` header
321
+ 5. Returns response to browser
322
+
323
+ ### 4. Session Helpers
324
+
325
+ Direct session management utilities:
326
+
327
+ ```typescript
328
+ import {
329
+ saveSession,
330
+ getSession,
331
+ clearSession
332
+ } from '@spfn/auth/nextjs';
333
+
334
+ // Save session data (encrypted HttpOnly cookie)
335
+ await saveSession({
336
+ userId: '123',
337
+ privateKey: '...',
338
+ keyId: 'uuid',
339
+ algorithm: 'ES256'
340
+ }, 60 * 60 * 24 * 7); // 7 days
341
+
342
+ // Get current session
343
+ const session = await getSession();
344
+ console.log(session?.userId);
345
+
346
+ // Clear session
347
+ await clearSession();
348
+ ```
349
+
350
+ ### 5. JWT Helper (Manual Usage)
351
+
352
+ Generate JWT from session manually if needed:
353
+
354
+ ```typescript
355
+ import { generateJWTFromSession } from '@spfn/auth/nextjs';
356
+
357
+ const jwt = await generateJWTFromSession();
358
+ // → Returns signed JWT or null if no session
359
+ ```
360
+
361
+ ### Updated Middleware (No X-Key-Id Required)
362
+
363
+ The authenticate middleware now extracts `keyId` from the JWT payload, so you **no longer need** to send the `X-Key-Id` header:
364
+
365
+ ```typescript
366
+ // ❌ Old way (deprecated)
367
+ fetch('/api/protected', {
368
+ headers: {
369
+ 'Authorization': `Bearer ${jwt}`,
370
+ 'X-Key-Id': keyId // ← No longer needed!
371
+ }
372
+ });
373
+
374
+ // ✅ New way
375
+ fetch('/api/protected', {
376
+ headers: {
377
+ 'Authorization': `Bearer ${jwt}` // keyId extracted from JWT
378
+ }
379
+ });
380
+ ```
381
+
382
+ The middleware flow:
383
+ 1. Decode JWT to extract `keyId` (without verification)
384
+ 2. Fetch public key from database using `keyId`
385
+ 3. Verify JWT signature with public key
386
+ 4. Validate user and attach to context
387
+
388
+ ### Complete Next.js Example
389
+
390
+ ```typescript
391
+ // app/auth/login/route.ts
392
+ import { authApi } from '@spfn/auth/nextjs';
393
+
394
+ export async function POST(request: Request) {
395
+ const { email, password } = await request.json();
396
+
397
+ try {
398
+ const result = await authApi.login({ email, password });
399
+ return Response.json({ success: true, userId: result.userId });
400
+ } catch (error) {
401
+ return Response.json({ success: false, error: error.message }, { status: 401 });
402
+ }
403
+ }
404
+
405
+ // app/dashboard/page.tsx (Server Component)
406
+ import { UniversalClient } from '@spfn/core/client';
407
+ import { createAuthInterceptor } from '@spfn/auth/nextjs';
408
+
409
+ const client = new UniversalClient({
410
+ baseURL: process.env.SPFN_API_URL!,
411
+ requestInterceptor: createAuthInterceptor()
412
+ });
413
+
414
+ export default async function Dashboard() {
415
+ // JWT automatically injected
416
+ const user = await client.call(getUserContract);
417
+
418
+ return <div>Welcome {user.email}</div>;
419
+ }
420
+
421
+ // app/profile/page.tsx (Client Component)
422
+ 'use client';
423
+ import { UniversalClient } from '@spfn/core/client';
424
+
425
+ const client = new UniversalClient({
426
+ baseURL: '/api/actions'
427
+ });
428
+
429
+ export default function Profile() {
430
+ const [user, setUser] = useState(null);
431
+
432
+ useEffect(() => {
433
+ // Browser → Proxy → SPFN API (JWT auto-injected)
434
+ client.call(getUserContract).then(setUser);
435
+ }, []);
436
+
437
+ return <div>{user?.email}</div>;
438
+ }
439
+ ```
440
+
441
+ ### Environment Variables
442
+
443
+ ```bash
444
+ # Required for session encryption
445
+ SPFN_AUTH_SESSION_SECRET=your-32-char-secret-key
446
+
447
+ # SPFN API URL (server-side)
448
+ SPFN_API_URL=http://localhost:8790
449
+
450
+ # Public API URL (optional, for client-side)
451
+ NEXT_PUBLIC_API_URL=http://localhost:8790
452
+ ```
453
+
454
+ ---
455
+
206
456
  ## Service Layer (Reusable Business Logic)
207
457
 
208
458
  The `@spfn/auth` package provides **service functions** that encapsulate all business logic, making it easy to create custom authentication flows while reusing the same secure logic.
@@ -1166,8 +1416,8 @@ if (shouldRotate) {
1166
1416
 
1167
1417
  ```bash
1168
1418
  # .env
1169
- JWT_SECRET=your-secret-key-change-in-production # For legacy tokens
1170
- JWT_EXPIRES_IN=7d # Token expiry
1419
+ SPFN_AUTH_JWT_SECRET=your-secret-key-change-in-production # For legacy tokens
1420
+ SPFN_AUTH_JWT_EXPIRES_IN=7d # Token expiry
1171
1421
  ```
1172
1422
 
1173
1423
  ---
@@ -1196,12 +1446,70 @@ This creates the auth schema with 8 tables:
1196
1446
 
1197
1447
  ### 2. Configure Environment Variables
1198
1448
 
1449
+ #### Core Settings (Required)
1450
+
1199
1451
  ```bash
1200
1452
  # .env
1201
- JWT_SECRET=your-secret-key-change-in-production
1202
- JWT_EXPIRES_IN=7d
1453
+
1454
+ # ========================================
1455
+ # Core Authentication Settings (Required)
1456
+ # ========================================
1457
+
1458
+ # JWT Token Settings
1459
+ SPFN_AUTH_JWT_SECRET=your-secret-key-change-in-production # JWT signing secret (REQUIRED)
1460
+ SPFN_AUTH_JWT_EXPIRES_IN=7d # JWT token expiry (default: 7d)
1461
+
1462
+ # Verification Token Settings
1463
+ SPFN_AUTH_VERIFICATION_TOKEN_SECRET=separate-secret-key # Optional: separate secret for verification tokens
1464
+ # If not set, uses SPFN_AUTH_JWT_SECRET
1465
+
1466
+ # Password Hashing
1467
+ SPFN_AUTH_BCRYPT_SALT_ROUNDS=10 # bcrypt salt rounds (default: 10)
1468
+ # Higher = more secure but slower (10-12 recommended)
1469
+
1470
+ # ========================================
1471
+ # Client-Side Settings (Optional)
1472
+ # ========================================
1473
+
1474
+ # Session Management (for client-side session encryption)
1475
+ SPFN_AUTH_SESSION_SECRET=session-encryption-key # Required if using client-side session features
1476
+
1477
+ # API URL Configuration (for client-side API calls)
1478
+ SPFN_API_URL=http://localhost:8790 # SPFN API server URL
1479
+ NEXT_PUBLIC_API_URL=http://localhost:8790 # Next.js public API URL (takes precedence)
1480
+
1481
+ # Environment
1482
+ NODE_ENV=production # production | development
1203
1483
  ```
1204
1484
 
1485
+ #### Admin Account Creation (Optional)
1486
+
1487
+ See [Section 3: Create Initial Admin Accounts](#3-create-initial-admin-accounts-optional) below for details.
1488
+
1489
+ d---
1490
+
1491
+ ### Legacy Environment Variables (Backward Compatibility)
1492
+
1493
+ For backward compatibility, the package also supports legacy environment variable names without the `SPFN_AUTH_` prefix. The new prefixed versions take precedence:
1494
+
1495
+ ```bash
1496
+ # Legacy (still supported, but deprecated)
1497
+ JWT_SECRET=...
1498
+ JWT_EXPIRES_IN=...
1499
+ VERIFICATION_TOKEN_SECRET=...
1500
+ BCRYPT_SALT_ROUNDS=...
1501
+ SESSION_SECRET=...
1502
+
1503
+ ADMIN_ACCOUNTS=...
1504
+ ADMIN_EMAILS=...
1505
+ ADMIN_PASSWORDS=...
1506
+ ADMIN_ROLES=...
1507
+ ADMIN_EMAIL=...
1508
+ ADMIN_PASSWORD=...
1509
+ ```
1510
+
1511
+ **Recommendation:** Use the new `SPFN_AUTH_*` prefixed variables to avoid conflicts with other packages.
1512
+
1205
1513
  ### 3. Create Initial Admin Accounts (Optional)
1206
1514
 
1207
1515
  You can automatically create admin accounts on server startup using environment variables. Three formats are supported:
@@ -1212,7 +1520,7 @@ Allows full control over each account's configuration.
1212
1520
 
1213
1521
  ```bash
1214
1522
  # .env
1215
- ADMIN_ACCOUNTS='[
1523
+ SPFN_AUTH_ADMIN_ACCOUNTS='[
1216
1524
  {
1217
1525
  "email": "super@example.com",
1218
1526
  "password": "super-password",
@@ -1249,14 +1557,14 @@ Quick setup for multiple accounts with basic configuration.
1249
1557
 
1250
1558
  ```bash
1251
1559
  # .env
1252
- ADMIN_EMAILS=super@example.com,admin@example.com,user@example.com
1253
- ADMIN_PASSWORDS=super-pass,admin-pass,user-pass
1254
- ADMIN_ROLES=superadmin,admin,user # Optional, defaults to 'user'
1560
+ SPFN_AUTH_ADMIN_EMAILS=super@example.com,admin@example.com,user@example.com
1561
+ SPFN_AUTH_ADMIN_PASSWORDS=super-pass,admin-pass,user-pass
1562
+ SPFN_AUTH_ADMIN_ROLES=superadmin,admin,user # Optional, defaults to 'user'
1255
1563
  ```
1256
1564
 
1257
1565
  **Requirements:**
1258
- - `ADMIN_EMAILS` and `ADMIN_PASSWORDS` must have the same number of items
1259
- - `ADMIN_ROLES` is optional (defaults to `user` for each account)
1566
+ - `SPFN_AUTH_ADMIN_EMAILS` and `SPFN_AUTH_ADMIN_PASSWORDS` must have the same number of items
1567
+ - `SPFN_AUTH_ADMIN_ROLES` is optional (defaults to `user` for each account)
1260
1568
  - All accounts will have `passwordChangeRequired: true`
1261
1569
 
1262
1570
  ---
@@ -1267,8 +1575,8 @@ For backward compatibility, you can create a single superadmin account.
1267
1575
 
1268
1576
  ```bash
1269
1577
  # .env
1270
- ADMIN_EMAIL=admin@example.com
1271
- ADMIN_PASSWORD=secure-password
1578
+ SPFN_AUTH_ADMIN_EMAIL=admin@example.com
1579
+ SPFN_AUTH_ADMIN_PASSWORD=secure-password
1272
1580
  ```
1273
1581
 
1274
1582
  This creates a single account with: