@lenne.tech/nest-server 11.6.2 → 11.7.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.
- package/dist/config.env.js +2 -11
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +9 -9
- package/dist/core/common/helpers/filter.helper.js +2 -4
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/gridfs.helper.js +3 -3
- package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +4 -3
- package/dist/core/common/services/crud.service.d.ts +16 -16
- package/dist/core/common/services/crud.service.js +1 -1
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-models.d.ts +0 -1
- package/dist/core/modules/better-auth/better-auth-models.js +0 -4
- package/dist/core/modules/better-auth/better-auth-models.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +3 -0
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.module.d.ts +10 -2
- package/dist/core/modules/better-auth/better-auth.module.js +40 -52
- package/dist/core/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +8 -12
- package/dist/core/modules/better-auth/better-auth.resolver.js +33 -351
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.service.d.ts +0 -1
- package/dist/core/modules/better-auth/better-auth.service.js +0 -3
- package/dist/core/modules/better-auth/better-auth.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +9 -8
- package/dist/core/modules/better-auth/better-auth.types.js +14 -3
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +66 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js +491 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +59 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +538 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +2 -0
- package/dist/core/modules/better-auth/index.js +2 -0
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core.module.js +1 -1
- package/dist/core.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +10 -0
- package/dist/server/modules/better-auth/better-auth.controller.js +36 -0
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.module.d.ts +9 -0
- package/dist/server/modules/better-auth/better-auth.module.js +44 -0
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +45 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js +221 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -0
- package/dist/server/modules/file/file-info.model.d.ts +71 -3
- package/dist/server/modules/user/user.model.d.ts +169 -3
- package/dist/server/server.module.js +6 -1
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +20 -29
- package/src/config.env.ts +2 -11
- package/src/core/common/helpers/filter.helper.ts +15 -17
- package/src/core/common/helpers/gridfs.helper.ts +5 -5
- package/src/core/common/interfaces/server-options.interface.ts +47 -14
- package/src/core/common/services/crud.service.ts +22 -22
- package/src/core/modules/better-auth/README.md +365 -39
- package/src/core/modules/better-auth/better-auth-models.ts +0 -3
- package/src/core/modules/better-auth/better-auth.config.ts +5 -0
- package/src/core/modules/better-auth/better-auth.module.ts +107 -66
- package/src/core/modules/better-auth/better-auth.resolver.ts +88 -553
- package/src/core/modules/better-auth/better-auth.service.ts +0 -9
- package/src/core/modules/better-auth/better-auth.types.ts +25 -10
- package/src/core/modules/better-auth/core-better-auth.controller.ts +605 -0
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +705 -0
- package/src/core/modules/better-auth/index.ts +8 -1
- package/src/core.module.ts +3 -2
- package/src/server/modules/better-auth/better-auth.controller.ts +41 -0
- package/src/server/modules/better-auth/better-auth.module.ts +88 -0
- package/src/server/modules/better-auth/better-auth.resolver.ts +201 -0
- package/src/server/server.module.ts +10 -1
|
@@ -9,7 +9,6 @@ Integration of the [better-auth](https://better-auth.com) authentication framewo
|
|
|
9
9
|
- **JWT Tokens** - For API clients and stateless authentication
|
|
10
10
|
- **Two-Factor Authentication (2FA)** - TOTP-based second factor
|
|
11
11
|
- **Passkey/WebAuthn** - Passwordless authentication
|
|
12
|
-
- **Legacy Password Handling** - Migration support for existing users
|
|
13
12
|
|
|
14
13
|
### Core Features
|
|
15
14
|
|
|
@@ -26,16 +25,46 @@ Integration of the [better-auth](https://better-auth.com) authentication framewo
|
|
|
26
25
|
|
|
27
26
|
## Quick Start
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
Better-Auth is **enabled by default** and uses sensible defaults. Integration follows the same pattern as Legacy Auth - via an extended module in your project.
|
|
29
|
+
|
|
30
|
+
### 1. Create Extended Module (Recommended)
|
|
30
31
|
|
|
31
32
|
```typescript
|
|
32
|
-
//
|
|
33
|
-
|
|
33
|
+
// src/server/modules/better-auth/better-auth.module.ts
|
|
34
|
+
import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
|
|
35
|
+
|
|
36
|
+
@Module({})
|
|
37
|
+
export class BetterAuthModule {
|
|
38
|
+
static forRoot(options) {
|
|
39
|
+
return {
|
|
40
|
+
module: BetterAuthModule,
|
|
41
|
+
imports: [CoreBetterAuthModule.forRoot(options)],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Import in ServerModule
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// src/server/server.module.ts
|
|
51
|
+
import { BetterAuthModule } from './modules/better-auth/better-auth.module';
|
|
52
|
+
|
|
53
|
+
@Module({
|
|
54
|
+
imports: [
|
|
55
|
+
CoreModule.forRoot(environment),
|
|
56
|
+
BetterAuthModule.forRoot({ config: environment.betterAuth }),
|
|
57
|
+
],
|
|
58
|
+
})
|
|
59
|
+
export class ServerModule {}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Configure (Optional)
|
|
34
63
|
|
|
35
|
-
|
|
64
|
+
```typescript
|
|
65
|
+
// config.env.ts - customize behavior (optional):
|
|
36
66
|
const config = {
|
|
37
67
|
betterAuth: {
|
|
38
|
-
// Only add this block if you need to override defaults
|
|
39
68
|
// baseUrl: 'https://your-domain.com',
|
|
40
69
|
// basePath: '/iam',
|
|
41
70
|
},
|
|
@@ -51,12 +80,12 @@ const config = {
|
|
|
51
80
|
- **Passkey rpId**: `localhost`
|
|
52
81
|
- **Passkey rpName**: `Nest Server`
|
|
53
82
|
|
|
54
|
-
To **explicitly disable** Better-Auth
|
|
83
|
+
To **explicitly disable** Better-Auth:
|
|
55
84
|
|
|
56
85
|
```typescript
|
|
57
86
|
const config = {
|
|
58
87
|
betterAuth: {
|
|
59
|
-
enabled: false,
|
|
88
|
+
enabled: false,
|
|
60
89
|
},
|
|
61
90
|
};
|
|
62
91
|
```
|
|
@@ -262,10 +291,6 @@ export default {
|
|
|
262
291
|
},
|
|
263
292
|
},
|
|
264
293
|
|
|
265
|
-
// Legacy Password Handling (enabled by default when config block is present)
|
|
266
|
-
// Set enabled: false to explicitly disable
|
|
267
|
-
legacyPassword: {},
|
|
268
|
-
|
|
269
294
|
// Trusted Origins for CORS
|
|
270
295
|
trustedOrigins: ['http://localhost:3000', 'https://your-app.com'],
|
|
271
296
|
|
|
@@ -282,6 +307,127 @@ export default {
|
|
|
282
307
|
};
|
|
283
308
|
```
|
|
284
309
|
|
|
310
|
+
## Advanced Configuration
|
|
311
|
+
|
|
312
|
+
### Email/Password Authentication
|
|
313
|
+
|
|
314
|
+
Email/password authentication is enabled by default. You can disable it if you only want social login:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
const config = {
|
|
318
|
+
betterAuth: {
|
|
319
|
+
emailAndPassword: {
|
|
320
|
+
enabled: false, // Disable email/password, only allow social login
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Additional User Fields
|
|
327
|
+
|
|
328
|
+
Add custom fields to the Better-Auth user schema:
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
const config = {
|
|
332
|
+
betterAuth: {
|
|
333
|
+
additionalUserFields: {
|
|
334
|
+
phoneNumber: { type: 'string', defaultValue: null },
|
|
335
|
+
department: { type: 'string', required: true },
|
|
336
|
+
preferences: { type: 'string', defaultValue: '{}' },
|
|
337
|
+
isActive: { type: 'boolean', defaultValue: true },
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Available field types:** `'string'`, `'number'`, `'boolean'`, `'date'`, `'json'`, `'string[]'`, `'number[]'`
|
|
344
|
+
|
|
345
|
+
### Module Integration (Recommended Pattern)
|
|
346
|
+
|
|
347
|
+
By default (`autoRegister: false`), projects integrate BetterAuth via an **extended module** in their project. This follows the same pattern as Legacy Auth and allows for custom resolvers, controllers, and project-specific authentication logic.
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// src/server/modules/better-auth/better-auth.module.ts
|
|
351
|
+
import { Module, DynamicModule } from '@nestjs/common';
|
|
352
|
+
import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
|
|
353
|
+
|
|
354
|
+
@Module({})
|
|
355
|
+
export class BetterAuthModule {
|
|
356
|
+
static forRoot(options): DynamicModule {
|
|
357
|
+
return {
|
|
358
|
+
module: BetterAuthModule,
|
|
359
|
+
imports: [CoreBetterAuthModule.forRoot(options)],
|
|
360
|
+
// Add custom providers, resolvers, etc.
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/server/server.module.ts
|
|
366
|
+
import { BetterAuthModule } from './modules/better-auth/better-auth.module';
|
|
367
|
+
|
|
368
|
+
@Module({
|
|
369
|
+
imports: [
|
|
370
|
+
CoreModule.forRoot(environment),
|
|
371
|
+
BetterAuthModule.forRoot({
|
|
372
|
+
config: environment.betterAuth,
|
|
373
|
+
resolver: CustomBetterAuthResolver, // Optional custom resolver
|
|
374
|
+
}),
|
|
375
|
+
],
|
|
376
|
+
})
|
|
377
|
+
export class ServerModule {}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Auto-Registration (Simple Projects)
|
|
381
|
+
|
|
382
|
+
For simple projects that don't need customization, you can enable auto-registration:
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
// In config.env.ts
|
|
386
|
+
const config = {
|
|
387
|
+
betterAuth: {
|
|
388
|
+
autoRegister: true, // Enable auto-registration in CoreModule
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// No manual import needed - CoreModule handles everything
|
|
393
|
+
@Module({
|
|
394
|
+
imports: [CoreModule.forRoot(environment)],
|
|
395
|
+
})
|
|
396
|
+
export class ServerModule {}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Options Passthrough
|
|
400
|
+
|
|
401
|
+
For full Better-Auth customization, use the `options` passthrough. These options are passed directly to Better-Auth:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
const config = {
|
|
405
|
+
betterAuth: {
|
|
406
|
+
options: {
|
|
407
|
+
emailAndPassword: {
|
|
408
|
+
requireEmailVerification: true,
|
|
409
|
+
sendResetPassword: async ({ user, url }) => {
|
|
410
|
+
// Custom password reset email logic
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
account: {
|
|
414
|
+
accountLinking: { enabled: true },
|
|
415
|
+
},
|
|
416
|
+
session: {
|
|
417
|
+
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
|
418
|
+
updateAge: 60 * 60 * 24, // 1 day
|
|
419
|
+
},
|
|
420
|
+
advanced: {
|
|
421
|
+
cookiePrefix: 'my-app',
|
|
422
|
+
useSecureCookies: true,
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
See [Better-Auth Options Reference](https://www.better-auth.com/docs/reference/options) for all available options.
|
|
430
|
+
|
|
285
431
|
## Plugins and Extensions
|
|
286
432
|
|
|
287
433
|
Better-Auth provides a rich plugin ecosystem. This module uses a **hybrid approach**:
|
|
@@ -298,7 +444,6 @@ These plugins are enabled by default when their config block is present. **All p
|
|
|
298
444
|
| **JWT** | `jwt: {}` | `expiresIn: '15m'` |
|
|
299
445
|
| **Two-Factor** | `twoFactor: {}` | `appName: 'Nest Server'` |
|
|
300
446
|
| **Passkey** | `passkey: {}` | `origin: 'http://localhost:3000'`, `rpId: 'localhost'`, `rpName: 'Nest Server'` |
|
|
301
|
-
| **Legacy Password**| `legacyPassword: {}` | No config needed |
|
|
302
447
|
|
|
303
448
|
#### Minimal Syntax (Recommended for Development)
|
|
304
449
|
|
|
@@ -309,7 +454,6 @@ const config = {
|
|
|
309
454
|
jwt: {},
|
|
310
455
|
twoFactor: {},
|
|
311
456
|
passkey: {},
|
|
312
|
-
legacyPassword: {},
|
|
313
457
|
},
|
|
314
458
|
};
|
|
315
459
|
```
|
|
@@ -326,7 +470,6 @@ const config = {
|
|
|
326
470
|
rpName: 'My App',
|
|
327
471
|
origin: 'https://example.com',
|
|
328
472
|
},
|
|
329
|
-
legacyPassword: {},
|
|
330
473
|
},
|
|
331
474
|
};
|
|
332
475
|
```
|
|
@@ -472,50 +615,80 @@ const config = {
|
|
|
472
615
|
|
|
473
616
|
## Module Setup
|
|
474
617
|
|
|
475
|
-
|
|
618
|
+
Better-Auth is **enabled by default** but requires explicit module integration (`autoRegister: false` by default). This follows the same pattern as Legacy Auth, giving projects full control over customization.
|
|
476
619
|
|
|
477
|
-
###
|
|
620
|
+
### Recommended: Extended Module Pattern
|
|
621
|
+
|
|
622
|
+
Projects typically integrate Better-Auth via an extended module:
|
|
478
623
|
|
|
479
624
|
```typescript
|
|
480
|
-
//
|
|
625
|
+
// src/server/modules/better-auth/better-auth.module.ts
|
|
626
|
+
import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
|
|
627
|
+
|
|
628
|
+
@Module({})
|
|
629
|
+
export class BetterAuthModule {
|
|
630
|
+
static forRoot(options): DynamicModule {
|
|
631
|
+
return {
|
|
632
|
+
module: BetterAuthModule,
|
|
633
|
+
imports: [CoreBetterAuthModule.forRoot(options)],
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/server/server.module.ts
|
|
481
639
|
@Module({
|
|
482
640
|
imports: [
|
|
483
641
|
CoreModule.forRoot(environment),
|
|
484
|
-
|
|
485
|
-
// No betterAuth config block needed - works out of the box!
|
|
642
|
+
BetterAuthModule.forRoot({ config: environment.betterAuth }),
|
|
486
643
|
],
|
|
487
644
|
})
|
|
488
645
|
export class ServerModule {}
|
|
489
646
|
```
|
|
490
647
|
|
|
491
|
-
###
|
|
648
|
+
### Simple: Auto-Registration
|
|
649
|
+
|
|
650
|
+
For simple projects without customization needs:
|
|
492
651
|
|
|
493
652
|
```typescript
|
|
494
|
-
|
|
653
|
+
// In config.env.ts
|
|
654
|
+
const config = {
|
|
655
|
+
betterAuth: {
|
|
656
|
+
autoRegister: true, // Let CoreModule handle registration
|
|
657
|
+
},
|
|
658
|
+
};
|
|
495
659
|
|
|
660
|
+
// In server.module.ts - no manual import needed
|
|
496
661
|
@Module({
|
|
497
|
-
imports: [
|
|
498
|
-
BetterAuthModule.forRoot({
|
|
499
|
-
config: environment.betterAuth,
|
|
500
|
-
}),
|
|
501
|
-
],
|
|
662
|
+
imports: [CoreModule.forRoot(environment)],
|
|
502
663
|
})
|
|
503
|
-
export class
|
|
664
|
+
export class ServerModule {}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### Disable Better-Auth
|
|
668
|
+
|
|
669
|
+
To explicitly disable Better-Auth:
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
const config = {
|
|
673
|
+
betterAuth: {
|
|
674
|
+
enabled: false,
|
|
675
|
+
},
|
|
676
|
+
};
|
|
504
677
|
```
|
|
505
678
|
|
|
506
679
|
## REST API Endpoints
|
|
507
680
|
|
|
508
681
|
When enabled, Better-Auth exposes the following endpoints at the configured `basePath` (default: `/iam`):
|
|
509
682
|
|
|
510
|
-
| Endpoint
|
|
511
|
-
|
|
|
512
|
-
| `/iam/sign-up` | POST | Register new user |
|
|
513
|
-
| `/iam/sign-in` | POST | Sign in with email/password |
|
|
514
|
-
| `/iam/sign-out`
|
|
515
|
-
| `/iam/session`
|
|
516
|
-
| `/iam/forgot-password
|
|
517
|
-
| `/iam/reset-password`
|
|
518
|
-
| `/iam/verify-email`
|
|
683
|
+
| Endpoint | Method | Description |
|
|
684
|
+
| --------------------------- | ------ | ---------------------------- |
|
|
685
|
+
| `/iam/sign-up/email` | POST | Register new user |
|
|
686
|
+
| `/iam/sign-in/email` | POST | Sign in with email/password |
|
|
687
|
+
| `/iam/sign-out` | GET | Sign out (invalidate session)|
|
|
688
|
+
| `/iam/session` | GET | Get current session |
|
|
689
|
+
| `/iam/forgot-password` | POST | Request password reset |
|
|
690
|
+
| `/iam/reset-password` | POST | Reset password with token |
|
|
691
|
+
| `/iam/verify-email` | POST | Verify email address |
|
|
519
692
|
|
|
520
693
|
### Social Login Endpoints
|
|
521
694
|
|
|
@@ -601,7 +774,6 @@ type BetterAuthFeaturesModel {
|
|
|
601
774
|
jwt: Boolean!
|
|
602
775
|
twoFactor: Boolean!
|
|
603
776
|
passkey: Boolean!
|
|
604
|
-
legacyPassword: Boolean!
|
|
605
777
|
socialProviders: [String!]!
|
|
606
778
|
}
|
|
607
779
|
```
|
|
@@ -799,7 +971,6 @@ export class MyService {
|
|
|
799
971
|
| `isJwtEnabled()` | Check if JWT plugin is enabled |
|
|
800
972
|
| `isTwoFactorEnabled()` | Check if 2FA is enabled |
|
|
801
973
|
| `isPasskeyEnabled()` | Check if Passkey is enabled |
|
|
802
|
-
| `isLegacyPasswordEnabled()` | Check if legacy password handling is enabled |
|
|
803
974
|
| `getEnabledSocialProviders()` | Get list of enabled social providers |
|
|
804
975
|
| `getBasePath()` | Get the base path for endpoints |
|
|
805
976
|
| `getBaseUrl()` | Get the base URL |
|
|
@@ -1094,3 +1265,158 @@ const config = {
|
|
|
1094
1265
|
|
|
1095
1266
|
4. **Monitor rate limit events** - The service logs warnings when limits are exceeded
|
|
1096
1267
|
5. **Consider Redis** - For multi-instance deployments, implement Redis-based rate limiting
|
|
1268
|
+
|
|
1269
|
+
## Extending Better-Auth (Custom Resolver)
|
|
1270
|
+
|
|
1271
|
+
Better-Auth uses the same extension pattern as Legacy Auth. You can extend `CoreBetterAuthResolver` to add custom logic before/after authentication operations.
|
|
1272
|
+
|
|
1273
|
+
### Creating a Custom Resolver
|
|
1274
|
+
|
|
1275
|
+
```typescript
|
|
1276
|
+
// src/server/modules/better-auth/better-auth.resolver.ts
|
|
1277
|
+
import { Resolver } from '@nestjs/graphql';
|
|
1278
|
+
import { Roles } from '@lenne.tech/nest-server';
|
|
1279
|
+
import {
|
|
1280
|
+
BetterAuthAuthModel,
|
|
1281
|
+
BetterAuthService,
|
|
1282
|
+
BetterAuthUserMapper,
|
|
1283
|
+
CoreBetterAuthResolver,
|
|
1284
|
+
RoleEnum,
|
|
1285
|
+
} from '@lenne.tech/nest-server';
|
|
1286
|
+
import { EmailService } from '../email/email.service';
|
|
1287
|
+
|
|
1288
|
+
@Resolver(() => BetterAuthAuthModel)
|
|
1289
|
+
@Roles(RoleEnum.ADMIN)
|
|
1290
|
+
export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
1291
|
+
constructor(
|
|
1292
|
+
betterAuthService: BetterAuthService,
|
|
1293
|
+
userMapper: BetterAuthUserMapper,
|
|
1294
|
+
private readonly emailService: EmailService,
|
|
1295
|
+
) {
|
|
1296
|
+
super(betterAuthService, userMapper);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/**
|
|
1300
|
+
* Override signUp to send welcome email after registration
|
|
1301
|
+
*/
|
|
1302
|
+
override async betterAuthSignUp(
|
|
1303
|
+
email: string,
|
|
1304
|
+
password: string,
|
|
1305
|
+
name?: string,
|
|
1306
|
+
): Promise<BetterAuthAuthModel> {
|
|
1307
|
+
// Call original implementation
|
|
1308
|
+
const result = await super.betterAuthSignUp(email, password, name);
|
|
1309
|
+
|
|
1310
|
+
// Add custom logic after successful sign-up
|
|
1311
|
+
if (result.success && result.user) {
|
|
1312
|
+
await this.emailService.sendWelcomeEmail(result.user.email, result.user.name);
|
|
1313
|
+
await this.analyticsService.trackSignUp(result.user.id);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* Override signIn to add custom tracking
|
|
1321
|
+
*/
|
|
1322
|
+
override async betterAuthSignIn(
|
|
1323
|
+
email: string,
|
|
1324
|
+
password: string,
|
|
1325
|
+
ctx: { req: Request; res: Response },
|
|
1326
|
+
): Promise<BetterAuthAuthModel> {
|
|
1327
|
+
// Add pre-login logic
|
|
1328
|
+
this.logger.log(`Login attempt for ${email}`);
|
|
1329
|
+
|
|
1330
|
+
const result = await super.betterAuthSignIn(email, password, ctx);
|
|
1331
|
+
|
|
1332
|
+
// Add post-login logic
|
|
1333
|
+
if (result.success && result.user) {
|
|
1334
|
+
await this.analyticsService.trackLogin(result.user.id);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
return result;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
### Registering the Custom Resolver
|
|
1343
|
+
|
|
1344
|
+
**Option 1: Via BetterAuthModule options**
|
|
1345
|
+
|
|
1346
|
+
```typescript
|
|
1347
|
+
// src/server/server.module.ts
|
|
1348
|
+
import { BetterAuthModule } from '@lenne.tech/nest-server';
|
|
1349
|
+
import { BetterAuthResolver } from './modules/better-auth/better-auth.resolver';
|
|
1350
|
+
|
|
1351
|
+
@Module({
|
|
1352
|
+
imports: [
|
|
1353
|
+
CoreModule.forRoot(environment),
|
|
1354
|
+
BetterAuthModule.forRoot({
|
|
1355
|
+
config: environment.betterAuth,
|
|
1356
|
+
resolver: BetterAuthResolver, // Your custom resolver
|
|
1357
|
+
}),
|
|
1358
|
+
],
|
|
1359
|
+
})
|
|
1360
|
+
export class ServerModule {}
|
|
1361
|
+
```
|
|
1362
|
+
|
|
1363
|
+
**Option 2: Create your own module (like Legacy Auth)**
|
|
1364
|
+
|
|
1365
|
+
```typescript
|
|
1366
|
+
// src/server/modules/better-auth/better-auth.module.ts
|
|
1367
|
+
import { Module } from '@nestjs/common';
|
|
1368
|
+
import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
|
|
1369
|
+
import { BetterAuthResolver } from './better-auth.resolver';
|
|
1370
|
+
import { EmailModule } from '../email/email.module';
|
|
1371
|
+
|
|
1372
|
+
@Module({
|
|
1373
|
+
imports: [
|
|
1374
|
+
CoreBetterAuthModule.forRoot({
|
|
1375
|
+
config: environment.betterAuth,
|
|
1376
|
+
resolver: BetterAuthResolver,
|
|
1377
|
+
}),
|
|
1378
|
+
EmailModule,
|
|
1379
|
+
],
|
|
1380
|
+
providers: [BetterAuthResolver],
|
|
1381
|
+
exports: [BetterAuthResolver],
|
|
1382
|
+
})
|
|
1383
|
+
export class BetterAuthModule {}
|
|
1384
|
+
```
|
|
1385
|
+
|
|
1386
|
+
### Available Override Methods
|
|
1387
|
+
|
|
1388
|
+
All methods in `CoreBetterAuthResolver` can be overridden:
|
|
1389
|
+
|
|
1390
|
+
| Method | Description |
|
|
1391
|
+
| ------ | ----------- |
|
|
1392
|
+
| `betterAuthSignIn(email, password, ctx)` | Sign in with email/password |
|
|
1393
|
+
| `betterAuthSignUp(email, password, name?)` | Register new user |
|
|
1394
|
+
| `betterAuthSignOut(ctx)` | Sign out current session |
|
|
1395
|
+
| `betterAuthVerify2FA(code, ctx)` | Verify 2FA code |
|
|
1396
|
+
| `betterAuthEnable2FA(password, ctx)` | Enable 2FA for user |
|
|
1397
|
+
| `betterAuthDisable2FA(password, ctx)` | Disable 2FA for user |
|
|
1398
|
+
| `betterAuthGenerateBackupCodes(ctx)` | Generate new backup codes |
|
|
1399
|
+
| `betterAuthGetPasskeyChallenge(ctx)` | Get WebAuthn challenge |
|
|
1400
|
+
| `betterAuthListPasskeys(ctx)` | List user's passkeys |
|
|
1401
|
+
| `betterAuthDeletePasskey(passkeyId, ctx)` | Delete a passkey |
|
|
1402
|
+
| `betterAuthSession(ctx)` | Get current session |
|
|
1403
|
+
| `betterAuthEnabled()` | Check if Better-Auth is enabled |
|
|
1404
|
+
| `betterAuthFeatures()` | Get enabled features |
|
|
1405
|
+
|
|
1406
|
+
### Helper Methods (Protected)
|
|
1407
|
+
|
|
1408
|
+
These protected methods are available for use in your custom resolver:
|
|
1409
|
+
|
|
1410
|
+
```typescript
|
|
1411
|
+
// Check if Better-Auth is enabled (throws if not)
|
|
1412
|
+
this.ensureEnabled();
|
|
1413
|
+
|
|
1414
|
+
// Convert Express headers to Web API Headers
|
|
1415
|
+
const headers = this.convertHeaders(ctx.req.headers);
|
|
1416
|
+
|
|
1417
|
+
// Map session info
|
|
1418
|
+
const sessionInfo = this.mapSessionInfo(response.session);
|
|
1419
|
+
|
|
1420
|
+
// Map user to model
|
|
1421
|
+
const userModel = this.mapToUserModel(mappedUser);
|
|
1422
|
+
```
|
|
@@ -135,9 +135,6 @@ export class BetterAuthFeaturesModel {
|
|
|
135
135
|
@Field(() => Boolean, { description: 'Whether Passkey is enabled' })
|
|
136
136
|
passkey: boolean;
|
|
137
137
|
|
|
138
|
-
@Field(() => Boolean, { description: 'Whether legacy password handling is enabled' })
|
|
139
|
-
legacyPassword: boolean;
|
|
140
|
-
|
|
141
138
|
@Field(() => [String], { description: 'List of enabled social providers' })
|
|
142
139
|
socialProviders: string[];
|
|
143
140
|
}
|
|
@@ -139,6 +139,11 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Bett
|
|
|
139
139
|
basePath: config.basePath || '/iam',
|
|
140
140
|
baseURL: config.baseUrl || 'http://localhost:3000',
|
|
141
141
|
database: mongodbAdapter(db),
|
|
142
|
+
// Enable email/password authentication by default (required by Better-Auth 1.x)
|
|
143
|
+
// Can be disabled by setting config.emailAndPassword.enabled = false
|
|
144
|
+
emailAndPassword: {
|
|
145
|
+
enabled: config.emailAndPassword?.enabled !== false,
|
|
146
|
+
},
|
|
142
147
|
plugins,
|
|
143
148
|
secret: config.secret,
|
|
144
149
|
socialProviders,
|