@lenne.tech/nest-server 11.12.0 → 11.13.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 +1 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +16 -0
- package/dist/core/modules/better-auth/better-auth.config.d.ts +13 -0
- package/dist/core/modules/better-auth/better-auth.config.js +68 -18
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +7 -3
- package/dist/core/modules/better-auth/better-auth.resolver.js +16 -6
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +2 -2
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +46 -2
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-auth.model.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js +7 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.d.ts +48 -0
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +241 -0
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-models.d.ts +2 -1
- package/dist/core/modules/better-auth/core-better-auth-models.js +8 -4
- package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-signup-validator.service.d.ts +18 -0
- package/dist/core/modules/better-auth/core-better-auth-signup-validator.service.js +82 -0
- package/dist/core/modules/better-auth/core-better-auth-signup-validator.service.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +0 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +15 -8
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js +33 -24
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +11 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js +91 -15
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.js +55 -19
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +6 -0
- package/dist/core/modules/better-auth/core-better-auth.module.js +129 -24
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +12 -5
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +64 -17
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.d.ts +4 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js +123 -23
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- 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/modules/error-code/error-codes.d.ts +45 -0
- package/dist/core/modules/error-code/error-codes.js +40 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -1
- package/dist/core/modules/user/core-user.model.d.ts +1 -0
- package/dist/core/modules/user/core-user.model.js +11 -0
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +3 -1
- package/dist/server/modules/better-auth/better-auth.controller.js +12 -3
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +7 -3
- package/dist/server/modules/better-auth/better-auth.resolver.js +16 -6
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/error-code/error-codes.d.ts +5 -0
- package/dist/server/modules/user/user.model.d.ts +5 -0
- package/dist/templates/email-verification-de.ejs +78 -0
- package/dist/templates/email-verification-en.ejs +78 -0
- package/dist/test/test.helper.d.ts +4 -0
- package/dist/test/test.helper.js +54 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config.env.ts +2 -0
- package/src/core/common/interfaces/server-options.interface.ts +240 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +113 -0
- package/src/core/modules/better-auth/README.md +72 -7
- package/src/core/modules/better-auth/better-auth.config.ts +168 -42
- package/src/core/modules/better-auth/better-auth.resolver.ts +16 -5
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +65 -8
- package/src/core/modules/better-auth/core-better-auth-auth.model.ts +10 -0
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +433 -0
- package/src/core/modules/better-auth/core-better-auth-models.ts +6 -3
- package/src/core/modules/better-auth/core-better-auth-signup-validator.service.ts +178 -0
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +18 -14
- package/src/core/modules/better-auth/core-better-auth-web.helper.ts +53 -40
- package/src/core/modules/better-auth/core-better-auth.controller.ts +155 -16
- package/src/core/modules/better-auth/core-better-auth.middleware.ts +89 -31
- package/src/core/modules/better-auth/core-better-auth.module.ts +215 -38
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +140 -20
- package/src/core/modules/better-auth/core-better-auth.service.ts +181 -25
- package/src/core/modules/better-auth/index.ts +2 -0
- package/src/core/modules/error-code/error-codes.ts +45 -0
- package/src/core/modules/user/core-user.model.ts +15 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +6 -2
- package/src/server/modules/better-auth/better-auth.resolver.ts +16 -5
- package/src/templates/email-verification-de.ejs +78 -0
- package/src/templates/email-verification-en.ejs +78 -0
- package/src/test/README.md +190 -0
- package/src/test/test.helper.ts +82 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.13.0",
|
|
4
4
|
"description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
package/src/config.env.ts
CHANGED
|
@@ -125,6 +125,8 @@ const config: { [env: string]: IServerOptions } = {
|
|
|
125
125
|
},
|
|
126
126
|
automaticObjectIdFiltering: true,
|
|
127
127
|
betterAuth: {
|
|
128
|
+
// Email verification disabled for test environment (no real mailbox available)
|
|
129
|
+
emailVerification: false,
|
|
128
130
|
// JWT enabled by default (zero-config)
|
|
129
131
|
jwt: { enabled: true, expiresIn: '15m' },
|
|
130
132
|
// Passkey auto-activated when URLs can be resolved (env: 'local' → localhost defaults)
|
|
@@ -231,6 +231,128 @@ export interface IAuthRateLimit {
|
|
|
231
231
|
*/
|
|
232
232
|
export type IBetterAuth = IBetterAuthWithoutPasskey | IBetterAuthWithPasskey;
|
|
233
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Email verification configuration for Better-Auth
|
|
236
|
+
*
|
|
237
|
+
* Controls email verification behavior after sign-up.
|
|
238
|
+
* When enabled, users receive a verification email and must verify
|
|
239
|
+
* their email address before certain actions are allowed.
|
|
240
|
+
*
|
|
241
|
+
* **Enabled by Default:** Email verification is enabled by default.
|
|
242
|
+
* Set `emailVerification: false` or `emailVerification: { enabled: false }` to disable.
|
|
243
|
+
*
|
|
244
|
+
* Accepts:
|
|
245
|
+
* - `undefined`: Enabled with defaults (zero-config)
|
|
246
|
+
* - `true` or `{}`: Enable with defaults (same as undefined)
|
|
247
|
+
* - `{ locale: 'de', ... }`: Enable with custom settings
|
|
248
|
+
* - `false` or `{ enabled: false }`: Explicitly disable
|
|
249
|
+
*
|
|
250
|
+
* @since 11.13.0
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```typescript
|
|
254
|
+
* // Default: Email verification enabled
|
|
255
|
+
* betterAuth: {}
|
|
256
|
+
*
|
|
257
|
+
* // Custom configuration
|
|
258
|
+
* betterAuth: {
|
|
259
|
+
* emailVerification: {
|
|
260
|
+
* locale: 'de',
|
|
261
|
+
* autoSignInAfterVerification: true,
|
|
262
|
+
* expiresIn: 86400, // 24 hours in seconds
|
|
263
|
+
* }
|
|
264
|
+
* }
|
|
265
|
+
*
|
|
266
|
+
* // Disable email verification
|
|
267
|
+
* betterAuth: {
|
|
268
|
+
* emailVerification: false,
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
export interface IBetterAuthEmailVerificationConfig {
|
|
273
|
+
/**
|
|
274
|
+
* Whether to automatically sign in the user after email verification.
|
|
275
|
+
* @default true
|
|
276
|
+
*/
|
|
277
|
+
autoSignInAfterVerification?: boolean;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Brevo template ID for verification emails.
|
|
281
|
+
* When set and Brevo is configured (config.brevo), verification emails
|
|
282
|
+
* are sent via Brevo's transactional API instead of SMTP/EJS templates.
|
|
283
|
+
*
|
|
284
|
+
* Template variables passed to Brevo:
|
|
285
|
+
* - `name`: User display name
|
|
286
|
+
* - `link`: Verification URL
|
|
287
|
+
* - `appName`: Application name
|
|
288
|
+
* - `expiresIn`: Formatted expiration time
|
|
289
|
+
*
|
|
290
|
+
* @default undefined (uses SMTP/EJS templates)
|
|
291
|
+
*/
|
|
292
|
+
brevoTemplateId?: number;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Frontend callback URL for email verification.
|
|
296
|
+
*
|
|
297
|
+
* When set, the verification link in the email will point to this URL
|
|
298
|
+
* with the token as a query parameter (e.g., `{callbackURL}?token=xxx`).
|
|
299
|
+
* The frontend page should then call the backend verify-email endpoint
|
|
300
|
+
* to complete verification.
|
|
301
|
+
*
|
|
302
|
+
* Supports both absolute URLs and relative paths:
|
|
303
|
+
* - Absolute: `https://example.com/auth/verify-email`
|
|
304
|
+
* - Relative: `/auth/verify-email` (resolved against `appUrl`)
|
|
305
|
+
*
|
|
306
|
+
* When not set, the verification link points directly to the backend
|
|
307
|
+
* endpoint which handles verification and redirects.
|
|
308
|
+
*
|
|
309
|
+
* @default undefined (backend-handled verification)
|
|
310
|
+
* @since 11.13.0
|
|
311
|
+
*/
|
|
312
|
+
callbackURL?: string;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Whether email verification is enabled.
|
|
316
|
+
* @default true (enabled by default when BetterAuth is active)
|
|
317
|
+
*/
|
|
318
|
+
enabled?: boolean;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Time in seconds until the verification link expires.
|
|
322
|
+
* @default 86400 (24 hours)
|
|
323
|
+
*/
|
|
324
|
+
expiresIn?: number;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Locale for the verification email template.
|
|
328
|
+
* Used to select the correct language template.
|
|
329
|
+
* @default 'en'
|
|
330
|
+
*/
|
|
331
|
+
locale?: string;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Cooldown in seconds between resend requests for the same email address.
|
|
335
|
+
* Prevents abuse by limiting how often verification emails can be resent.
|
|
336
|
+
* Applied per email address in-memory.
|
|
337
|
+
*
|
|
338
|
+
* @default 60
|
|
339
|
+
* @since 11.13.0
|
|
340
|
+
*/
|
|
341
|
+
resendCooldownSeconds?: number;
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Custom template name for the verification email.
|
|
345
|
+
* The system looks for templates in this order:
|
|
346
|
+
* 1. `<template>-<locale>.ejs` in project templates
|
|
347
|
+
* 2. `<template>.ejs` in project templates
|
|
348
|
+
* 3. `<template>-<locale>.ejs` in nest-server templates (fallback)
|
|
349
|
+
* 4. `<template>.ejs` in nest-server templates (fallback)
|
|
350
|
+
*
|
|
351
|
+
* @default 'email-verification'
|
|
352
|
+
*/
|
|
353
|
+
template?: string;
|
|
354
|
+
}
|
|
355
|
+
|
|
234
356
|
/**
|
|
235
357
|
* JWT plugin configuration for Better-Auth
|
|
236
358
|
*
|
|
@@ -426,6 +548,59 @@ export interface IBetterAuthRateLimit {
|
|
|
426
548
|
windowSeconds?: number;
|
|
427
549
|
}
|
|
428
550
|
|
|
551
|
+
/**
|
|
552
|
+
* Sign-up checks configuration for Better-Auth
|
|
553
|
+
*
|
|
554
|
+
* Controls which fields are required during sign-up.
|
|
555
|
+
* This is useful for enforcing terms acceptance, age verification, etc.
|
|
556
|
+
*
|
|
557
|
+
* **Enabled by Default:** Sign-up checks are enabled by default with
|
|
558
|
+
* `requiredFields: ['termsAndPrivacyAccepted']`.
|
|
559
|
+
*
|
|
560
|
+
* Accepts:
|
|
561
|
+
* - `undefined`: Enabled with defaults (`termsAndPrivacyAccepted` required)
|
|
562
|
+
* - `true` or `{}`: Enable with defaults (same as undefined)
|
|
563
|
+
* - `{ requiredFields: [...] }`: Enable with custom required fields
|
|
564
|
+
* - `false` or `{ enabled: false }`: Disable sign-up checks entirely
|
|
565
|
+
*
|
|
566
|
+
* @since 11.13.0
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* // Default: termsAndPrivacyAccepted is required
|
|
571
|
+
* betterAuth: {}
|
|
572
|
+
*
|
|
573
|
+
* // Custom required fields
|
|
574
|
+
* betterAuth: {
|
|
575
|
+
* signUpChecks: {
|
|
576
|
+
* requiredFields: ['termsAndPrivacyAccepted', 'ageConfirmed'],
|
|
577
|
+
* }
|
|
578
|
+
* }
|
|
579
|
+
*
|
|
580
|
+
* // Disable sign-up checks (no fields required)
|
|
581
|
+
* betterAuth: {
|
|
582
|
+
* signUpChecks: false,
|
|
583
|
+
* }
|
|
584
|
+
* ```
|
|
585
|
+
*/
|
|
586
|
+
export interface IBetterAuthSignUpChecksConfig {
|
|
587
|
+
/**
|
|
588
|
+
* Whether sign-up checks are enabled.
|
|
589
|
+
* @default true (enabled by default when BetterAuth is active)
|
|
590
|
+
*/
|
|
591
|
+
enabled?: boolean;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Fields that must be provided and truthy during sign-up.
|
|
595
|
+
* If a required field is missing or falsy, sign-up will fail.
|
|
596
|
+
*
|
|
597
|
+
* @default ['termsAndPrivacyAccepted']
|
|
598
|
+
*
|
|
599
|
+
* @example ['termsAndPrivacyAccepted', 'ageConfirmed', 'newsletterOptIn']
|
|
600
|
+
*/
|
|
601
|
+
requiredFields?: string[];
|
|
602
|
+
}
|
|
603
|
+
|
|
429
604
|
/**
|
|
430
605
|
* Interface for better-auth social provider configuration
|
|
431
606
|
*
|
|
@@ -1498,6 +1673,39 @@ interface IBetterAuthBase {
|
|
|
1498
1673
|
enabled?: boolean;
|
|
1499
1674
|
};
|
|
1500
1675
|
|
|
1676
|
+
/**
|
|
1677
|
+
* Email verification configuration.
|
|
1678
|
+
*
|
|
1679
|
+
* **Enabled by Default:** Email verification is enabled by default.
|
|
1680
|
+
* Users receive a verification email after sign-up.
|
|
1681
|
+
*
|
|
1682
|
+
* Accepts:
|
|
1683
|
+
* - `undefined`: Enabled with defaults (zero-config)
|
|
1684
|
+
* - `true` or `{}`: Enable with defaults (same as undefined)
|
|
1685
|
+
* - `{ locale: 'de', ... }`: Enable with custom settings
|
|
1686
|
+
* - `false` or `{ enabled: false }`: Explicitly disable
|
|
1687
|
+
*
|
|
1688
|
+
* @default undefined (enabled by default)
|
|
1689
|
+
* @since 11.13.0
|
|
1690
|
+
*
|
|
1691
|
+
* @example
|
|
1692
|
+
* ```typescript
|
|
1693
|
+
* // Email verification enabled by default - no config needed
|
|
1694
|
+
*
|
|
1695
|
+
* // Custom configuration
|
|
1696
|
+
* betterAuth: {
|
|
1697
|
+
* emailVerification: {
|
|
1698
|
+
* locale: 'de',
|
|
1699
|
+
* autoSignInAfterVerification: true,
|
|
1700
|
+
* }
|
|
1701
|
+
* }
|
|
1702
|
+
*
|
|
1703
|
+
* // Disable email verification
|
|
1704
|
+
* betterAuth: { emailVerification: false }
|
|
1705
|
+
* ```
|
|
1706
|
+
*/
|
|
1707
|
+
emailVerification?: boolean | IBetterAuthEmailVerificationConfig;
|
|
1708
|
+
|
|
1501
1709
|
/**
|
|
1502
1710
|
* Whether better-auth is enabled.
|
|
1503
1711
|
*
|
|
@@ -1631,6 +1839,38 @@ interface IBetterAuthBase {
|
|
|
1631
1839
|
*/
|
|
1632
1840
|
secret?: string;
|
|
1633
1841
|
|
|
1842
|
+
/**
|
|
1843
|
+
* Sign-up checks configuration.
|
|
1844
|
+
*
|
|
1845
|
+
* **Enabled by Default:** Sign-up checks are enabled by default with
|
|
1846
|
+
* `requiredFields: ['termsAndPrivacyAccepted']`.
|
|
1847
|
+
*
|
|
1848
|
+
* Accepts:
|
|
1849
|
+
* - `undefined`: Enabled with defaults (termsAndPrivacyAccepted required)
|
|
1850
|
+
* - `true` or `{}`: Enable with defaults (same as undefined)
|
|
1851
|
+
* - `{ requiredFields: [...] }`: Enable with custom required fields
|
|
1852
|
+
* - `false` or `{ enabled: false }`: Disable sign-up checks entirely
|
|
1853
|
+
*
|
|
1854
|
+
* @default undefined (enabled by default)
|
|
1855
|
+
* @since 11.13.0
|
|
1856
|
+
*
|
|
1857
|
+
* @example
|
|
1858
|
+
* ```typescript
|
|
1859
|
+
* // Default: termsAndPrivacyAccepted is required during sign-up
|
|
1860
|
+
*
|
|
1861
|
+
* // Custom required fields
|
|
1862
|
+
* betterAuth: {
|
|
1863
|
+
* signUpChecks: {
|
|
1864
|
+
* requiredFields: ['termsAndPrivacyAccepted', 'ageConfirmed'],
|
|
1865
|
+
* }
|
|
1866
|
+
* }
|
|
1867
|
+
*
|
|
1868
|
+
* // Disable sign-up checks (no fields required)
|
|
1869
|
+
* betterAuth: { signUpChecks: false }
|
|
1870
|
+
* ```
|
|
1871
|
+
*/
|
|
1872
|
+
signUpChecks?: boolean | IBetterAuthSignUpChecksConfig;
|
|
1873
|
+
|
|
1634
1874
|
/**
|
|
1635
1875
|
* Social login providers configuration
|
|
1636
1876
|
* Supports all Better-Auth providers dynamically (google, github, apple, discord, etc.)
|
|
@@ -58,6 +58,8 @@ GraphQL schema is built from decorators at compile time. The parent class (`Core
|
|
|
58
58
|
|
|
59
59
|
**Note:** `@UseGuards(AuthGuard(JWT))` is NOT needed when using `@Roles(S_USER)` or `@Roles(ADMIN)` because `RolesGuard` already extends `AuthGuard(JWT)` internally.
|
|
60
60
|
|
|
61
|
+
**Sign-Up Validation (v11.13.0+):** The resolver includes `CoreBetterAuthSignUpValidatorService` injection with `@Optional()`. This enables the `termsAndPrivacyAccepted` parameter on the `betterAuthSignUp` mutation.
|
|
62
|
+
|
|
61
63
|
---
|
|
62
64
|
|
|
63
65
|
### 4. Update UserService (CRITICAL!)
|
|
@@ -178,6 +180,103 @@ const config = {
|
|
|
178
180
|
|
|
179
181
|
---
|
|
180
182
|
|
|
183
|
+
## Email Verification (v11.13.0+)
|
|
184
|
+
|
|
185
|
+
Email verification is **enabled by default** via Better-Auth's `emailVerification` plugin.
|
|
186
|
+
|
|
187
|
+
### Default Behavior
|
|
188
|
+
|
|
189
|
+
- Users receive a verification email after sign-up
|
|
190
|
+
- Email contains a verification link with token
|
|
191
|
+
- After verification, `verifiedAt` is automatically set on the user
|
|
192
|
+
- Templates are provided in German and English
|
|
193
|
+
|
|
194
|
+
### Configuration
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const config = {
|
|
198
|
+
betterAuth: {
|
|
199
|
+
// Email verification is enabled by default
|
|
200
|
+
// To customize:
|
|
201
|
+
emailVerification: {
|
|
202
|
+
expiresIn: 86400, // Token expiration in seconds (default: 24h)
|
|
203
|
+
template: 'custom-verify', // Custom template name
|
|
204
|
+
locale: 'en', // Template locale (default: 'de')
|
|
205
|
+
},
|
|
206
|
+
// To disable:
|
|
207
|
+
emailVerification: false,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Custom Email Templates
|
|
213
|
+
|
|
214
|
+
Create custom templates in your project's templates directory:
|
|
215
|
+
- `templates/email-verification-de.ejs` - German
|
|
216
|
+
- `templates/email-verification-en.ejs` - English
|
|
217
|
+
|
|
218
|
+
Available variables: `name`, `link`, `expiresIn`, `appName`
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Sign-Up Checks (v11.13.0+)
|
|
223
|
+
|
|
224
|
+
Sign-up validation is **enabled by default** requiring `termsAndPrivacyAccepted`.
|
|
225
|
+
|
|
226
|
+
### Default Behavior
|
|
227
|
+
|
|
228
|
+
- `termsAndPrivacyAccepted: true` is required for sign-up
|
|
229
|
+
- When accepted, `termsAndPrivacyAcceptedAt` is stored in the user record
|
|
230
|
+
- Sign-up fails with error `LTNS_0021` if not accepted
|
|
231
|
+
|
|
232
|
+
### GraphQL Usage
|
|
233
|
+
|
|
234
|
+
```graphql
|
|
235
|
+
mutation {
|
|
236
|
+
betterAuthSignUp(
|
|
237
|
+
email: "user@example.com"
|
|
238
|
+
password: "hashedPassword"
|
|
239
|
+
name: "User Name"
|
|
240
|
+
termsAndPrivacyAccepted: true # Required by default
|
|
241
|
+
) {
|
|
242
|
+
success
|
|
243
|
+
user { id email }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Configuration
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
const config = {
|
|
252
|
+
betterAuth: {
|
|
253
|
+
// Sign-up checks are enabled by default
|
|
254
|
+
// To customize required fields:
|
|
255
|
+
signUpChecks: {
|
|
256
|
+
requiredFields: ['termsAndPrivacyAccepted', 'ageConfirmed'],
|
|
257
|
+
},
|
|
258
|
+
// To disable all sign-up checks:
|
|
259
|
+
signUpChecks: false,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### REST API
|
|
265
|
+
|
|
266
|
+
For REST sign-up, include `termsAndPrivacyAccepted` in the request body:
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
POST /iam/sign-up/email
|
|
270
|
+
{
|
|
271
|
+
"email": "user@example.com",
|
|
272
|
+
"password": "hashedPassword",
|
|
273
|
+
"name": "User Name",
|
|
274
|
+
"termsAndPrivacyAccepted": true
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
181
280
|
## Verification Checklist
|
|
182
281
|
|
|
183
282
|
After integration, verify:
|
|
@@ -189,6 +288,16 @@ After integration, verify:
|
|
|
189
288
|
- [ ] Sign-up via BetterAuth creates user in database with `iamId`
|
|
190
289
|
- [ ] Sign-in via BetterAuth works correctly
|
|
191
290
|
|
|
291
|
+
### Additional checks for v11.13.0+ features:
|
|
292
|
+
- [ ] Sign-up without `termsAndPrivacyAccepted` returns error `LTNS_0021`
|
|
293
|
+
- [ ] Sign-up with `termsAndPrivacyAccepted: true` succeeds
|
|
294
|
+
- [ ] User record contains `termsAndPrivacyAcceptedAt` timestamp after sign-up
|
|
295
|
+
- [ ] Email verification link is sent after sign-up (check console in local mode)
|
|
296
|
+
- [ ] After clicking verification link, `verifiedAt` is set on user
|
|
297
|
+
- [ ] Passkey login returns user data in response (verify enrichment works)
|
|
298
|
+
- [ ] Passkey login redirects to dashboard after successful authentication
|
|
299
|
+
- [ ] Passkey can be registered, listed, and deleted from security settings
|
|
300
|
+
|
|
192
301
|
### Additional checks for Migration scenario:
|
|
193
302
|
- [ ] Sign-in via Legacy Auth works for BetterAuth-created users
|
|
194
303
|
- [ ] Sign-in via BetterAuth works for Legacy-created users
|
|
@@ -206,6 +315,8 @@ After integration, verify:
|
|
|
206
315
|
| Wrong `basePath` in config | 404 on BetterAuth endpoints | Ensure basePath matches controller (default: `/iam`) |
|
|
207
316
|
| Using wrong CoreModule signature | Build errors or missing features | New projects: 1-parameter, Existing: 3-parameter |
|
|
208
317
|
| AuthResolver override missing `checkLegacyGraphQLEnabled()` | Legacy endpoint disabling doesn't work (no HTTP 410) | Call `this.checkLegacyGraphQLEnabled('signIn')` in overrides |
|
|
318
|
+
| Missing `signUpValidator` in custom Resolver (v11.13.0+) | Sign-up validation not working | Add `@Optional() signUpValidator?: CoreBetterAuthSignUpValidatorService` to constructor and pass to `super()` |
|
|
319
|
+
| Missing `termsAndPrivacyAccepted` parameter in Resolver (v11.13.0+) | GraphQL error "Unknown argument" | Add `@Args('termsAndPrivacyAccepted', { nullable: true })` to `betterAuthSignUp` method |
|
|
209
320
|
|
|
210
321
|
---
|
|
211
322
|
|
|
@@ -361,6 +472,8 @@ Handle passkey authentication with session validation fallback.
|
|
|
361
472
|
|
|
362
473
|
**IMPORTANT:** For JWT mode (`cookies: false`), you MUST use the `authenticateWithPasskey()` function from the composable instead of `authClient.signIn.passkey()` directly. This is because JWT mode requires sending a `challengeId` to the server for challenge verification.
|
|
363
474
|
|
|
475
|
+
**Note on Passkey Login Response (v11.13.0+):** The server enriches the passkey verify-authentication response with user data. Better Auth's passkey plugin only returns `{ session }`, but the server fetches the user from the database and adds it to the response. The composable handles both scenarios (user in response vs. fallback to get-session).
|
|
476
|
+
|
|
364
477
|
```typescript
|
|
365
478
|
// login.vue - Passkey login (JWT-compatible)
|
|
366
479
|
// Use authenticateWithPasskey from useBetterAuth composable
|
|
@@ -48,6 +48,8 @@ const config = {
|
|
|
48
48
|
- **JWT Tokens** - For API clients and stateless authentication (**enabled by default**)
|
|
49
49
|
- **Two-Factor Authentication (2FA)** - TOTP-based second factor (**enabled by default**)
|
|
50
50
|
- **Passkey/WebAuthn** - Passwordless authentication (**enabled by default**, requires resolvable URLs)
|
|
51
|
+
- **Email Verification** - Verify user email addresses (**enabled by default** since v11.13.0)
|
|
52
|
+
- **Sign-Up Checks** - Validate sign-up requirements like `termsAndPrivacyAccepted` (**enabled by default** since v11.13.0)
|
|
51
53
|
|
|
52
54
|
### Core Features
|
|
53
55
|
|
|
@@ -497,6 +499,66 @@ export default {
|
|
|
497
499
|
|
|
498
500
|
## Advanced Configuration
|
|
499
501
|
|
|
502
|
+
### Email Verification (v11.13.0+)
|
|
503
|
+
|
|
504
|
+
Email verification is **enabled by default**. Users receive a verification email after sign-up and `verifiedAt` is automatically set when verified.
|
|
505
|
+
|
|
506
|
+
```typescript
|
|
507
|
+
const config = {
|
|
508
|
+
betterAuth: {
|
|
509
|
+
// Email verification is enabled by default
|
|
510
|
+
// To customize:
|
|
511
|
+
emailVerification: {
|
|
512
|
+
expiresIn: 86400, // Token expiration in seconds (default: 24h)
|
|
513
|
+
template: 'custom-verify', // Custom template name
|
|
514
|
+
locale: 'en', // Template locale (default: 'de')
|
|
515
|
+
brevoTemplateId: 42, // Send via Brevo transactional API (optional)
|
|
516
|
+
},
|
|
517
|
+
// To disable:
|
|
518
|
+
emailVerification: false,
|
|
519
|
+
},
|
|
520
|
+
};
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Custom Templates:** Create `templates/email-verification-{locale}.ejs` in your project. Available variables: `name`, `link`, `expiresIn`, `appName`.
|
|
524
|
+
|
|
525
|
+
**Brevo Integration:** When `brevoTemplateId` is set and Brevo is configured (`config.brevo`), verification emails are sent via Brevo's transactional API instead of SMTP/EJS templates. The same template variables (`name`, `link`, `appName`, `expiresIn`) are passed to the Brevo template.
|
|
526
|
+
|
|
527
|
+
### Sign-Up Checks (v11.13.0+)
|
|
528
|
+
|
|
529
|
+
Sign-up validation is **enabled by default** requiring `termsAndPrivacyAccepted: true`.
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
const config = {
|
|
533
|
+
betterAuth: {
|
|
534
|
+
// Sign-up checks are enabled by default
|
|
535
|
+
// To customize required fields:
|
|
536
|
+
signUpChecks: {
|
|
537
|
+
requiredFields: ['termsAndPrivacyAccepted', 'ageConfirmed'],
|
|
538
|
+
},
|
|
539
|
+
// To disable all sign-up checks:
|
|
540
|
+
signUpChecks: false,
|
|
541
|
+
},
|
|
542
|
+
};
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
When `termsAndPrivacyAccepted: true` is provided, `termsAndPrivacyAcceptedAt` is automatically stored in the user record.
|
|
546
|
+
|
|
547
|
+
**GraphQL Example:**
|
|
548
|
+
```graphql
|
|
549
|
+
mutation {
|
|
550
|
+
betterAuthSignUp(
|
|
551
|
+
email: "user@example.com"
|
|
552
|
+
password: "hashedPassword"
|
|
553
|
+
name: "User"
|
|
554
|
+
termsAndPrivacyAccepted: true # Required by default
|
|
555
|
+
) {
|
|
556
|
+
success
|
|
557
|
+
user { id email }
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
500
562
|
### Email/Password Authentication
|
|
501
563
|
|
|
502
564
|
Email/password authentication is enabled by default. You can disable it if you only want social login:
|
|
@@ -939,12 +1001,14 @@ In addition to REST endpoints, Better-Auth provides GraphQL queries and mutation
|
|
|
939
1001
|
|
|
940
1002
|
#### Authentication
|
|
941
1003
|
|
|
942
|
-
| Mutation | Arguments
|
|
943
|
-
| --------------------- |
|
|
944
|
-
| `betterAuthSignIn` | `email`, `password`
|
|
945
|
-
| `betterAuthSignUp` | `email`, `password`, `name?` | `BetterAuthAuthModel`| Register new account |
|
|
946
|
-
| `betterAuthSignOut` | -
|
|
947
|
-
| `betterAuthVerify2FA` | `code`
|
|
1004
|
+
| Mutation | Arguments | Return Type | Description |
|
|
1005
|
+
| --------------------- | -------------------------------------------- | -------------------- | ------------------------- |
|
|
1006
|
+
| `betterAuthSignIn` | `email`, `password` | `BetterAuthAuthModel`| Sign in with email/pass |
|
|
1007
|
+
| `betterAuthSignUp` | `email`, `password`, `name?`, `termsAndPrivacyAccepted?` | `BetterAuthAuthModel`| Register new account |
|
|
1008
|
+
| `betterAuthSignOut` | - | `Boolean` | Sign out (requires auth) |
|
|
1009
|
+
| `betterAuthVerify2FA` | `code` | `BetterAuthAuthModel`| Verify 2FA code |
|
|
1010
|
+
|
|
1011
|
+
**Note (v11.13.0+):** `termsAndPrivacyAccepted` is required by default. Set `signUpChecks: false` to disable.
|
|
948
1012
|
|
|
949
1013
|
#### 2FA Management (requires authentication)
|
|
950
1014
|
|
|
@@ -1054,12 +1118,13 @@ mutation {
|
|
|
1054
1118
|
}
|
|
1055
1119
|
}
|
|
1056
1120
|
|
|
1057
|
-
# Sign up
|
|
1121
|
+
# Sign up (v11.13.0+: termsAndPrivacyAccepted required by default)
|
|
1058
1122
|
mutation {
|
|
1059
1123
|
betterAuthSignUp(
|
|
1060
1124
|
email: "newuser@example.com"
|
|
1061
1125
|
password: "securePassword123"
|
|
1062
1126
|
name: "New User"
|
|
1127
|
+
termsAndPrivacyAccepted: true
|
|
1063
1128
|
) {
|
|
1064
1129
|
success
|
|
1065
1130
|
user {
|