@ofeklabs/horizon-auth 0.4.1 โ†’ 1.0.0

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 (55) hide show
  1. package/README.md +175 -565
  2. package/dist/account/account.module.js +0 -2
  3. package/dist/account/account.module.js.map +1 -1
  4. package/dist/account/account.service.d.ts +2 -2
  5. package/dist/account/account.service.js +2 -2
  6. package/dist/account/account.service.js.map +1 -1
  7. package/dist/auth/auth.module.js +2 -0
  8. package/dist/auth/auth.module.js.map +1 -1
  9. package/dist/auth/auth.service.d.ts +2 -2
  10. package/dist/auth/auth.service.js +2 -2
  11. package/dist/auth/auth.service.js.map +1 -1
  12. package/dist/devices/device.module.js +1 -2
  13. package/dist/devices/device.module.js.map +1 -1
  14. package/dist/devices/device.service.d.ts +2 -2
  15. package/dist/devices/device.service.js +2 -2
  16. package/dist/devices/device.service.js.map +1 -1
  17. package/dist/index.d.ts +0 -1
  18. package/dist/index.js +0 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/lib/horizon-auth.module.d.ts +1 -1
  21. package/dist/lib/horizon-auth.module.js +7 -14
  22. package/dist/lib/horizon-auth.module.js.map +1 -1
  23. package/dist/push-tokens/push-token.module.js +1 -2
  24. package/dist/push-tokens/push-token.module.js.map +1 -1
  25. package/dist/push-tokens/push-token.service.d.ts +2 -2
  26. package/dist/push-tokens/push-token.service.js +2 -2
  27. package/dist/push-tokens/push-token.service.js.map +1 -1
  28. package/dist/social-auth/social-auth.module.js +1 -2
  29. package/dist/social-auth/social-auth.module.js.map +1 -1
  30. package/dist/social-auth/social-auth.service.d.ts +3 -3
  31. package/dist/social-auth/social-auth.service.js +2 -2
  32. package/dist/social-auth/social-auth.service.js.map +1 -1
  33. package/dist/tsconfig.build.tsbuildinfo +1 -1
  34. package/dist/two-factor/two-factor.module.js +0 -2
  35. package/dist/two-factor/two-factor.module.js.map +1 -1
  36. package/dist/two-factor/two-factor.service.d.ts +2 -2
  37. package/dist/two-factor/two-factor.service.js +2 -2
  38. package/dist/two-factor/two-factor.service.js.map +1 -1
  39. package/dist/users/users.module.js +0 -2
  40. package/dist/users/users.module.js.map +1 -1
  41. package/dist/users/users.service.d.ts +2 -2
  42. package/dist/users/users.service.js +2 -2
  43. package/dist/users/users.service.js.map +1 -1
  44. package/package.json +3 -6
  45. package/dist/lib/horizon-auth-env.config.d.ts +0 -3
  46. package/dist/lib/horizon-auth-env.config.js +0 -178
  47. package/dist/lib/horizon-auth-env.config.js.map +0 -1
  48. package/dist/prisma/prisma.module.d.ts +0 -4
  49. package/dist/prisma/prisma.module.js +0 -33
  50. package/dist/prisma/prisma.module.js.map +0 -1
  51. package/dist/prisma/prisma.service.d.ts +0 -8
  52. package/dist/prisma/prisma.service.js +0 -42
  53. package/dist/prisma/prisma.service.js.map +0 -1
  54. package/prisma/migrations/20260218105110_add_enhanced_auth_features/migration.sql +0 -192
  55. package/prisma/migrations/migration_lock.toml +0 -3
package/README.md CHANGED
@@ -1,17 +1,10 @@
1
1
  # @ofeklabs/horizon-auth
2
2
 
3
- Production-ready NestJS authentication module with 2026 security standards. One package, two modes: embedded auth or SSO - configured entirely through ENV variables.
3
+ Production-ready NestJS authentication module with 2026 security standards. Deploy once, use everywhere.
4
4
 
5
- ## ๐ŸŽฏ Use Cases
5
+ ## Use Cases
6
6
 
7
- ### 1. Embedded Auth
8
- Each application has its own isolated authentication. Perfect for standalone apps.
9
-
10
- ```
11
- myapp.com (App + Auth)
12
- ```
13
-
14
- ### 2. Portfolio SSO (Recommended)
7
+ ### 1. Portfolio SSO (Recommended)
15
8
  Deploy one auth service, use it across all your projects. Users sign in once and access everything.
16
9
 
17
10
  ```
@@ -22,7 +15,8 @@ auth.yourdomain.com (Auth Service)
22
15
  โ””โ”€โ”€ project3.yourdomain.com
23
16
  ```
24
17
 
25
- **Same package, different ENV variables!** No code changes needed.
18
+ ### 2. Embedded Auth
19
+ Each application has its own isolated authentication.
26
20
 
27
21
  ## Features
28
22
 
@@ -35,128 +29,99 @@ auth.yourdomain.com (Auth Service)
35
29
  - ๐ŸŽฏ **Type-Safe**: Full TypeScript support
36
30
  - ๐Ÿ“ฆ **Zero Config**: Sensible defaults, fully customizable
37
31
 
38
- ### ๐Ÿ†• Enterprise Features (v0.3.0)
32
+ ## Quick Start
39
33
 
40
- - ๐Ÿ”’ **Two-Factor Authentication**: TOTP-based 2FA with QR codes and backup codes
41
- - ๐Ÿ“ฑ **Device Management**: Track, list, and revoke user devices
42
- - ๐Ÿ”” **Push Notifications**: Register and manage push tokens (FCM/APNS)
43
- - ๐Ÿ‘ค **Account Management**: Deactivate, reactivate, and delete accounts
44
- - ๐ŸŒ **Social Login**: Google and Facebook OAuth integration
34
+ ### Portfolio SSO Setup (Recommended)
45
35
 
46
- ## ๐Ÿš€ Quick Start
36
+ Deploy one auth service, use it across all your projects.
47
37
 
48
- ### Installation
38
+ #### 1. Deploy Auth Service (One Time)
49
39
 
50
40
  ```bash
51
- npm install @ofeklabs/horizon-auth @prisma/client ioredis passport passport-jwt
52
- npm install -D prisma
41
+ # Clone and deploy packages/horizon-auth to auth.yourdomain.com
42
+ npm install
43
+ npm run build
44
+ npm run start:prod
53
45
  ```
54
46
 
55
- ### Generate RSA Keys
56
-
57
- ```bash
58
- openssl genrsa -out private.pem 2048
59
- openssl rsa -in private.pem -pubout -out public.pem
47
+ **Environment Variables**:
48
+ ```env
49
+ DATABASE_URL=postgresql://...
50
+ REDIS_HOST=your-redis-host
51
+ JWT_PRIVATE_KEY=<your-private-key>
52
+ JWT_PUBLIC_KEY=<your-public-key>
53
+ COOKIE_DOMAIN=.yourdomain.com
54
+ NODE_ENV=production
60
55
  ```
61
56
 
62
- ---
63
-
64
- ## Configuration Options
65
-
66
- ### Option 1: Environment Variables Only (Recommended โญ)
67
-
68
- **Zero code configuration** - just set ENV variables and you're done!
57
+ #### 2. Use in Your Projects
69
58
 
70
- #### Embedded Mode (Standalone App)
59
+ For each project:
71
60
 
72
- ```env
73
- # .env
74
- AUTH_MODE=full
75
- DATABASE_URL=postgresql://user:password@localhost:5432/myapp
76
- REDIS_HOST=localhost
77
- REDIS_PORT=6379
78
- JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
79
- JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
80
-
81
- # Optional: Enable features
82
- ENABLE_2FA=true
83
- ENABLE_DEVICE_MGMT=true
84
- ENABLE_PUSH=true
85
- ENABLE_ACCOUNT_MGMT=true
86
- APP_NAME=MyApp
61
+ ```bash
62
+ npm install @ofeklabs/horizon-auth
87
63
  ```
88
64
 
89
65
  ```typescript
90
66
  // app.module.ts
91
- import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
92
-
93
- @Module({
94
- imports: [
95
- HorizonAuthModule.forRoot(), // ๐Ÿ‘ˆ No config needed! Uses ENV variables
96
- ],
67
+ HorizonAuthModule.forRoot({
68
+ ssoMode: true,
69
+ authServiceUrl: process.env.AUTH_SERVICE_URL,
70
+ jwt: {
71
+ publicKey: process.env.JWT_PUBLIC_KEY,
72
+ },
73
+ cookie: {
74
+ domain: process.env.COOKIE_DOMAIN,
75
+ secure: process.env.NODE_ENV === 'production',
76
+ },
97
77
  })
98
- export class AppModule {}
99
78
  ```
100
79
 
101
- #### SSO Mode (Multiple Projects, One Auth)
102
-
103
- **Auth Service (auth.yourdomain.com):**
104
80
  ```env
105
- AUTH_MODE=full
106
- DATABASE_URL=postgresql://user:password@host:5432/auth_db
107
- REDIS_HOST=redis.yourdomain.com
108
- JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
109
- JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
110
- COOKIE_DOMAIN=.yourdomain.com
111
- NODE_ENV=production
112
- ENABLE_2FA=true
113
- ENABLE_DEVICE_MGMT=true
114
- APP_NAME=YourCompany
115
- ```
116
-
117
- **Your Projects (project1.yourdomain.com, project2.yourdomain.com):**
118
- ```env
119
- AUTH_MODE=sso
81
+ # .env
120
82
  AUTH_SERVICE_URL=https://auth.yourdomain.com
121
- JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
83
+ JWT_PUBLIC_KEY=<paste-public-key>
122
84
  COOKIE_DOMAIN=.yourdomain.com
123
- NODE_ENV=production
124
85
  ```
125
86
 
126
- ```typescript
127
- // app.module.ts (same for all projects)
128
- import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
87
+ Deploy to:
88
+ - project1.yourdomain.com
89
+ - project2.yourdomain.com
90
+ - project3.yourdomain.com
129
91
 
130
- @Module({
131
- imports: [
132
- HorizonAuthModule.forRoot(), // ๐Ÿ‘ˆ Automatically uses SSO mode from ENV
133
- ],
134
- })
135
- export class AppModule {}
136
- ```
92
+ Users sign in once, access all projects.
137
93
 
138
- **That's it!** Deploy your auth service once, then use the same package in all your projects with different ENV variables. No code changes needed!
94
+ ---
139
95
 
140
- **๐Ÿ“š See [ENV-CONFIGURATION.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/ENV-CONFIGURATION.md) for complete ENV reference.**
96
+ ### Embedded Auth Setup (Alternative)
141
97
 
142
- **๐Ÿ“– See [DEPLOYMENT-EXAMPLES.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/DEPLOYMENT-EXAMPLES.md) for real-world deployment scenarios.**
98
+ Each application has its own authentication.
143
99
 
144
- ---
100
+ ### 1. Install
145
101
 
146
- ### Option 2: Code Configuration (Advanced)
102
+ ```bash
103
+ npm install @ofeklabs/horizon-auth @prisma/client ioredis passport passport-jwt
104
+ npm install -D prisma
105
+ ```
147
106
 
148
- If you prefer code-based configuration or need dynamic config:
107
+ ### 2. Generate RSA Keys
149
108
 
150
- ### Option 2: Code Configuration (Advanced)
109
+ ```bash
110
+ # Generate private key
111
+ openssl genrsa -out private.pem 2048
151
112
 
152
- If you prefer code-based configuration or need dynamic config:
113
+ # Generate public key
114
+ openssl rsa -in private.pem -pubout -out public.pem
115
+ ```
153
116
 
154
- #### Embedded Mode
117
+ ### 3. Configure Module
155
118
 
156
119
  ```typescript
157
120
  // app.module.ts
158
121
  import { Module } from '@nestjs/common';
159
122
  import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
123
+ import { readFileSync } from 'fs';
124
+ import { join } from 'path';
160
125
 
161
126
  @Module({
162
127
  imports: [
@@ -167,19 +132,12 @@ import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
167
132
  redis: {
168
133
  host: process.env.REDIS_HOST || 'localhost',
169
134
  port: parseInt(process.env.REDIS_PORT) || 6379,
135
+ password: process.env.REDIS_PASSWORD,
170
136
  },
171
137
  jwt: {
172
- privateKey: process.env.JWT_PRIVATE_KEY,
173
- publicKey: process.env.JWT_PUBLIC_KEY,
174
- },
175
- features: {
176
- twoFactor: {
177
- enabled: true,
178
- issuer: 'YourApp',
179
- },
180
- deviceManagement: {
181
- enabled: true,
182
- },
138
+ // For production: use environment variables
139
+ privateKey: process.env.JWT_PRIVATE_KEY || readFileSync(join(__dirname, '../certs/private.pem'), 'utf8'),
140
+ publicKey: process.env.JWT_PUBLIC_KEY || readFileSync(join(__dirname, '../certs/public.pem'), 'utf8'),
183
141
  },
184
142
  }),
185
143
  ],
@@ -187,48 +145,17 @@ import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
187
145
  export class AppModule {}
188
146
  ```
189
147
 
190
- #### SSO Mode
191
-
192
- ```typescript
193
- // app.module.ts
194
- import { HorizonAuthModule } from '@ofeklabs/horizon-auth';
195
-
196
- @Module({
197
- imports: [
198
- HorizonAuthModule.forRoot({
199
- ssoMode: true,
200
- authServiceUrl: process.env.AUTH_SERVICE_URL,
201
- jwt: {
202
- publicKey: process.env.JWT_PUBLIC_KEY,
203
- },
204
- cookie: {
205
- domain: process.env.COOKIE_DOMAIN,
206
- secure: process.env.NODE_ENV === 'production',
207
- },
208
- }),
209
- ],
210
- })
211
- export class AppModule {}
212
- ```
213
-
214
- **Note:** ENV variables are still loaded automatically. Code config overrides ENV values.
215
-
216
- ---
217
-
218
- ## ๐Ÿ—„๏ธ Database Setup
148
+ ### 4. Set Up Database
219
149
 
220
150
  ```bash
221
- # Start PostgreSQL and Redis (using Docker)
222
- docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:15
223
- docker run -d -p 6379:6379 redis:7-alpine
151
+ # Start PostgreSQL and Redis
152
+ docker-compose up -d
224
153
 
225
154
  # Run Prisma migrations
226
155
  npx prisma migrate dev
227
156
  ```
228
157
 
229
- ---
230
-
231
- ## ๐ŸŽจ Use in Your Application
158
+ ### 5. Use in Controllers
232
159
 
233
160
  ```typescript
234
161
  import { Controller, Get, Post, Body, UseGuards } from '@nestjs/common';
@@ -237,6 +164,8 @@ import {
237
164
  CurrentUser,
238
165
  JwtAuthGuard,
239
166
  Roles,
167
+ LoginDto,
168
+ RegisterDto,
240
169
  } from '@ofeklabs/horizon-auth';
241
170
 
242
171
  @Controller()
@@ -265,193 +194,69 @@ export class AppController {
265
194
  }
266
195
  ```
267
196
 
268
- ---
269
-
270
- ## ๐Ÿ“ก API Endpoints
197
+ ## API Endpoints
271
198
 
272
199
  The package automatically provides these endpoints:
273
200
 
274
- ### Core Authentication
201
+ ### Authentication
275
202
 
276
203
  - `POST /auth/register` - Register new user
277
204
  - `POST /auth/login` - Login with email/password
278
205
  - `POST /auth/refresh` - Refresh access token
279
206
  - `POST /auth/logout` - Logout and revoke tokens
280
207
  - `GET /auth/profile` - Get current user profile
208
+
209
+ ### Password Management
210
+
281
211
  - `POST /auth/password-reset/request` - Request password reset
282
212
  - `POST /auth/password-reset/complete` - Complete password reset
283
213
  - `POST /auth/verify-email` - Verify email address
284
214
 
285
- ### Enterprise Features (v0.3.0+)
286
-
287
- **Two-Factor Authentication:**
288
- - `POST /auth/2fa/enable` - Enable 2FA and get QR code
289
- - `POST /auth/2fa/verify` - Verify 2FA setup
290
- - `POST /auth/2fa/verify-login` - Complete login with 2FA
291
- - `POST /auth/2fa/disable` - Disable 2FA
292
- - `POST /auth/2fa/backup-codes/regenerate` - Regenerate backup codes
293
-
294
- **Device Management:**
295
- - `GET /auth/devices` - List user's active devices
296
- - `POST /auth/devices/:deviceId/revoke` - Revoke specific device
297
-
298
- **Push Notifications:**
299
- - `POST /auth/push-tokens` - Register push notification token
300
- - `DELETE /auth/push-tokens/:tokenId` - Revoke push token
301
-
302
- **Account Management:**
303
- - `POST /auth/account/deactivate` - Deactivate account
304
- - `POST /auth/account/reactivate` - Reactivate account
305
- - `DELETE /auth/account` - Permanently delete account
306
-
307
- **Social Login:**
308
- - `POST /auth/social/google` - Google OAuth callback
309
- - `POST /auth/social/facebook` - Facebook OAuth callback
310
-
311
215
  ### Cross-Language Support
312
216
 
313
217
  - `GET /.well-known/jwks.json` - Public keys for JWT verification
314
218
 
315
- ---
316
-
317
- ## ๐ŸŽฏ How SSO Mode Works
318
-
319
- When you deploy in SSO mode, here's what happens:
320
-
321
- 1. **Auth Service (auth.yourdomain.com):**
322
- - Runs in `AUTH_MODE=full`
323
- - Has database and Redis
324
- - Handles login, registration, 2FA, etc.
325
- - Issues JWT tokens
326
- - Sets cookies for `.yourdomain.com`
327
-
328
- 2. **Your Projects (project1.yourdomain.com, project2.yourdomain.com):**
329
- - Run in `AUTH_MODE=sso`
330
- - No database or Redis needed
331
- - Only verify JWT tokens using public key
332
- - Read cookies from `.yourdomain.com`
333
- - Users are automatically authenticated!
334
-
335
- 3. **User Experience:**
336
- - User visits `project1.yourdomain.com`
337
- - Not logged in โ†’ Your frontend redirects to `auth.yourdomain.com/login`
338
- - User logs in at auth service
339
- - Cookie set for `.yourdomain.com`
340
- - Redirect back to `project1.yourdomain.com`
341
- - User is now logged in!
342
- - User visits `project2.yourdomain.com` โ†’ Already logged in! (same cookie)
343
-
344
- **Important:** This package is API-only. You need to build your own login/register UI that calls the auth endpoints.
345
-
346
- ---
347
-
348
- ## ๐Ÿ”ง Configuration Reference
349
-
350
- ## ๐Ÿ”ง Configuration Reference
351
-
352
- ### Complete Configuration Interface
219
+ ## Configuration Options
353
220
 
354
221
  ```typescript
355
222
  interface HorizonAuthConfig {
356
- // Mode Selection
357
- ssoMode?: boolean; // false = full auth service, true = token verification only
358
- authServiceUrl?: string; // Required when ssoMode=true
359
-
360
- // Database (required when ssoMode=false)
361
- database?: {
223
+ // Required
224
+ database: {
362
225
  url: string;
363
226
  };
364
-
365
- // Redis (required when ssoMode=false)
366
- redis?: {
227
+ redis: {
367
228
  host: string;
368
229
  port: number;
369
230
  password?: string;
370
231
  db?: number;
371
232
  };
372
-
373
- // JWT (always required)
374
233
  jwt: {
375
- privateKey?: string; // Required when ssoMode=false
376
- publicKey: string; // Always required
234
+ privateKey: string; // RSA private key (PEM format)
235
+ publicKey: string; // RSA public key (PEM format)
377
236
  accessTokenExpiry?: string; // Default: '15m'
378
237
  refreshTokenExpiry?: string; // Default: '7d'
379
238
  issuer?: string; // Default: 'horizon-auth'
380
239
  audience?: string; // Default: 'horizon-api'
381
- kid?: string; // Default: 'horizon-auth-key-1'
382
- };
383
-
384
- // Cookie Configuration
385
- cookie?: {
386
- domain?: string; // e.g., '.yourdomain.com' for SSO
387
- secure?: boolean; // Default: true in production
388
- sameSite?: 'strict' | 'lax' | 'none'; // Default: 'lax'
389
240
  };
390
-
391
- // Multi-Tenant Support
241
+
242
+ // Optional
392
243
  multiTenant?: {
393
244
  enabled: boolean;
394
245
  tenantIdExtractor?: 'header' | 'subdomain' | 'custom';
395
246
  defaultTenantId?: string;
396
247
  };
397
-
398
- // Rate Limiting
399
248
  rateLimit?: {
400
249
  login?: { limit: number; ttl: number };
401
250
  register?: { limit: number; ttl: number };
402
251
  passwordReset?: { limit: number; ttl: number };
403
252
  };
404
-
405
- // Email Configuration
406
- email?: {
407
- provider: 'resend' | 'sendgrid' | 'custom';
408
- apiKey?: string;
409
- from?: string;
410
- };
411
-
412
- // Global Guards
413
253
  guards?: {
414
254
  applyJwtGuardGlobally?: boolean;
415
255
  };
416
-
417
- // Enterprise Features
418
- features?: {
419
- twoFactor?: {
420
- enabled: boolean;
421
- issuer?: string; // Shows in authenticator apps
422
- };
423
- deviceManagement?: {
424
- enabled: boolean;
425
- maxDevicesPerUser?: number;
426
- };
427
- pushNotifications?: {
428
- enabled: boolean;
429
- };
430
- accountManagement?: {
431
- enabled: boolean;
432
- allowReactivation?: boolean;
433
- };
434
- socialLogin?: {
435
- google?: {
436
- clientId: string;
437
- clientSecret: string;
438
- callbackUrl: string;
439
- };
440
- facebook?: {
441
- appId: string;
442
- appSecret: string;
443
- callbackUrl: string;
444
- };
445
- };
446
- };
447
256
  }
448
257
  ```
449
258
 
450
- **๐Ÿ’ก Tip:** Use ENV variables instead of code config for maximum flexibility!
451
-
452
- ---
453
-
454
- ## ๐ŸŽญ Decorators
259
+ ## Decorators
455
260
 
456
261
  ### @Public()
457
262
  Mark routes as publicly accessible (skip authentication)
@@ -495,113 +300,105 @@ getTenantData(@CurrentTenant() tenantId: string) {
495
300
  }
496
301
  ```
497
302
 
498
- ## Enterprise Features Usage
499
-
500
- ### Two-Factor Authentication
303
+ ## Multi-Tenant Configuration
501
304
 
502
305
  ```typescript
503
- // Enable 2FA for a user
504
- const setup = await fetch('/auth/2fa/enable', {
505
- method: 'POST',
506
- headers: { Authorization: `Bearer ${accessToken}` },
507
- });
508
- const { secret, qrCode } = await setup.json();
509
-
510
- // Display QR code to user (qrCode is a data URL)
511
- // User scans with Google Authenticator or Authy
512
-
513
- // Verify setup with code from authenticator
514
- await fetch('/auth/2fa/verify', {
515
- method: 'POST',
516
- headers: {
517
- Authorization: `Bearer ${accessToken}`,
518
- 'Content-Type': 'application/json',
306
+ HorizonAuthModule.forRoot({
307
+ // ... other config
308
+ multiTenant: {
309
+ enabled: true,
310
+ tenantIdExtractor: 'header', // or 'subdomain' or 'custom'
311
+ defaultTenantId: 'default',
519
312
  },
520
- body: JSON.stringify({ code: '123456' }),
521
313
  });
314
+ ```
522
315
 
523
- // Login with 2FA
524
- const loginResponse = await fetch('/auth/login', {
525
- method: 'POST',
526
- body: JSON.stringify({ email, password }),
527
- });
316
+ ## Dev SSO Mode
528
317
 
529
- if (loginResponse.requiresTwoFactor) {
530
- // Prompt user for 2FA code
531
- await fetch('/auth/2fa/verify-login', {
532
- method: 'POST',
533
- body: JSON.stringify({
534
- userId: loginResponse.userId,
535
- code: '123456', // or backup code
536
- }),
537
- });
538
- }
318
+ For local development with multiple microservices:
319
+
320
+ ```yaml
321
+ # docker-compose.dev-sso.yml
322
+ version: '3.8'
323
+ services:
324
+ auth-service:
325
+ build: .
326
+ ports:
327
+ - '3000:3000'
328
+ environment:
329
+ COOKIE_DOMAIN: '.localhost'
330
+ REDIS_HOST: redis
331
+ depends_on:
332
+ - postgres
333
+ - redis
539
334
  ```
540
335
 
541
- ### Device Management
336
+ All `*.localhost:3000` apps will share the same authentication session.
542
337
 
543
- ```typescript
544
- // List user's devices (automatically tracked on login)
545
- const devices = await fetch('/auth/devices', {
546
- headers: { Authorization: `Bearer ${accessToken}` },
547
- }).then(r => r.json());
548
-
549
- // Revoke a specific device
550
- await fetch(`/auth/devices/${deviceId}/revoke`, {
551
- method: 'POST',
552
- headers: { Authorization: `Bearer ${accessToken}` },
553
- });
554
- ```
338
+ ## Cross-Language Token Verification
555
339
 
556
- ### Push Notifications
340
+ ### C# Example
557
341
 
558
- ```typescript
559
- // Register push token (requires device from login)
560
- await fetch('/auth/push-tokens', {
561
- method: 'POST',
562
- headers: {
563
- Authorization: `Bearer ${accessToken}`,
564
- 'Content-Type': 'application/json',
565
- },
566
- body: JSON.stringify({
567
- token: fcmToken, // From Firebase Cloud Messaging
568
- tokenType: 'FCM', // or 'APNS' for iOS
569
- deviceId: deviceId, // From device list
570
- }),
571
- });
342
+ ```csharp
343
+ using Microsoft.IdentityModel.Tokens;
344
+ using System.IdentityModel.Tokens.Jwt;
345
+
346
+ var jwks = await httpClient.GetStringAsync("http://auth-service/.well-known/jwks.json");
347
+ var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(jwks);
348
+
349
+ var tokenHandler = new JwtSecurityTokenHandler();
350
+ var validationParameters = new TokenValidationParameters
351
+ {
352
+ ValidateIssuerSigningKey = true,
353
+ IssuerSigningKeys = keys.Keys,
354
+ ValidateIssuer = true,
355
+ ValidIssuer = "horizon-auth",
356
+ ValidateAudience = true,
357
+ ValidAudience = "horizon-api"
358
+ };
359
+
360
+ var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
572
361
  ```
573
362
 
574
- ### Account Management
363
+ ### Python Example
575
364
 
576
- ```typescript
577
- // Deactivate account
578
- await fetch('/auth/account/deactivate', {
579
- method: 'POST',
580
- headers: {
581
- Authorization: `Bearer ${accessToken}`,
582
- 'Content-Type': 'application/json',
583
- },
584
- body: JSON.stringify({
585
- reason: 'Taking a break',
586
- }),
587
- });
365
+ ```python
366
+ import jwt
367
+ import requests
588
368
 
589
- // Reactivate account (no auth required)
590
- await fetch('/auth/account/reactivate', {
591
- method: 'POST',
592
- body: JSON.stringify({ email, password }),
593
- });
369
+ # Fetch JWKS
370
+ jwks_url = "http://auth-service/.well-known/jwks.json"
371
+ jwks = requests.get(jwks_url).json()
594
372
 
595
- // Permanently delete account
596
- await fetch('/auth/account', {
597
- method: 'DELETE',
598
- headers: { Authorization: `Bearer ${accessToken}` },
599
- });
373
+ # Verify token
374
+ token = "your-jwt-token"
375
+ decoded = jwt.decode(
376
+ token,
377
+ jwks,
378
+ algorithms=["RS256"],
379
+ issuer="horizon-auth",
380
+ audience="horizon-api"
381
+ )
600
382
  ```
601
383
 
602
- ---
384
+ ## Security Best Practices
385
+
386
+ 1. **Always use HTTPS in production**
387
+ 2. **Store RSA keys securely** (environment variables, secrets manager)
388
+ 3. **Enable rate limiting** to prevent brute force attacks
389
+ 4. **Monitor security events** (failed logins, token reuse)
390
+ 5. **Rotate JWT keys periodically**
391
+ 6. **Use strong Redis passwords** in production
603
392
 
604
- ## ๐ŸŒ Cross-Language Token Verification
393
+ ## Environment Variables
394
+
395
+ ```env
396
+ # Database
397
+ DATABASE_URL=postgresql://user:password@localhost:5432/horizon_auth
398
+
399
+ # Redis
400
+ REDIS_HOST=localhost
401
+ REDIS_PORT=6379
605
402
  REDIS_PASSWORD=your_redis_password
606
403
 
607
404
  # JWT Keys (for production - use multiline env vars)
@@ -751,209 +548,22 @@ docker run -p 3000:3000 \
751
548
  - All user tokens have been revoked for security
752
549
  - User needs to login again
753
550
 
754
- ### "Device ID required for push tokens"
755
- - Push tokens require a valid deviceId
756
- - Devices are created automatically on login (not registration)
757
- - Login first, then get device list, then register push token
758
-
759
- ### "Feature disabled" error
760
- - The feature you're trying to use is not enabled in configuration
761
- - Enable it in `HorizonAuthModule.forRoot({ features: { ... } })`
762
-
763
- ## Testing Status
764
-
765
- **โœ… Fully Tested:**
766
- - User registration and login
767
- - JWT token generation and validation
768
- - Refresh token rotation
769
- - 2FA setup (QR code generation)
770
- - Account deactivation/reactivation
771
- - Login protection for deactivated accounts
772
-
773
- **โš ๏ธ Requires Manual Testing:**
774
- - 2FA login flow (requires actual authenticator app)
775
- - Device tracking (automatic on login)
776
- - Push token registration (requires valid device)
777
- - Social login (requires OAuth credentials from Google/Facebook)
778
- - Backup codes usage during login
779
-
780
- ## ๐ŸŒ Cross-Platform Support
781
-
782
- **Works with ANY backend language!** Your auth service issues JWT tokens that can be verified by:
783
- - โœ… NestJS (use package in SSO mode)
784
- - โœ… .NET / C# (JWT Bearer Auth)
785
- - โœ… Python (PyJWT)
786
- - โœ… Go (golang-jwt)
787
- - โœ… Java / Spring Boot (OAuth2 Resource Server)
788
- - โœ… PHP (Firebase JWT)
789
- - โœ… Any language with JWT support!
790
-
791
- **๐Ÿ“– See [CROSS-PLATFORM-INTEGRATION.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/CROSS-PLATFORM-INTEGRATION.md) for complete integration guides with code examples.**
792
-
793
- ---
794
-
795
- ## ๐ŸŒ Cross-Language Token Verification
796
-
797
- Your other services (in any language) can verify tokens using the JWKS endpoint:
798
-
799
- ### C# Example
800
-
801
- ```csharp
802
- using Microsoft.IdentityModel.Tokens;
803
- using System.IdentityModel.Tokens.Jwt;
804
-
805
- var jwks = await httpClient.GetStringAsync("https://auth.yourdomain.com/.well-known/jwks.json");
806
- var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(jwks);
807
-
808
- var tokenHandler = new JwtSecurityTokenHandler();
809
- var validationParameters = new TokenValidationParameters
810
- {
811
- ValidateIssuerSigningKey = true,
812
- IssuerSigningKeys = keys.Keys,
813
- ValidateIssuer = true,
814
- ValidIssuer = "horizon-auth",
815
- ValidateAudience = true,
816
- ValidAudience = "horizon-api"
817
- };
818
-
819
- var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
820
- ```
821
-
822
- ### Python Example
823
-
824
- ```python
825
- import jwt
826
- import requests
827
-
828
- # Fetch JWKS
829
- jwks_url = "https://auth.yourdomain.com/.well-known/jwks.json"
830
- jwks = requests.get(jwks_url).json()
831
-
832
- # Verify token
833
- token = "your-jwt-token"
834
- decoded = jwt.decode(
835
- token,
836
- jwks,
837
- algorithms=["RS256"],
838
- issuer="horizon-auth",
839
- audience="horizon-api"
840
- )
841
- ```
842
-
843
- ---
844
-
845
- ## ๐Ÿ› Troubleshooting
846
-
847
- ### "AUTH_SERVICE_URL is required when AUTH_MODE=sso"
848
- Set `AUTH_SERVICE_URL` in your ENV file when using SSO mode.
849
-
850
- ### "JWT_PRIVATE_KEY is required when AUTH_MODE=full"
851
- Make sure you've set `JWT_PRIVATE_KEY` when running in full mode (auth service).
852
-
853
- ### "Invalid or expired access token"
854
- - Check that your JWT keys are correctly configured
855
- - Verify token hasn't expired (default 15 minutes)
856
- - Ensure token isn't blacklisted in Redis
857
-
858
- ### "Redis connection error"
859
- - Verify Redis is running: `docker ps` or check your cloud Redis service
860
- - Check Redis connection settings in ENV
861
- - Test connection: `redis-cli ping`
862
-
863
- ### "Token reuse detected"
864
- - This is a security feature - someone tried to reuse a revoked refresh token
865
- - All user tokens have been revoked for security
866
- - User needs to login again
867
-
868
- ### "Device ID required for push tokens"
869
- - Push tokens require a valid deviceId
870
- - Devices are created automatically on login (not registration)
871
- - Login first, then get device list, then register push token
551
+ ## Migration from Existing Auth
872
552
 
873
- ### "Feature disabled" error
874
- - The feature you're trying to use is not enabled
875
- - Enable it via ENV: `ENABLE_2FA=true`, `ENABLE_DEVICE_MGMT=true`, etc.
553
+ See [MIGRATION.md](./MIGRATION.md) for guides on:
554
+ - Migrating from bcrypt to Argon2id
555
+ - Migrating from HS256 to RS256
556
+ - Database schema migration
876
557
 
877
- ### Cookies not working across subdomains
878
- - Make sure `COOKIE_DOMAIN` starts with a dot: `.yourdomain.com`
879
- - Verify `COOKIE_SECURE=true` in production (requires HTTPS)
880
- - Check that all apps use the same cookie domain
881
-
882
- ---
883
-
884
- ## ๐Ÿ“š Documentation
885
-
886
- - **[ENV-CONFIGURATION.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/ENV-CONFIGURATION.md)** - Complete environment variable reference
887
- - **[DEPLOYMENT-EXAMPLES.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/DEPLOYMENT-EXAMPLES.md)** - Real-world deployment scenarios
888
- - **[CROSS-PLATFORM-INTEGRATION.md](https://github.com/OfekItzhaki/horizon-auth-platform/blob/main/CROSS-PLATFORM-INTEGRATION.md)** - Integration with .NET, Python, Go, Java, PHP
889
- - **[GitHub Repository](https://github.com/OfekItzhaki/horizon-auth-platform)** - Source code and issues
890
-
891
- ---
892
-
893
- ## ๐Ÿงช Testing Status
894
-
895
- **โœ… Fully Tested:**
896
- - User registration and login
897
- - JWT token generation and validation
898
- - Refresh token rotation
899
- - 2FA setup (QR code generation)
900
- - Account deactivation/reactivation
901
- - Login protection for deactivated accounts
902
- - SSO mode token verification
903
-
904
- **โš ๏ธ Requires Manual Testing:**
905
- - 2FA login flow (requires actual authenticator app)
906
- - Device tracking (automatic on login)
907
- - Push token registration (requires valid device)
908
- - Social login (requires OAuth credentials from Google/Facebook)
909
- - Backup codes usage during login
910
-
911
- ---
912
-
913
- ## ๐Ÿ“ฆ What's New
914
-
915
- ### v0.4.1 (Latest)
916
- - ๐Ÿ“ **Cross-platform integration guide** - Complete examples for .NET, Python, Go, Java, PHP
917
- - ๐Ÿ“ Enhanced README with cross-platform support section
918
- - ๐ŸŒ JWKS endpoint documentation for polyglot architectures
919
-
920
- ### v0.4.0
921
- - โœจ **ENV-based configuration** - Zero code changes needed!
922
- - โœจ **Flexible deployment** - Same package for embedded and SSO modes
923
- - ๐Ÿ“ Complete ENV variable documentation
924
- - ๐Ÿ“ Real-world deployment examples
925
- - ๐Ÿ”ง Improved configuration merging
926
-
927
- ### v0.3.0
928
- - โœจ Two-Factor Authentication (TOTP)
929
- - โœจ Device Management
930
- - โœจ Push Notifications
931
- - โœจ Account Management
932
- - โœจ Social Login (Google, Facebook)
933
-
934
- ### v0.2.1
935
- - ๐Ÿ› Fixed SSO mode JWT strategy
936
- - ๐Ÿ”ง Dynamic module configuration
937
-
938
- ---
939
-
940
- ## ๐Ÿ“„ License
558
+ ## License
941
559
 
942
560
  MIT
943
561
 
944
- ---
945
-
946
- ## ๐Ÿค Support
947
-
948
- - **Issues:** [GitHub Issues](https://github.com/OfekItzhaki/horizon-auth-platform/issues)
949
- - **Discussions:** [GitHub Discussions](https://github.com/OfekItzhaki/horizon-auth-platform/discussions)
562
+ ## Support
950
563
 
951
- ---
952
-
953
- ## ๐Ÿ‘จโ€๐Ÿ’ป Author
564
+ - GitHub Issues: https://github.com/OfekItzhaki/horizon-auth-platform/issues
565
+ - Documentation: https://github.com/OfekItzhaki/horizon-auth-platform
954
566
 
955
- Created by **Ofek Itzhaki**
956
-
957
- ---
567
+ ## Credits
958
568
 
959
- **โญ If this package helps you, consider giving it a star on GitHub!**
569
+ Created by Ofek Itzhaki