najm-auth 4.0.1 → 4.0.2
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/README.md +13 -6
- package/dist/index.d.ts +5 -1
- package/dist/index.js +17 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -138,8 +138,9 @@ auth({
|
|
|
138
138
|
publicRegistration?: boolean // Default: true; mounts POST /auth/register
|
|
139
139
|
bcryptRounds?: number // Default: 10 (valid: 4-31)
|
|
140
140
|
|
|
141
|
-
// Frontend
|
|
142
|
-
frontendUrl?: string // Password reset link base URL
|
|
141
|
+
// Frontend
|
|
142
|
+
frontendUrl?: string // Password reset link base URL
|
|
143
|
+
appName?: string // Security email brand (default: 'Your app')
|
|
143
144
|
|
|
144
145
|
// Login identifier normalization (see "Identity presets")
|
|
145
146
|
identity?: {
|
|
@@ -1130,10 +1131,16 @@ consumption. Once consumed, a token stays consumed even if the later user
|
|
|
1130
1131
|
mutation fails; restoring it would make the link replayable, so the user must
|
|
1131
1132
|
request a new one.
|
|
1132
1133
|
|
|
1133
|
-
Accepting an account invitation also marks the destination email verified and
|
|
1134
|
-
activates the account when its status is `pending`. An ordinary password reset
|
|
1135
|
-
changes neither verification nor lifecycle status, and an explicitly inactive
|
|
1136
|
-
invited account remains inactive.
|
|
1134
|
+
Accepting an account invitation also marks the destination email verified and
|
|
1135
|
+
activates the account when its status is `pending`. An ordinary password reset
|
|
1136
|
+
changes neither verification nor lifecycle status, and an explicitly inactive
|
|
1137
|
+
invited account remains inactive.
|
|
1138
|
+
|
|
1139
|
+
Set `appName` on `auth()` to brand the invitation subject and email card. The
|
|
1140
|
+
provisioned role is presented as the account type, so a sponsor invitation can
|
|
1141
|
+
say “Activate your sponsor account” without application-owned HTML. The shared
|
|
1142
|
+
template uses inline critical styles for Gmail and keeps the raw token URL out
|
|
1143
|
+
of visible fallback copy.
|
|
1137
1144
|
|
|
1138
1145
|
The built-in memory and Redis drivers implement the required atomic primitive.
|
|
1139
1146
|
A custom cache driver may omit `compareAndDelete()` for compatibility with
|
package/dist/index.d.ts
CHANGED
|
@@ -198,6 +198,8 @@ interface AuthConfig {
|
|
|
198
198
|
defaultRole: string | null;
|
|
199
199
|
/** Frontend URL for password reset links (default: 'http://localhost:3000') */
|
|
200
200
|
frontendUrl: string;
|
|
201
|
+
/** Product name used in security email subjects and templates. */
|
|
202
|
+
appName: string;
|
|
201
203
|
/** Registration mode: 'active' auto-activates, 'pending' requires admin approval (default: 'active') */
|
|
202
204
|
registrationMode: 'active' | 'pending';
|
|
203
205
|
/** Whether the unauthenticated POST /auth/register route is mounted. */
|
|
@@ -265,6 +267,8 @@ type AuthPluginConfig = {
|
|
|
265
267
|
defaultRole?: string | null;
|
|
266
268
|
/** Frontend URL for password reset links. Falls back to FRONTEND_URL env var, then 'http://localhost:3000' */
|
|
267
269
|
frontendUrl?: string;
|
|
270
|
+
/** Product name used in account invitation emails (default: 'Your app'). */
|
|
271
|
+
appName?: string;
|
|
268
272
|
/** Registration mode: 'active' auto-activates new users, 'pending' requires admin approval (default: 'active') */
|
|
269
273
|
registrationMode?: 'active' | 'pending';
|
|
270
274
|
/**
|
|
@@ -432,7 +436,7 @@ var auth = {
|
|
|
432
436
|
subject: "Reset your password"
|
|
433
437
|
},
|
|
434
438
|
accountInvite: {
|
|
435
|
-
subject: "
|
|
439
|
+
subject: "{{appName}}: activate your {{accountLabel}}"
|
|
436
440
|
}
|
|
437
441
|
}
|
|
438
442
|
};
|
package/dist/index.js
CHANGED
|
@@ -3488,9 +3488,16 @@ var AuthService = class AuthService2 {
|
|
|
3488
3488
|
});
|
|
3489
3489
|
const { token } = await this.tokenService.generateInviteToken(user.id);
|
|
3490
3490
|
const inviteLink = `${this.config.frontendUrl}/reset-password?token=${token}`;
|
|
3491
|
+
const accountType = body.role?.trim().toLowerCase();
|
|
3492
|
+
const accountLabel = accountType ? `${accountType} account` : "account";
|
|
3491
3493
|
let emailSent = false;
|
|
3492
3494
|
try {
|
|
3493
|
-
await this.emailService.sendHtml(body.email, this.t("emails.accountInvite.subject"
|
|
3495
|
+
await this.emailService.sendHtml(body.email, this.t("emails.accountInvite.subject", {
|
|
3496
|
+
accountLabel,
|
|
3497
|
+
appName: this.config.appName
|
|
3498
|
+
}), accountInviteTemplate({
|
|
3499
|
+
accountType,
|
|
3500
|
+
appName: this.config.appName,
|
|
3494
3501
|
inviteLink,
|
|
3495
3502
|
userName: user.name || body.email
|
|
3496
3503
|
}));
|
|
@@ -6346,7 +6353,7 @@ var en_default = {
|
|
|
6346
6353
|
subject: "Reset your password"
|
|
6347
6354
|
},
|
|
6348
6355
|
accountInvite: {
|
|
6349
|
-
subject: "
|
|
6356
|
+
subject: "{{appName}}: activate your {{accountLabel}}"
|
|
6350
6357
|
}
|
|
6351
6358
|
}
|
|
6352
6359
|
},
|
|
@@ -7478,6 +7485,13 @@ var validateCallbackUrl = /* @__PURE__ */ __name((value, name) => {
|
|
|
7478
7485
|
}
|
|
7479
7486
|
return callback.toString();
|
|
7480
7487
|
}, "validateCallbackUrl");
|
|
7488
|
+
var resolveAppName = /* @__PURE__ */ __name((value) => {
|
|
7489
|
+
const appName = value?.trim() || "Your app";
|
|
7490
|
+
if (appName.length > 80 || /[\u0000-\u001f\u007f]/.test(appName)) {
|
|
7491
|
+
throw new Error("auth.appName must be at most 80 characters without control characters");
|
|
7492
|
+
}
|
|
7493
|
+
return appName;
|
|
7494
|
+
}, "resolveAppName");
|
|
7481
7495
|
var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
|
|
7482
7496
|
const configuredGoogle = config?.oauth?.google;
|
|
7483
7497
|
if (!configuredGoogle)
|
|
@@ -7554,6 +7568,7 @@ var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7554
7568
|
blacklistPrefix: config?.blacklistPrefix ?? "auth:blacklist:",
|
|
7555
7569
|
defaultRole: config?.defaultRole ?? null,
|
|
7556
7570
|
frontendUrl: config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000",
|
|
7571
|
+
appName: resolveAppName(config?.appName),
|
|
7557
7572
|
registrationMode: config?.registrationMode ?? "active",
|
|
7558
7573
|
publicRegistration: config?.publicRegistration ?? true,
|
|
7559
7574
|
requireVerifiedEmail: config?.requireVerifiedEmail ?? false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "najm-auth",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Authentication and authorization library for najm framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"najm-guard": "^2.0.2",
|
|
98
98
|
"najm-i18n": "^2.1.2",
|
|
99
99
|
"najm-cache": "^2.2.0",
|
|
100
|
-
"najm-email": "^2.0.
|
|
100
|
+
"najm-email": "^2.0.4",
|
|
101
101
|
"najm-rate": "^2.1.1",
|
|
102
102
|
"najm-validation": "^2.0.2",
|
|
103
103
|
"jsonwebtoken": "^9.0.3",
|