@lenne.tech/nest-server 11.37.0 → 11.39.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/.claude/rules/configurable-features.md +51 -0
- package/.claude/rules/module-deprecation.md +25 -1
- package/.claude/rules/package-management.md +66 -0
- package/.claude/rules/testing.md +81 -5
- package/FRAMEWORK-API.md +4 -2
- package/dist/config.env.js +5 -3
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/config.helper.d.ts +2 -0
- package/dist/core/common/helpers/config.helper.js +18 -0
- package/dist/core/common/helpers/config.helper.js.map +1 -1
- package/dist/core/common/helpers/cookies.helper.d.ts +3 -0
- package/dist/core/common/helpers/cookies.helper.js +9 -0
- package/dist/core/common/helpers/cookies.helper.js.map +1 -1
- package/dist/core/common/helpers/input.helper.d.ts +1 -0
- package/dist/core/common/helpers/input.helper.js +4 -0
- package/dist/core/common/helpers/input.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.js +6 -1
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +1 -0
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +21 -0
- package/dist/core/common/middlewares/security-headers.middleware.d.ts +18 -0
- package/dist/core/common/middlewares/security-headers.middleware.js +90 -0
- package/dist/core/common/middlewares/security-headers.middleware.js.map +1 -0
- package/dist/core/common/services/email.service.d.ts +4 -1
- package/dist/core/common/services/email.service.js +25 -2
- package/dist/core/common/services/email.service.js.map +1 -1
- package/dist/core/common/services/module.service.js +1 -0
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.controller.js +2 -5
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.module.js +2 -0
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +2 -5
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/core-legacy-auth-deprecation.initializer.d.ts +12 -0
- package/dist/core/modules/auth/core-legacy-auth-deprecation.initializer.js +83 -0
- package/dist/core/modules/auth/core-legacy-auth-deprecation.initializer.js.map +1 -0
- package/dist/core/modules/auth/helpers/legacy-endpoints.helper.d.ts +3 -0
- package/dist/core/modules/auth/helpers/legacy-endpoints.helper.js +14 -0
- package/dist/core/modules/auth/helpers/legacy-endpoints.helper.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.config.d.ts +12 -0
- package/dist/core/modules/better-auth/better-auth.config.js +40 -1
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +9 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +53 -4
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.d.ts +5 -2
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +57 -4
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-error-codes.helper.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth-error-codes.helper.js +54 -0
- package/dist/core/modules/better-auth/core-better-auth-error-codes.helper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-password-reset.registry.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth-password-reset.registry.js +19 -0
- package/dist/core/modules/better-auth/core-better-auth-password-reset.registry.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +4 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +13 -10
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +8 -2
- package/dist/core/modules/better-auth/core-better-auth.module.js +34 -4
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/index.d.ts +1 -0
- package/dist/core/modules/better-auth/index.js +1 -0
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/error-code/error-codes.d.ts +27 -0
- package/dist/core/modules/error-code/error-codes.js +24 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -1
- package/dist/core/modules/hub/core-hub.service.js +1 -0
- package/dist/core/modules/hub/core-hub.service.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 -1
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +10 -1
- package/dist/core/modules/user/core-user.service.js +124 -15
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core/modules/user/inputs/core-user.input.js +1 -1
- package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
- package/dist/core.module.js +2 -0
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/error-code/error-codes.d.ts +3 -0
- package/dist/server/modules/user/user.controller.js +2 -1
- package/dist/server/modules/user/user.controller.js.map +1 -1
- package/dist/server/modules/user/user.model.d.ts +5 -0
- package/dist/server/modules/user/user.resolver.js +2 -1
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +1 -1
- package/dist/server/modules/user/user.service.js +18 -5
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/templates/password-reset-de.ejs +12 -0
- package/dist/templates/password-reset-en.ejs +12 -0
- package/dist/templates/password-reset.ejs +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/REQUEST-LIFECYCLE.md +49 -1
- package/migration-guides/11.37.x-to-11.38.x.md +528 -0
- package/migration-guides/11.38.x-to-11.39.x.md +456 -0
- package/package.json +1 -1
- package/src/config.env.ts +28 -4
- package/src/core/common/helpers/config.helper.ts +79 -0
- package/src/core/common/helpers/cookies.helper.ts +38 -0
- package/src/core/common/helpers/input.helper.ts +37 -0
- package/src/core/common/helpers/service.helper.ts +9 -1
- package/src/core/common/interceptors/check-security.interceptor.ts +1 -0
- package/src/core/common/interfaces/server-options.interface.ts +326 -10
- package/src/core/common/middlewares/security-headers.middleware.ts +155 -0
- package/src/core/common/services/email.service.ts +46 -1
- package/src/core/common/services/module.service.ts +1 -0
- package/src/core/modules/auth/README.md +104 -0
- package/src/core/modules/auth/core-auth.controller.ts +4 -11
- package/src/core/modules/auth/core-auth.module.ts +5 -0
- package/src/core/modules/auth/core-auth.resolver.ts +4 -11
- package/src/core/modules/auth/core-legacy-auth-deprecation.initializer.ts +128 -0
- package/src/core/modules/auth/helpers/legacy-endpoints.helper.ts +69 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +22 -0
- package/src/core/modules/better-auth/README.md +32 -59
- package/src/core/modules/better-auth/better-auth.config.ts +131 -4
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +126 -3
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +166 -7
- package/src/core/modules/better-auth/core-better-auth-error-codes.helper.ts +146 -0
- package/src/core/modules/better-auth/core-better-auth-password-reset.registry.ts +92 -0
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +42 -10
- package/src/core/modules/better-auth/core-better-auth.module.ts +67 -4
- package/src/core/modules/better-auth/index.ts +1 -0
- package/src/core/modules/error-code/error-codes.ts +55 -0
- package/src/core/modules/hub/core-hub.service.ts +1 -0
- package/src/core/modules/user/core-user.model.ts +28 -1
- package/src/core/modules/user/core-user.service.ts +389 -22
- package/src/core/modules/user/inputs/core-user.input.ts +16 -1
- package/src/core.module.ts +8 -0
- package/src/index.ts +3 -0
- package/src/server/modules/user/user.controller.ts +7 -1
- package/src/server/modules/user/user.resolver.ts +7 -1
- package/src/server/modules/user/user.service.ts +58 -13
- package/src/templates/password-reset-de.ejs +12 -0
- package/src/templates/password-reset-en.ejs +12 -0
- package/src/templates/password-reset.ejs +1 -0
|
@@ -74,22 +74,67 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* Request password reset mail
|
|
77
|
+
*
|
|
78
|
+
* REFERENCE IMPLEMENTATION — the two details below are the ones that matter, and a project
|
|
79
|
+
* copying this method needs both. Either one alone leaves the endpoint an account oracle.
|
|
80
|
+
*
|
|
81
|
+
* 1. An unknown address yields `null` (since 11.38.0, unless
|
|
82
|
+
* `auth.passwordReset.preventUserEnumeration` is off) and this method returns quietly, so the
|
|
83
|
+
* caller answers the same way it would for a known one.
|
|
84
|
+
* 2. The mail send is NOT awaited. This is the half that actually closes the channel: the send
|
|
85
|
+
* is a network round trip to SMTP or Brevo, orders of magnitude above everything else in the
|
|
86
|
+
* request. Awaiting it would make the known path visibly slower whatever the status code says
|
|
87
|
+
* — you would have given up the "unknown address" hint in the UI and kept the oracle.
|
|
88
|
+
*
|
|
89
|
+
* A failed send must still be reported rather than crash the process, which is why it carries
|
|
90
|
+
* its own `catch`. The user is told the mail is on its way either way; that is the same trade
|
|
91
|
+
* Better-Auth makes on the IAM path.
|
|
77
92
|
*/
|
|
78
|
-
async sendPasswordResetMail(email: string, serviceOptions?: ServiceOptions): Promise<User> {
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
async sendPasswordResetMail(email: string, serviceOptions?: ServiceOptions): Promise<null | User> {
|
|
94
|
+
// `createPasswordResetToken`, not `setPasswordResetTokenForEmail`: the latter returns the user
|
|
95
|
+
// through `process()`, where the security interceptor strips `passwordResetToken`. Reading the
|
|
96
|
+
// token off that object is what mailed the word `undefined` to a real recipient.
|
|
97
|
+
const created = await this.createPasswordResetToken(email, serviceOptions);
|
|
98
|
+
|
|
99
|
+
if (!created) {
|
|
100
|
+
// Unknown address, enumeration protection on. Answer exactly as for a known one.
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// `buildPasswordResetLink`, not string concatenation: `email.passwordResetLink` has no default,
|
|
105
|
+
// and this config file does not set one, so concatenating produced `undefined/<token>`.
|
|
106
|
+
const link = this.buildPasswordResetLink(created.token);
|
|
107
|
+
if (!link) {
|
|
108
|
+
// Sending a mail whose link cannot work is worse than sending none. The recipient has no
|
|
109
|
+
// second way in, and a dead link gives them nothing to act on — while no mail at least reads
|
|
110
|
+
// as "try again". The address is still answered exactly as a known one.
|
|
111
|
+
this.userServiceLogger.error(
|
|
112
|
+
'Password reset mail not sent: no reset link could be built. Set `email.passwordResetLink` or `appUrl`.',
|
|
113
|
+
);
|
|
114
|
+
return created.user;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Deliberately NOT awaited — see the note above.
|
|
118
|
+
void this.emailService
|
|
119
|
+
.sendMail(created.user.email, 'Password reset', {
|
|
120
|
+
htmlTemplate: 'password-reset',
|
|
121
|
+
templateData: {
|
|
122
|
+
link,
|
|
123
|
+
// The mail is the only place the recipient can learn there IS a deadline. Without it an
|
|
124
|
+
// expired link is indistinguishable from a broken one — the same experience this whole
|
|
125
|
+
// area was repaired for.
|
|
126
|
+
linkExpiresInMinutes: this.passwordResetTokenExpiryMinutes(),
|
|
127
|
+
name: created.user.username,
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
.catch((error: unknown) => {
|
|
131
|
+
this.userServiceLogger.error(
|
|
132
|
+
`Failed to send the password-reset mail: ${error instanceof Error ? error.message : String(error)}`,
|
|
133
|
+
);
|
|
134
|
+
});
|
|
90
135
|
|
|
91
136
|
// Return user
|
|
92
|
-
return user;
|
|
137
|
+
return created.user;
|
|
93
138
|
}
|
|
94
139
|
|
|
95
140
|
/**
|
|
@@ -50,6 +50,18 @@
|
|
|
50
50
|
Falls die Schaltfläche nicht funktioniert, kopiere diesen Link in deinen Browser:<br>
|
|
51
51
|
<a href="<%= link %>" style="color:#1d4ed8; word-break:break-all; overflow-wrap:break-word;"><%= link %></a>
|
|
52
52
|
</p>
|
|
53
|
+
<%
|
|
54
|
+
/* Optional, like `appName`: a caller that omits it must not turn a password-reset
|
|
55
|
+
mail into a 500. Rendered only for a real, positive value — a deployment that
|
|
56
|
+
switched the expiry off (`0`) has no deadline to announce. */
|
|
57
|
+
const expiryMinutes = (typeof linkExpiresInMinutes !== 'undefined' && Number(linkExpiresInMinutes) > 0)
|
|
58
|
+
? Number(linkExpiresInMinutes) : 0;
|
|
59
|
+
-%>
|
|
60
|
+
<% if (expiryMinutes) { %>
|
|
61
|
+
<p style="margin:16px 0 0 0; font-size:13px; line-height:20px; color:#737373;">
|
|
62
|
+
Der Link ist <%= expiryMinutes %> Minuten lang gültig. Danach kannst du einfach einen neuen anfordern.
|
|
63
|
+
</p>
|
|
64
|
+
<% } %>
|
|
53
65
|
</td>
|
|
54
66
|
</tr>
|
|
55
67
|
<tr>
|
|
@@ -50,6 +50,18 @@
|
|
|
50
50
|
If the button doesn't work, copy and paste this link into your browser:<br>
|
|
51
51
|
<a href="<%= link %>" style="color:#1d4ed8; word-break:break-all; overflow-wrap:break-word;"><%= link %></a>
|
|
52
52
|
</p>
|
|
53
|
+
<%
|
|
54
|
+
/* Optional, like `appName`: a caller that omits it must not turn a password-reset
|
|
55
|
+
mail into a 500. Rendered only for a real, positive value — a deployment that
|
|
56
|
+
switched the expiry off (`0`) has no deadline to announce. */
|
|
57
|
+
const expiryMinutes = (typeof linkExpiresInMinutes !== 'undefined' && Number(linkExpiresInMinutes) > 0)
|
|
58
|
+
? Number(linkExpiresInMinutes) : 0;
|
|
59
|
+
-%>
|
|
60
|
+
<% if (expiryMinutes) { %>
|
|
61
|
+
<p style="margin:16px 0 0 0; font-size:13px; line-height:20px; color:#737373;">
|
|
62
|
+
This link is valid for <%= expiryMinutes %> minutes. After that, just request a new one.
|
|
63
|
+
</p>
|
|
64
|
+
<% } %>
|
|
53
65
|
</td>
|
|
54
66
|
</tr>
|
|
55
67
|
<tr>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
<h1>Hello <%= name %>,</h1>
|
|
2
2
|
<p>you requested a link for setting a new password. Here it is.</p><br />
|
|
3
3
|
<a href="<%= link %>">Reset password</a>
|
|
4
|
+
<% if (typeof linkExpiresInMinutes !== 'undefined' && Number(linkExpiresInMinutes) > 0) { %><br /><p>This link is valid for <%= Number(linkExpiresInMinutes) %> minutes. After that, just request a new one.</p><% } %>
|