@fonderie/auth 7.21.2 → 7.22.1
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/brain/outcomes.md +1 -1
- package/dist/index.cjs +360 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +360 -40
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/brain/outcomes.md
CHANGED
|
@@ -142,7 +142,7 @@ Raw SQL ships in `node_modules/@fonderie/auth/dist/migrations/sql/` — read it
|
|
|
142
142
|
|
|
143
143
|
| Method | Path | Middleware chain (auth / validation / handler) |
|
|
144
144
|
|---|---|---|
|
|
145
|
-
| GET | `/_admin/users` | `async (ctx) => { const params = new URL(ctx.request.url).searchParams; const
|
|
145
|
+
| GET | `/_admin/users` | `async (ctx) => { const params = new URL(ctx.request.url).searchParams; // Accounts are stored under normalizeEmail: a search for the address a // user typed ('Jane+work@x.com') finds the account ('jane@x.com'). const raw = params.get('email')?.trim(); const email = raw ? normalizeEmailSafe(raw) ?? raw.toLowerCase() : undefined; if (email) { const user = await users.findByEmail(email); return user ? setApiResponse(HTTP.OK, 'USER', 'User', toAdminUserDTO(user)) : NOT_FOUND(); } const rawLimit = Number(params.get('limit') ?? 50); const limit = Number.isFinite(rawLimit) ? Math.min(Math.max(Math.trunc(rawLimit), 1), 200) : 50; const cursorParam = params.get('cursor'); const cursor = cursorParam ? decodeLoginCursor(cursorParam) : null; if (cursorParam && !cursor) return setApiResponse(HTTP.UNPROCESSABLE, 'INVALID_PARAMETER', 'Invalid cursor'); const deleted = params.get('deleted') === '1' || params.get('deleted') === 'true'; const page = await users.list({ limit, ...(cursor ? { cursor } : {}), ...(deleted ? { deleted } : {}), }); return setApiResponse(HTTP.OK, 'USERS', 'Users', toAdminUserPageDTO(page)); }` |
|
|
146
146
|
| GET | `/_admin/users/:id` | `async (ctx) => { // Read-only view: a soft-deleted account resolves (deletedAt set), so // an operator arriving from billing sees what happened to it. const user = await users.findByIdIncludingDeleted(idOf(ctx)); return user ? setApiResponse(HTTP.OK, 'USER', 'User', toAdminUserDTO(user)) : NOT_FOUND(); }` |
|
|
147
147
|
| GET | `/_admin/users/:id/login-history` | `async (ctx) => { if (!(await users.findById(idOf(ctx)))) return NOT_FOUND(); const params = new URL(ctx.request.url).searchParams; const rawLimit = Number(params.get('limit') ?? 50); const limit = Number.isFinite(rawLimit) ? Math.min(Math.max(Math.trunc(rawLimit), 1), 200) : 50; const cursorParam = params.get('cursor'); const cursor = cursorParam ? decodeLoginCursor(cursorParam) : null; if (cursorParam && !cursor) return setApiResponse(HTTP.UNPROCESSABLE, 'INVALID_PARAMETER', 'Invalid cursor'); const page = await events.listByUser({ userId: idOf(ctx), limit, ...(cursor ? { cursor } : {}), }); return setApiResponse( HTTP.OK, 'LOGIN_HISTORY', 'Login history', toLoginHistoryPageDTO(page), ); }` |
|
|
148
148
|
| DELETE | `/_admin/users/:id/sessions` | `async (ctx) => { if (!(await users.findById(idOf(ctx)))) return NOT_FOUND(); await sessions.deleteByUser(idOf(ctx)); await background(bus?.emit(EVENT_KEYS.sessionRevoked, { userId: idOf(ctx), sids: null, reason: 'admin' } satisfies ISessionRevokedEvent)); return setApiResponse(HTTP.OK, 'SESSIONS_REVOKED', 'All sessions revoked'); }` |
|
package/dist/index.cjs
CHANGED
|
@@ -125,6 +125,41 @@ var import_middlewares = require("@fonderie/core/middlewares");
|
|
|
125
125
|
|
|
126
126
|
// src/services/rate-limit.ts
|
|
127
127
|
var import_rate_limit = require("@fonderie/rate-limit");
|
|
128
|
+
|
|
129
|
+
// src/services/email.ts
|
|
130
|
+
function normalizeEmail(email2) {
|
|
131
|
+
if (typeof email2 !== "string" || email2.length === 0) {
|
|
132
|
+
throw new Error("Invalid email");
|
|
133
|
+
}
|
|
134
|
+
const lower = email2.trim().toLowerCase();
|
|
135
|
+
if (lower.length === 0) {
|
|
136
|
+
throw new Error("Email cannot be empty");
|
|
137
|
+
}
|
|
138
|
+
const atIndex = lower.indexOf("@");
|
|
139
|
+
if (atIndex === -1 || lower.lastIndexOf("@") !== atIndex) {
|
|
140
|
+
throw new Error("Invalid email format");
|
|
141
|
+
}
|
|
142
|
+
const local = lower.substring(0, atIndex);
|
|
143
|
+
const domain = lower.substring(atIndex + 1);
|
|
144
|
+
if (!local || !domain) {
|
|
145
|
+
throw new Error("Invalid email format");
|
|
146
|
+
}
|
|
147
|
+
const plusIndex = local.indexOf("+");
|
|
148
|
+
const normalizedLocal = plusIndex === -1 ? local : local.substring(0, plusIndex);
|
|
149
|
+
if (!normalizedLocal) {
|
|
150
|
+
throw new Error("Invalid email format");
|
|
151
|
+
}
|
|
152
|
+
return `${normalizedLocal}@${domain}`;
|
|
153
|
+
}
|
|
154
|
+
function normalizeEmailSafe(email2) {
|
|
155
|
+
try {
|
|
156
|
+
return normalizeEmail(email2);
|
|
157
|
+
} catch {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/services/rate-limit.ts
|
|
128
163
|
var min = (n) => n * 60;
|
|
129
164
|
var DEFAULTS = {
|
|
130
165
|
// login: 10/15min per IP AND 5/15min per account (credential stuffing
|
|
@@ -177,7 +212,9 @@ function buildAuthAccountLimiter(route, store, config) {
|
|
|
177
212
|
return (0, import_rate_limit.rateLimit)({
|
|
178
213
|
store: r.store,
|
|
179
214
|
rule: r.account.rule,
|
|
180
|
-
|
|
215
|
+
// The account bucket is keyed the way accounts are stored, so a rotating
|
|
216
|
+
// '+tag' on the same address does not buy fresh attempts.
|
|
217
|
+
key: (0, import_rate_limit.byBodyField)(`auth:${route}`, r.account.field, r.account.field === "email" ? normalizeEmailSafe : void 0)
|
|
181
218
|
});
|
|
182
219
|
}
|
|
183
220
|
|
|
@@ -1633,39 +1670,6 @@ function checkCooldown(lastSentAt, cooldownMs) {
|
|
|
1633
1670
|
// src/controllers/auth.controller.ts
|
|
1634
1671
|
init_password();
|
|
1635
1672
|
|
|
1636
|
-
// src/services/email.ts
|
|
1637
|
-
function normalizeEmail(email2) {
|
|
1638
|
-
if (typeof email2 !== "string" || email2.length === 0) {
|
|
1639
|
-
throw new Error("Invalid email");
|
|
1640
|
-
}
|
|
1641
|
-
const lower = email2.trim().toLowerCase();
|
|
1642
|
-
if (lower.length === 0) {
|
|
1643
|
-
throw new Error("Email cannot be empty");
|
|
1644
|
-
}
|
|
1645
|
-
const atIndex = lower.indexOf("@");
|
|
1646
|
-
if (atIndex === -1 || lower.lastIndexOf("@") !== atIndex) {
|
|
1647
|
-
throw new Error("Invalid email format");
|
|
1648
|
-
}
|
|
1649
|
-
const local = lower.substring(0, atIndex);
|
|
1650
|
-
const domain = lower.substring(atIndex + 1);
|
|
1651
|
-
if (!local || !domain) {
|
|
1652
|
-
throw new Error("Invalid email format");
|
|
1653
|
-
}
|
|
1654
|
-
const plusIndex = local.indexOf("+");
|
|
1655
|
-
const normalizedLocal = plusIndex === -1 ? local : local.substring(0, plusIndex);
|
|
1656
|
-
if (!normalizedLocal) {
|
|
1657
|
-
throw new Error("Invalid email format");
|
|
1658
|
-
}
|
|
1659
|
-
return `${normalizedLocal}@${domain}`;
|
|
1660
|
-
}
|
|
1661
|
-
function normalizeEmailSafe(email2) {
|
|
1662
|
-
try {
|
|
1663
|
-
return normalizeEmail(email2);
|
|
1664
|
-
} catch {
|
|
1665
|
-
return null;
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
1673
|
// src/models/password-reset.model.ts
|
|
1670
1674
|
var import_node_crypto5 = require("crypto");
|
|
1671
1675
|
var hashSecret = (value) => (0, import_node_crypto5.createHash)("sha256").update(value).digest("hex");
|
|
@@ -3355,7 +3359,7 @@ function oauthController(store, config, bus) {
|
|
|
3355
3359
|
const meta = requestMeta(ctx);
|
|
3356
3360
|
await loginEvents.recordSafe({
|
|
3357
3361
|
userId: null,
|
|
3358
|
-
emailAttempted: claims.email ?? null,
|
|
3362
|
+
emailAttempted: claims.email ? normalizeEmailSafe(claims.email) ?? claims.email : null,
|
|
3359
3363
|
method: "oauth-apple",
|
|
3360
3364
|
outcome: "failed",
|
|
3361
3365
|
failureReason: "token_replayed",
|
|
@@ -3403,7 +3407,7 @@ function oauthController(store, config, bus) {
|
|
|
3403
3407
|
if (!await consumedTokens.consumeOnce(tokenHash, new Date(expMs))) {
|
|
3404
3408
|
await loginEvents.recordSafe({
|
|
3405
3409
|
userId: null,
|
|
3406
|
-
emailAttempted: claims.email ?? null,
|
|
3410
|
+
emailAttempted: claims.email ? normalizeEmailSafe(claims.email) ?? claims.email : null,
|
|
3407
3411
|
method: "oauth-google",
|
|
3408
3412
|
outcome: "failed",
|
|
3409
3413
|
failureReason: "token_replayed",
|
|
@@ -3761,7 +3765,8 @@ function adminRouteTable(store, bus) {
|
|
|
3761
3765
|
// see anything cannot discover who signed up this morning.
|
|
3762
3766
|
async (ctx) => {
|
|
3763
3767
|
const params = new URL(ctx.request.url).searchParams;
|
|
3764
|
-
const
|
|
3768
|
+
const raw = params.get("email")?.trim();
|
|
3769
|
+
const email2 = raw ? normalizeEmailSafe(raw) ?? raw.toLowerCase() : void 0;
|
|
3765
3770
|
if (email2) {
|
|
3766
3771
|
const user = await users.findByEmail(email2);
|
|
3767
3772
|
return user ? (0, import_core12.setApiResponse)(import_core12.HTTP.OK, "USER", "User", toAdminUserDTO(user)) : NOT_FOUND();
|
|
@@ -3865,7 +3870,7 @@ var AuthModule = class {
|
|
|
3865
3870
|
name = "@fonderie/auth";
|
|
3866
3871
|
// Baked in at build time by tsup.base, so the operator's Modules page can
|
|
3867
3872
|
// say what is actually deployed rather than 'not reported'.
|
|
3868
|
-
version = "7.
|
|
3873
|
+
version = "7.22.1";
|
|
3869
3874
|
// Users, sessions, login history, suspend — only through @fonderie/admin.
|
|
3870
3875
|
describeAdmin() {
|
|
3871
3876
|
return { routes: describeAuthAdminRoutes(this.store, this.bus) };
|
|
@@ -4216,6 +4221,314 @@ Si c'est bien vous, tout est en ordre. Sinon, contactez imm\xE9diatement le supp
|
|
|
4216
4221
|
}
|
|
4217
4222
|
};
|
|
4218
4223
|
|
|
4224
|
+
// src/templates.zh-Hans.ts
|
|
4225
|
+
var ZH_HANS_TEMPLATES = {
|
|
4226
|
+
[MESSAGE_KEYS.emailRegistration]: {
|
|
4227
|
+
subject: "\u786E\u8BA4\u60A8\u7684\u8D26\u6237",
|
|
4228
|
+
html: `<h1>\u6B22\u8FCE\u52A0\u5165</h1>
|
|
4229
|
+
<p>{{firstName}}\uFF0C\u60A8\u597D\uFF1A</p>
|
|
4230
|
+
<p>\u611F\u8C22\u60A8\u7684\u6CE8\u518C\u3002\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u786E\u8BA4\u60A8\u7684\u8D26\u6237\uFF1A</p>
|
|
4231
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4232
|
+
<p class="muted">\u6B64\u9A8C\u8BC1\u7801\u5C06\u5728 24 \u5C0F\u65F6\u540E\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u8D26\u6237\uFF0C\u8BF7\u5FFD\u7565\u6B64\u90AE\u4EF6\u3002</p>`,
|
|
4233
|
+
text: `\u6B22\u8FCE\u52A0\u5165
|
|
4234
|
+
|
|
4235
|
+
{{firstName}}\uFF0C\u60A8\u597D\uFF1A
|
|
4236
|
+
|
|
4237
|
+
\u611F\u8C22\u60A8\u7684\u6CE8\u518C\u3002\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u786E\u8BA4\u60A8\u7684\u8D26\u6237\uFF1A{{pin}}
|
|
4238
|
+
|
|
4239
|
+
\u6B64\u9A8C\u8BC1\u7801\u5C06\u5728 24 \u5C0F\u65F6\u540E\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u8D26\u6237\uFF0C\u8BF7\u5FFD\u7565\u6B64\u90AE\u4EF6\u3002`
|
|
4240
|
+
},
|
|
4241
|
+
[MESSAGE_KEYS.emailVerification]: {
|
|
4242
|
+
subject: "\u60A8\u7684\u9A8C\u8BC1\u7801",
|
|
4243
|
+
html: `<h1>\u9A8C\u8BC1\u60A8\u7684\u7535\u5B50\u90AE\u7BB1</h1>
|
|
4244
|
+
<p>{{firstName}}\uFF0C\u60A8\u597D\uFF1A</p>
|
|
4245
|
+
<p>\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u5B8C\u6210\u8D26\u6237\u8BBE\u7F6E\uFF1A</p>
|
|
4246
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4247
|
+
<p class="muted">\u6B64\u9A8C\u8BC1\u7801\u5C06\u5728 24 \u5C0F\u65F6\u540E\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u8D26\u6237\uFF0C\u8BF7\u5FFD\u7565\u6B64\u90AE\u4EF6\u3002</p>`,
|
|
4248
|
+
text: `\u9A8C\u8BC1\u60A8\u7684\u7535\u5B50\u90AE\u7BB1
|
|
4249
|
+
|
|
4250
|
+
{{firstName}}\uFF0C\u60A8\u597D\uFF1A
|
|
4251
|
+
|
|
4252
|
+
\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u5B8C\u6210\u8D26\u6237\u8BBE\u7F6E\uFF1A{{pin}}
|
|
4253
|
+
|
|
4254
|
+
\u6B64\u9A8C\u8BC1\u7801\u5C06\u5728 24 \u5C0F\u65F6\u540E\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u8D26\u6237\uFF0C\u8BF7\u5FFD\u7565\u6B64\u90AE\u4EF6\u3002`
|
|
4255
|
+
},
|
|
4256
|
+
[MESSAGE_KEYS.passwordReset]: {
|
|
4257
|
+
subject: "\u91CD\u7F6E\u60A8\u7684\u5BC6\u7801",
|
|
4258
|
+
html: `<h1>\u91CD\u7F6E\u60A8\u7684\u5BC6\u7801</h1>
|
|
4259
|
+
<p>\u6211\u4EEC\u6536\u5230\u4E86\u91CD\u7F6E\u60A8\u5BC6\u7801\u7684\u8BF7\u6C42\u3002\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u7EE7\u7EED\uFF1A</p>
|
|
4260
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4261
|
+
<p class="muted">\u6B64\u9A8C\u8BC1\u7801\u5F88\u5FEB\u5C31\u4F1A\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u7533\u8BF7\u91CD\u7F6E\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u60A8\u7684\u5BC6\u7801\u4FDD\u6301\u4E0D\u53D8\u3002</p>`,
|
|
4262
|
+
text: `\u91CD\u7F6E\u60A8\u7684\u5BC6\u7801
|
|
4263
|
+
|
|
4264
|
+
\u6211\u4EEC\u6536\u5230\u4E86\u91CD\u7F6E\u60A8\u5BC6\u7801\u7684\u8BF7\u6C42\u3002\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u9A8C\u8BC1\u7801\u7EE7\u7EED\uFF1A{{pin}}
|
|
4265
|
+
|
|
4266
|
+
\u6B64\u9A8C\u8BC1\u7801\u5F88\u5FEB\u5C31\u4F1A\u5931\u6548\u3002\u5982\u679C\u60A8\u6CA1\u6709\u7533\u8BF7\u91CD\u7F6E\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u60A8\u7684\u5BC6\u7801\u4FDD\u6301\u4E0D\u53D8\u3002`
|
|
4267
|
+
},
|
|
4268
|
+
[MESSAGE_KEYS.phoneOtp]: {
|
|
4269
|
+
text: "\u60A8\u7684\u9A8C\u8BC1\u7801\u662F {{otp}}\uFF0C10 \u5206\u949F\u5185\u6709\u6548\u3002"
|
|
4270
|
+
},
|
|
4271
|
+
[MESSAGE_KEYS.mfaEnabled]: {
|
|
4272
|
+
subject: "\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5F00\u542F",
|
|
4273
|
+
html: `<h1>\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5F00\u542F</h1>
|
|
4274
|
+
<p>\u60A8\u7684\u8D26\u6237\u521A\u521A\u5F00\u542F\u4E86\u53CC\u91CD\u9A8C\u8BC1\u3002\u4ECA\u540E\u767B\u5F55\u65F6\uFF0C\u60A8\u9700\u8981\u8F93\u5165\u8EAB\u4EFD\u9A8C\u8BC1\u5668\u5E94\u7528\u4E2D\u7684\u9A8C\u8BC1\u7801\u3002</p>
|
|
4275
|
+
<p class="muted">\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002</p>`,
|
|
4276
|
+
text: `\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5F00\u542F
|
|
4277
|
+
|
|
4278
|
+
\u60A8\u7684\u8D26\u6237\u521A\u521A\u5F00\u542F\u4E86\u53CC\u91CD\u9A8C\u8BC1\u3002\u4ECA\u540E\u767B\u5F55\u65F6\uFF0C\u60A8\u9700\u8981\u8F93\u5165\u8EAB\u4EFD\u9A8C\u8BC1\u5668\u5E94\u7528\u4E2D\u7684\u9A8C\u8BC1\u7801\u3002
|
|
4279
|
+
|
|
4280
|
+
\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002`
|
|
4281
|
+
},
|
|
4282
|
+
[MESSAGE_KEYS.mfaDisabled]: {
|
|
4283
|
+
subject: "\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5173\u95ED",
|
|
4284
|
+
html: `<h1>\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5173\u95ED</h1>
|
|
4285
|
+
<p>\u60A8\u7684\u8D26\u6237\u521A\u521A\u5173\u95ED\u4E86\u53CC\u91CD\u9A8C\u8BC1\u3002\u73B0\u5728\u60A8\u7684\u8D26\u6237\u4EC5\u7531\u5BC6\u7801\u4FDD\u62A4\u3002</p>
|
|
4286
|
+
<p class="muted">\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u5E76\u91CD\u65B0\u5F00\u542F\u53CC\u91CD\u9A8C\u8BC1\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002</p>`,
|
|
4287
|
+
text: `\u53CC\u91CD\u9A8C\u8BC1\u5DF2\u5173\u95ED
|
|
4288
|
+
|
|
4289
|
+
\u60A8\u7684\u8D26\u6237\u521A\u521A\u5173\u95ED\u4E86\u53CC\u91CD\u9A8C\u8BC1\u3002\u73B0\u5728\u60A8\u7684\u8D26\u6237\u4EC5\u7531\u5BC6\u7801\u4FDD\u62A4\u3002
|
|
4290
|
+
|
|
4291
|
+
\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u5E76\u91CD\u65B0\u5F00\u542F\u53CC\u91CD\u9A8C\u8BC1\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002`
|
|
4292
|
+
},
|
|
4293
|
+
[MESSAGE_KEYS.mfaBackupCodesRegenerated]: {
|
|
4294
|
+
subject: "\u60A8\u7684\u5907\u7528\u9A8C\u8BC1\u7801\u5DF2\u91CD\u65B0\u751F\u6210",
|
|
4295
|
+
html: `<h1>\u5DF2\u751F\u6210\u65B0\u7684\u5907\u7528\u9A8C\u8BC1\u7801</h1>
|
|
4296
|
+
<p>\u60A8\u7684\u8D26\u6237\u521A\u521A\u751F\u6210\u4E86\u4E00\u7EC4\u65B0\u7684\u53CC\u91CD\u9A8C\u8BC1\u5907\u7528\u7801\u3002\u4E4B\u524D\u7684\u5907\u7528\u7801\u5DF2\u5168\u90E8\u5931\u6548\u3002</p>
|
|
4297
|
+
<p class="muted">\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002</p>`,
|
|
4298
|
+
text: `\u5DF2\u751F\u6210\u65B0\u7684\u5907\u7528\u9A8C\u8BC1\u7801
|
|
4299
|
+
|
|
4300
|
+
\u60A8\u7684\u8D26\u6237\u521A\u521A\u751F\u6210\u4E86\u4E00\u7EC4\u65B0\u7684\u53CC\u91CD\u9A8C\u8BC1\u5907\u7528\u7801\u3002\u4E4B\u524D\u7684\u5907\u7528\u7801\u5DF2\u5168\u90E8\u5931\u6548\u3002
|
|
4301
|
+
|
|
4302
|
+
\u5982\u679C\u8FD9\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002`
|
|
4303
|
+
},
|
|
4304
|
+
[MESSAGE_KEYS.emailChanged]: {
|
|
4305
|
+
subject: "\u60A8\u7684\u7535\u5B50\u90AE\u7BB1\u5730\u5740\u5DF2\u66F4\u6539",
|
|
4306
|
+
html: `<h1>\u60A8\u7684\u7535\u5B50\u90AE\u7BB1\u5DF2\u66F4\u6539</h1>
|
|
4307
|
+
<p>\u60A8\u8D26\u6237\u7684\u7535\u5B50\u90AE\u7BB1\u5730\u5740\u521A\u521A\u66F4\u6539\u4E3A <strong>{{newEmail}}</strong>\u3002</p>
|
|
4308
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u66F4\u6539\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002</p>`,
|
|
4309
|
+
text: `\u60A8\u7684\u7535\u5B50\u90AE\u7BB1\u5DF2\u66F4\u6539
|
|
4310
|
+
|
|
4311
|
+
\u60A8\u8D26\u6237\u7684\u7535\u5B50\u90AE\u7BB1\u5730\u5740\u521A\u521A\u66F4\u6539\u4E3A {{newEmail}}\u3002
|
|
4312
|
+
|
|
4313
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u66F4\u6539\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002`
|
|
4314
|
+
},
|
|
4315
|
+
[MESSAGE_KEYS.phoneChanged]: {
|
|
4316
|
+
subject: "\u60A8\u7684\u624B\u673A\u53F7\u7801\u5DF2\u66F4\u6539",
|
|
4317
|
+
html: `<h1>\u60A8\u7684\u624B\u673A\u53F7\u7801\u5DF2\u66F4\u6539</h1>
|
|
4318
|
+
<p>\u60A8\u8D26\u6237\u7684\u624B\u673A\u53F7\u7801\u521A\u521A\u5B8C\u6210\u66F4\u65B0\u3002</p>
|
|
4319
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u66F4\u6539\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002</p>`,
|
|
4320
|
+
text: `\u60A8\u7684\u624B\u673A\u53F7\u7801\u5DF2\u66F4\u6539
|
|
4321
|
+
|
|
4322
|
+
\u60A8\u8D26\u6237\u7684\u624B\u673A\u53F7\u7801\u521A\u521A\u5B8C\u6210\u66F4\u65B0\u3002
|
|
4323
|
+
|
|
4324
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u66F4\u6539\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u7ECF\u80FD\u591F\u8BBF\u95EE\u60A8\u7684\u8D26\u6237\u3002`
|
|
4325
|
+
},
|
|
4326
|
+
[MESSAGE_KEYS.passwordRevoked]: {
|
|
4327
|
+
subject: "\u60A8\u8D26\u6237\u7684\u5BC6\u7801\u5DF2\u88AB\u79FB\u9664",
|
|
4328
|
+
html: `<h1>\u60A8\u7684\u5BC6\u7801\u5DF2\u88AB\u79FB\u9664</h1>
|
|
4329
|
+
<p>\u60A8\u521A\u521A\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5F55\u3002\u6B64\u8D26\u6237\u4E4B\u524D\u8BBE\u7F6E\u8FC7\u5BC6\u7801\uFF0C\u4F46\u8BE5\u7535\u5B50\u90AE\u7BB1\u5730\u5740\u4ECE\u672A\u7ECF\u8FC7\u786E\u8BA4\uFF0C\u56E0\u6B64\u6211\u4EEC\u65E0\u6CD5\u786E\u5B9A\u5BC6\u7801\u662F\u8C01\u8BBE\u7F6E\u7684\uFF0C\u5DF2\u5C06\u5176\u79FB\u9664\u3002</p>
|
|
4330
|
+
<p>\u4F7F\u7528 {{provider}} \u767B\u5F55\u4E0D\u53D7\u5F71\u54CD\u3002\u5982\u679C\u60A8\u8FD8\u60F3\u8BBE\u7F6E\u5BC6\u7801\uFF0C\u53EF\u4EE5\u5728\u8D26\u6237\u8BBE\u7F6E\u4E2D\u8FDB\u884C\u8BBE\u7F6E\u3002</p>
|
|
4331
|
+
<p class="muted">\u5982\u679C\u60A8\u4ECE\u672A\u5728\u6B64\u8BBE\u7F6E\u8FC7\u5BC6\u7801\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u66FE\u8BD5\u56FE\u7528\u60A8\u7684\u5730\u5740\u6CE8\u518C\u3002\u60A8\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u6B64\u8D26\u6237\u5C5E\u4E8E\u60A8\u3002</p>`,
|
|
4332
|
+
text: `\u60A8\u7684\u5BC6\u7801\u5DF2\u88AB\u79FB\u9664
|
|
4333
|
+
|
|
4334
|
+
\u60A8\u521A\u521A\u4F7F\u7528 {{provider}} \u767B\u5F55\u3002\u6B64\u8D26\u6237\u4E4B\u524D\u8BBE\u7F6E\u8FC7\u5BC6\u7801\uFF0C\u4F46\u8BE5\u7535\u5B50\u90AE\u7BB1\u5730\u5740\u4ECE\u672A\u7ECF\u8FC7\u786E\u8BA4\uFF0C
|
|
4335
|
+
\u56E0\u6B64\u6211\u4EEC\u65E0\u6CD5\u786E\u5B9A\u5BC6\u7801\u662F\u8C01\u8BBE\u7F6E\u7684\uFF0C\u5DF2\u5C06\u5176\u79FB\u9664\u3002
|
|
4336
|
+
|
|
4337
|
+
\u4F7F\u7528 {{provider}} \u767B\u5F55\u4E0D\u53D7\u5F71\u54CD\u3002\u5982\u679C\u60A8\u8FD8\u60F3\u8BBE\u7F6E\u5BC6\u7801\uFF0C\u53EF\u4EE5\u5728\u8D26\u6237\u8BBE\u7F6E\u4E2D\u8FDB\u884C\u8BBE\u7F6E\u3002
|
|
4338
|
+
|
|
4339
|
+
\u5982\u679C\u60A8\u4ECE\u672A\u5728\u6B64\u8BBE\u7F6E\u8FC7\u5BC6\u7801\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u66FE\u8BD5\u56FE\u7528\u60A8\u7684\u5730\u5740\u6CE8\u518C\u3002\u60A8\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u6B64\u8D26\u6237\u5C5E\u4E8E\u60A8\u3002`
|
|
4340
|
+
},
|
|
4341
|
+
[MESSAGE_KEYS.oauthRegistration]: {
|
|
4342
|
+
subject: "\u6B22\u8FCE\u4F7F\u7528 {{appName}}",
|
|
4343
|
+
html: `<h1>\u6B22\u8FCE\u4F7F\u7528 {{appName}}</h1>
|
|
4344
|
+
<p>\u60A8\u7684\u8D26\u6237\u5DF2\u901A\u8FC7 <strong>{{provider}}</strong> \u521B\u5EFA\u3002\u4ECA\u540E\u968F\u65F6\u53EF\u4EE5\u4F7F\u7528\u540C\u4E00\u4E2A {{provider}} \u8D26\u6237\u767B\u5F55\uFF0C\u65E0\u9700\u8BB0\u4F4F\u5BC6\u7801\u3002</p>
|
|
4345
|
+
<p class="muted">\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u6B64\u8D26\u6237\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D\u3002</p>`,
|
|
4346
|
+
text: `\u6B22\u8FCE
|
|
4347
|
+
|
|
4348
|
+
\u60A8\u7684\u8D26\u6237\u5DF2\u901A\u8FC7 {{provider}} \u521B\u5EFA\u3002\u4ECA\u540E\u968F\u65F6\u53EF\u4EE5\u4F7F\u7528\u540C\u4E00\u4E2A
|
|
4349
|
+
{{provider}} \u8D26\u6237\u767B\u5F55\uFF0C\u65E0\u9700\u8BB0\u4F4F\u5BC6\u7801\u3002
|
|
4350
|
+
|
|
4351
|
+
\u5982\u679C\u60A8\u6CA1\u6709\u521B\u5EFA\u6B64\u8D26\u6237\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D\u3002`
|
|
4352
|
+
},
|
|
4353
|
+
[MESSAGE_KEYS.oauthLinked]: {
|
|
4354
|
+
subject: "\u60A8\u7684\u8D26\u6237\u65B0\u589E\u4E86\u4E00\u79CD\u767B\u5F55\u65B9\u5F0F",
|
|
4355
|
+
html: `<h1>\u5DF2\u6DFB\u52A0 {{provider}} \u767B\u5F55</h1>
|
|
4356
|
+
<p>\u73B0\u5728\u4E5F\u53EF\u4EE5\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5F55\u60A8\u7684\u8D26\u6237\u3002</p>
|
|
4357
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u6DFB\u52A0\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u5E76\u66F4\u6539\u5BC6\u7801\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u767B\u5F55\u3002</p>`,
|
|
4358
|
+
text: `\u5DF2\u6DFB\u52A0 {{provider}} \u767B\u5F55
|
|
4359
|
+
|
|
4360
|
+
\u73B0\u5728\u4E5F\u53EF\u4EE5\u4F7F\u7528 {{provider}} \u767B\u5F55\u60A8\u7684\u8D26\u6237\u3002
|
|
4361
|
+
|
|
4362
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u6DFB\u52A0\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u5E76\u66F4\u6539\u5BC6\u7801\uFF0C
|
|
4363
|
+
\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u767B\u5F55\u3002`
|
|
4364
|
+
},
|
|
4365
|
+
[MESSAGE_KEYS.oauthUnlinked]: {
|
|
4366
|
+
subject: "\u60A8\u7684\u8D26\u6237\u79FB\u9664\u4E86\u4E00\u79CD\u767B\u5F55\u65B9\u5F0F",
|
|
4367
|
+
html: `<h1>\u5DF2\u79FB\u9664 {{provider}} \u767B\u5F55</h1>
|
|
4368
|
+
<p>\u5DF2\u65E0\u6CD5\u518D\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5F55\u3002\u60A8\u7684\u7535\u5B50\u90AE\u7BB1\u548C\u5BC6\u7801\u4ECD\u7136\u53EF\u7528\u3002</p>
|
|
4369
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u79FB\u9664\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u3002</p>`,
|
|
4370
|
+
text: `\u5DF2\u79FB\u9664 {{provider}} \u767B\u5F55
|
|
4371
|
+
|
|
4372
|
+
\u5DF2\u65E0\u6CD5\u518D\u4F7F\u7528 {{provider}} \u767B\u5F55\u3002\u60A8\u7684\u7535\u5B50\u90AE\u7BB1\u548C\u5BC6\u7801\u4ECD\u7136\u53EF\u7528\u3002
|
|
4373
|
+
|
|
4374
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u79FB\u9664\u7684\uFF0C\u65E0\u9700\u4EFB\u4F55\u64CD\u4F5C\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8BF7\u7ACB\u5373\u8054\u7CFB\u5BA2\u670D\u3002`
|
|
4375
|
+
}
|
|
4376
|
+
};
|
|
4377
|
+
|
|
4378
|
+
// src/templates.zh-Hant.ts
|
|
4379
|
+
var ZH_HANT_TEMPLATES = {
|
|
4380
|
+
[MESSAGE_KEYS.emailRegistration]: {
|
|
4381
|
+
subject: "\u78BA\u8A8D\u60A8\u7684\u5E33\u6236",
|
|
4382
|
+
html: `<h1>\u6B61\u8FCE\u52A0\u5165</h1>
|
|
4383
|
+
<p>{{firstName}}\uFF0C\u60A8\u597D\uFF1A</p>
|
|
4384
|
+
<p>\u611F\u8B1D\u60A8\u7684\u8A3B\u518A\u3002\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u78BA\u8A8D\u60A8\u7684\u5E33\u6236\uFF1A</p>
|
|
4385
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4386
|
+
<p class="muted">\u6B64\u9A57\u8B49\u78BC\u5C07\u65BC 24 \u5C0F\u6642\u5F8C\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u5E33\u6236\uFF0C\u8ACB\u7565\u904E\u9019\u5C01\u90F5\u4EF6\u3002</p>`,
|
|
4387
|
+
text: `\u6B61\u8FCE\u52A0\u5165
|
|
4388
|
+
|
|
4389
|
+
{{firstName}}\uFF0C\u60A8\u597D\uFF1A
|
|
4390
|
+
|
|
4391
|
+
\u611F\u8B1D\u60A8\u7684\u8A3B\u518A\u3002\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u78BA\u8A8D\u60A8\u7684\u5E33\u6236\uFF1A{{pin}}
|
|
4392
|
+
|
|
4393
|
+
\u6B64\u9A57\u8B49\u78BC\u5C07\u65BC 24 \u5C0F\u6642\u5F8C\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u5E33\u6236\uFF0C\u8ACB\u7565\u904E\u9019\u5C01\u90F5\u4EF6\u3002`
|
|
4394
|
+
},
|
|
4395
|
+
[MESSAGE_KEYS.emailVerification]: {
|
|
4396
|
+
subject: "\u60A8\u7684\u9A57\u8B49\u78BC",
|
|
4397
|
+
html: `<h1>\u9A57\u8B49\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6</h1>
|
|
4398
|
+
<p>{{firstName}}\uFF0C\u60A8\u597D\uFF1A</p>
|
|
4399
|
+
<p>\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u5B8C\u6210\u5E33\u6236\u8A2D\u5B9A\uFF1A</p>
|
|
4400
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4401
|
+
<p class="muted">\u6B64\u9A57\u8B49\u78BC\u5C07\u65BC 24 \u5C0F\u6642\u5F8C\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u5E33\u6236\uFF0C\u8ACB\u7565\u904E\u9019\u5C01\u90F5\u4EF6\u3002</p>`,
|
|
4402
|
+
text: `\u9A57\u8B49\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6
|
|
4403
|
+
|
|
4404
|
+
{{firstName}}\uFF0C\u60A8\u597D\uFF1A
|
|
4405
|
+
|
|
4406
|
+
\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u5B8C\u6210\u5E33\u6236\u8A2D\u5B9A\uFF1A{{pin}}
|
|
4407
|
+
|
|
4408
|
+
\u6B64\u9A57\u8B49\u78BC\u5C07\u65BC 24 \u5C0F\u6642\u5F8C\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u5E33\u6236\uFF0C\u8ACB\u7565\u904E\u9019\u5C01\u90F5\u4EF6\u3002`
|
|
4409
|
+
},
|
|
4410
|
+
[MESSAGE_KEYS.passwordReset]: {
|
|
4411
|
+
subject: "\u91CD\u8A2D\u60A8\u7684\u5BC6\u78BC",
|
|
4412
|
+
html: `<h1>\u91CD\u8A2D\u60A8\u7684\u5BC6\u78BC</h1>
|
|
4413
|
+
<p>\u6211\u5011\u6536\u5230\u91CD\u8A2D\u60A8\u5BC6\u78BC\u7684\u8981\u6C42\u3002\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u7E7C\u7E8C\uFF1A</p>
|
|
4414
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
4415
|
+
<p class="muted">\u6B64\u9A57\u8B49\u78BC\u5373\u5C07\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u63D0\u51FA\u91CD\u8A2D\u8981\u6C42\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\uFF0C\u60A8\u7684\u5BC6\u78BC\u7DAD\u6301\u4E0D\u8B8A\u3002</p>`,
|
|
4416
|
+
text: `\u91CD\u8A2D\u60A8\u7684\u5BC6\u78BC
|
|
4417
|
+
|
|
4418
|
+
\u6211\u5011\u6536\u5230\u91CD\u8A2D\u60A8\u5BC6\u78BC\u7684\u8981\u6C42\u3002\u8ACB\u4F7F\u7528\u4EE5\u4E0B\u9A57\u8B49\u78BC\u7E7C\u7E8C\uFF1A{{pin}}
|
|
4419
|
+
|
|
4420
|
+
\u6B64\u9A57\u8B49\u78BC\u5373\u5C07\u5931\u6548\u3002\u5982\u679C\u60A8\u6C92\u6709\u63D0\u51FA\u91CD\u8A2D\u8981\u6C42\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\uFF0C\u60A8\u7684\u5BC6\u78BC\u7DAD\u6301\u4E0D\u8B8A\u3002`
|
|
4421
|
+
},
|
|
4422
|
+
[MESSAGE_KEYS.phoneOtp]: {
|
|
4423
|
+
text: "\u60A8\u7684\u9A57\u8B49\u78BC\u662F {{otp}}\uFF0C10 \u5206\u9418\u5167\u6709\u6548\u3002"
|
|
4424
|
+
},
|
|
4425
|
+
[MESSAGE_KEYS.mfaEnabled]: {
|
|
4426
|
+
subject: "\u96D9\u91CD\u9A57\u8B49\u5DF2\u555F\u7528",
|
|
4427
|
+
html: `<h1>\u96D9\u91CD\u9A57\u8B49\u5DF2\u555F\u7528</h1>
|
|
4428
|
+
<p>\u60A8\u7684\u5E33\u6236\u525B\u525B\u555F\u7528\u4E86\u96D9\u91CD\u9A57\u8B49\u3002\u5F80\u5F8C\u767B\u5165\u6642\uFF0C\u60A8\u9700\u8981\u8F38\u5165\u9A57\u8B49\u5668\u61C9\u7528\u7A0B\u5F0F\u4E2D\u7684\u9A57\u8B49\u78BC\u3002</p>
|
|
4429
|
+
<p class="muted">\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002</p>`,
|
|
4430
|
+
text: `\u96D9\u91CD\u9A57\u8B49\u5DF2\u555F\u7528
|
|
4431
|
+
|
|
4432
|
+
\u60A8\u7684\u5E33\u6236\u525B\u525B\u555F\u7528\u4E86\u96D9\u91CD\u9A57\u8B49\u3002\u5F80\u5F8C\u767B\u5165\u6642\uFF0C\u60A8\u9700\u8981\u8F38\u5165\u9A57\u8B49\u5668\u61C9\u7528\u7A0B\u5F0F\u4E2D\u7684\u9A57\u8B49\u78BC\u3002
|
|
4433
|
+
|
|
4434
|
+
\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002`
|
|
4435
|
+
},
|
|
4436
|
+
[MESSAGE_KEYS.mfaDisabled]: {
|
|
4437
|
+
subject: "\u96D9\u91CD\u9A57\u8B49\u5DF2\u505C\u7528",
|
|
4438
|
+
html: `<h1>\u96D9\u91CD\u9A57\u8B49\u5DF2\u505C\u7528</h1>
|
|
4439
|
+
<p>\u60A8\u7684\u5E33\u6236\u525B\u525B\u505C\u7528\u4E86\u96D9\u91CD\u9A57\u8B49\u3002\u73FE\u5728\u60A8\u7684\u5E33\u6236\u50C5\u53D7\u5BC6\u78BC\u4FDD\u8B77\u3002</p>
|
|
4440
|
+
<p class="muted">\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u4E26\u91CD\u65B0\u555F\u7528\u96D9\u91CD\u9A57\u8B49\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002</p>`,
|
|
4441
|
+
text: `\u96D9\u91CD\u9A57\u8B49\u5DF2\u505C\u7528
|
|
4442
|
+
|
|
4443
|
+
\u60A8\u7684\u5E33\u6236\u525B\u525B\u505C\u7528\u4E86\u96D9\u91CD\u9A57\u8B49\u3002\u73FE\u5728\u60A8\u7684\u5E33\u6236\u50C5\u53D7\u5BC6\u78BC\u4FDD\u8B77\u3002
|
|
4444
|
+
|
|
4445
|
+
\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u4E26\u91CD\u65B0\u555F\u7528\u96D9\u91CD\u9A57\u8B49\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002`
|
|
4446
|
+
},
|
|
4447
|
+
[MESSAGE_KEYS.mfaBackupCodesRegenerated]: {
|
|
4448
|
+
subject: "\u60A8\u7684\u5099\u7528\u9A57\u8B49\u78BC\u5DF2\u91CD\u65B0\u7522\u751F",
|
|
4449
|
+
html: `<h1>\u5DF2\u7522\u751F\u65B0\u7684\u5099\u7528\u9A57\u8B49\u78BC</h1>
|
|
4450
|
+
<p>\u60A8\u7684\u5E33\u6236\u525B\u525B\u7522\u751F\u4E86\u4E00\u7D44\u65B0\u7684\u96D9\u91CD\u9A57\u8B49\u5099\u7528\u78BC\u3002\u5148\u524D\u7684\u5099\u7528\u78BC\u5DF2\u5168\u90E8\u5931\u6548\u3002</p>
|
|
4451
|
+
<p class="muted">\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002</p>`,
|
|
4452
|
+
text: `\u5DF2\u7522\u751F\u65B0\u7684\u5099\u7528\u9A57\u8B49\u78BC
|
|
4453
|
+
|
|
4454
|
+
\u60A8\u7684\u5E33\u6236\u525B\u525B\u7522\u751F\u4E86\u4E00\u7D44\u65B0\u7684\u96D9\u91CD\u9A57\u8B49\u5099\u7528\u78BC\u3002\u5148\u524D\u7684\u5099\u7528\u78BC\u5DF2\u5168\u90E8\u5931\u6548\u3002
|
|
4455
|
+
|
|
4456
|
+
\u5982\u679C\u9019\u4E0D\u662F\u60A8\u672C\u4EBA\u7684\u64CD\u4F5C\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002`
|
|
4457
|
+
},
|
|
4458
|
+
[MESSAGE_KEYS.emailChanged]: {
|
|
4459
|
+
subject: "\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6\u5730\u5740\u5DF2\u8B8A\u66F4",
|
|
4460
|
+
html: `<h1>\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6\u5DF2\u8B8A\u66F4</h1>
|
|
4461
|
+
<p>\u60A8\u5E33\u6236\u7684\u96FB\u5B50\u90F5\u4EF6\u5730\u5740\u525B\u525B\u8B8A\u66F4\u70BA <strong>{{newEmail}}</strong>\u3002</p>
|
|
4462
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u8B8A\u66F4\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002</p>`,
|
|
4463
|
+
text: `\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6\u5DF2\u8B8A\u66F4
|
|
4464
|
+
|
|
4465
|
+
\u60A8\u5E33\u6236\u7684\u96FB\u5B50\u90F5\u4EF6\u5730\u5740\u525B\u525B\u8B8A\u66F4\u70BA {{newEmail}}\u3002
|
|
4466
|
+
|
|
4467
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u8B8A\u66F4\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002`
|
|
4468
|
+
},
|
|
4469
|
+
[MESSAGE_KEYS.phoneChanged]: {
|
|
4470
|
+
subject: "\u60A8\u7684\u96FB\u8A71\u865F\u78BC\u5DF2\u8B8A\u66F4",
|
|
4471
|
+
html: `<h1>\u60A8\u7684\u96FB\u8A71\u865F\u78BC\u5DF2\u8B8A\u66F4</h1>
|
|
4472
|
+
<p>\u60A8\u5E33\u6236\u7684\u96FB\u8A71\u865F\u78BC\u525B\u525B\u5B8C\u6210\u66F4\u65B0\u3002</p>
|
|
4473
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u8B8A\u66F4\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002</p>`,
|
|
4474
|
+
text: `\u60A8\u7684\u96FB\u8A71\u865F\u78BC\u5DF2\u8B8A\u66F4
|
|
4475
|
+
|
|
4476
|
+
\u60A8\u5E33\u6236\u7684\u96FB\u8A71\u865F\u78BC\u525B\u525B\u5B8C\u6210\u66F4\u65B0\u3002
|
|
4477
|
+
|
|
4478
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u8B8A\u66F4\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\uFF0C\u53EF\u80FD\u6709\u4EBA\u5DF2\u80FD\u5B58\u53D6\u60A8\u7684\u5E33\u6236\u3002`
|
|
4479
|
+
},
|
|
4480
|
+
[MESSAGE_KEYS.passwordRevoked]: {
|
|
4481
|
+
subject: "\u60A8\u5E33\u6236\u7684\u5BC6\u78BC\u5DF2\u88AB\u79FB\u9664",
|
|
4482
|
+
html: `<h1>\u60A8\u7684\u5BC6\u78BC\u5DF2\u88AB\u79FB\u9664</h1>
|
|
4483
|
+
<p>\u60A8\u525B\u525B\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5165\u3002\u6B64\u5E33\u6236\u5148\u524D\u8A2D\u5B9A\u904E\u5BC6\u78BC\uFF0C\u4F46\u9019\u500B\u96FB\u5B50\u90F5\u4EF6\u5730\u5740\u5F9E\u672A\u7D93\u904E\u78BA\u8A8D\uFF0C\u56E0\u6B64\u6211\u5011\u7121\u6CD5\u5224\u65B7\u5BC6\u78BC\u662F\u8AB0\u8A2D\u5B9A\u7684\uFF0C\u5DF2\u5C07\u5176\u79FB\u9664\u3002</p>
|
|
4484
|
+
<p>\u4F7F\u7528 {{provider}} \u767B\u5165\u4E0D\u53D7\u5F71\u97FF\u3002\u5982\u679C\u60A8\u4E5F\u60F3\u8A2D\u5B9A\u5BC6\u78BC\uFF0C\u53EF\u4EE5\u5728\u5E33\u6236\u8A2D\u5B9A\u4E2D\u9032\u884C\u8A2D\u5B9A\u3002</p>
|
|
4485
|
+
<p class="muted">\u5982\u679C\u60A8\u5F9E\u672A\u5728\u6B64\u8A2D\u5B9A\u904E\u5BC6\u78BC\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u66FE\u8A66\u5716\u7528\u60A8\u7684\u5730\u5740\u8A3B\u518A\u3002\u60A8\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\uFF0C\u6B64\u5E33\u6236\u5C6C\u65BC\u60A8\u3002</p>`,
|
|
4486
|
+
text: `\u60A8\u7684\u5BC6\u78BC\u5DF2\u88AB\u79FB\u9664
|
|
4487
|
+
|
|
4488
|
+
\u60A8\u525B\u525B\u4F7F\u7528 {{provider}} \u767B\u5165\u3002\u6B64\u5E33\u6236\u5148\u524D\u8A2D\u5B9A\u904E\u5BC6\u78BC\uFF0C\u4F46\u9019\u500B\u96FB\u5B50\u90F5\u4EF6\u5730\u5740\u5F9E\u672A\u7D93\u904E\u78BA\u8A8D\uFF0C
|
|
4489
|
+
\u56E0\u6B64\u6211\u5011\u7121\u6CD5\u5224\u65B7\u5BC6\u78BC\u662F\u8AB0\u8A2D\u5B9A\u7684\uFF0C\u5DF2\u5C07\u5176\u79FB\u9664\u3002
|
|
4490
|
+
|
|
4491
|
+
\u4F7F\u7528 {{provider}} \u767B\u5165\u4E0D\u53D7\u5F71\u97FF\u3002\u5982\u679C\u60A8\u4E5F\u60F3\u8A2D\u5B9A\u5BC6\u78BC\uFF0C\u53EF\u4EE5\u5728\u5E33\u6236\u8A2D\u5B9A\u4E2D\u9032\u884C\u8A2D\u5B9A\u3002
|
|
4492
|
+
|
|
4493
|
+
\u5982\u679C\u60A8\u5F9E\u672A\u5728\u6B64\u8A2D\u5B9A\u904E\u5BC6\u78BC\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u66FE\u8A66\u5716\u7528\u60A8\u7684\u5730\u5740\u8A3B\u518A\u3002\u60A8\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\uFF0C\u6B64\u5E33\u6236\u5C6C\u65BC\u60A8\u3002`
|
|
4494
|
+
},
|
|
4495
|
+
[MESSAGE_KEYS.oauthRegistration]: {
|
|
4496
|
+
subject: "\u6B61\u8FCE\u4F7F\u7528 {{appName}}",
|
|
4497
|
+
html: `<h1>\u6B61\u8FCE\u4F7F\u7528 {{appName}}</h1>
|
|
4498
|
+
<p>\u60A8\u7684\u5E33\u6236\u5DF2\u900F\u904E <strong>{{provider}}</strong> \u5EFA\u7ACB\u3002\u5F80\u5F8C\u96A8\u6642\u90FD\u80FD\u4F7F\u7528\u540C\u4E00\u500B {{provider}} \u5E33\u6236\u767B\u5165\uFF0C\u4E0D\u5FC5\u8A18\u4F4F\u5BC6\u78BC\u3002</p>
|
|
4499
|
+
<p class="muted">\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u6B64\u5E33\u6236\uFF0C\u8ACB\u806F\u7D61\u5BA2\u670D\u3002</p>`,
|
|
4500
|
+
text: `\u6B61\u8FCE
|
|
4501
|
+
|
|
4502
|
+
\u60A8\u7684\u5E33\u6236\u5DF2\u900F\u904E {{provider}} \u5EFA\u7ACB\u3002\u5F80\u5F8C\u96A8\u6642\u90FD\u80FD\u4F7F\u7528\u540C\u4E00\u500B
|
|
4503
|
+
{{provider}} \u5E33\u6236\u767B\u5165\uFF0C\u4E0D\u5FC5\u8A18\u4F4F\u5BC6\u78BC\u3002
|
|
4504
|
+
|
|
4505
|
+
\u5982\u679C\u60A8\u6C92\u6709\u5EFA\u7ACB\u6B64\u5E33\u6236\uFF0C\u8ACB\u806F\u7D61\u5BA2\u670D\u3002`
|
|
4506
|
+
},
|
|
4507
|
+
[MESSAGE_KEYS.oauthLinked]: {
|
|
4508
|
+
subject: "\u60A8\u7684\u5E33\u6236\u65B0\u589E\u4E86\u4E00\u7A2E\u767B\u5165\u65B9\u5F0F",
|
|
4509
|
+
html: `<h1>\u5DF2\u65B0\u589E {{provider}} \u767B\u5165</h1>
|
|
4510
|
+
<p>\u73FE\u5728\u4E5F\u53EF\u4EE5\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5165\u60A8\u7684\u5E33\u6236\u3002</p>
|
|
4511
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u65B0\u589E\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u4E26\u8B8A\u66F4\u5BC6\u78BC\uFF0C\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u80FD\u4EE5\u60A8\u7684\u8EAB\u5206\u767B\u5165\u3002</p>`,
|
|
4512
|
+
text: `\u5DF2\u65B0\u589E {{provider}} \u767B\u5165
|
|
4513
|
+
|
|
4514
|
+
\u73FE\u5728\u4E5F\u53EF\u4EE5\u4F7F\u7528 {{provider}} \u767B\u5165\u60A8\u7684\u5E33\u6236\u3002
|
|
4515
|
+
|
|
4516
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u65B0\u589E\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u4E26\u8B8A\u66F4\u5BC6\u78BC\uFF0C
|
|
4517
|
+
\u53EF\u80FD\u6709\u5176\u4ED6\u4EBA\u80FD\u4EE5\u60A8\u7684\u8EAB\u5206\u767B\u5165\u3002`
|
|
4518
|
+
},
|
|
4519
|
+
[MESSAGE_KEYS.oauthUnlinked]: {
|
|
4520
|
+
subject: "\u60A8\u7684\u5E33\u6236\u79FB\u9664\u4E86\u4E00\u7A2E\u767B\u5165\u65B9\u5F0F",
|
|
4521
|
+
html: `<h1>\u5DF2\u79FB\u9664 {{provider}} \u767B\u5165</h1>
|
|
4522
|
+
<p>\u5DF2\u7121\u6CD5\u518D\u4F7F\u7528 <strong>{{provider}}</strong> \u767B\u5165\u3002\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6\u548C\u5BC6\u78BC\u4ECD\u53EF\u4F7F\u7528\u3002</p>
|
|
4523
|
+
<p class="muted">\u5982\u679C\u662F\u60A8\u672C\u4EBA\u79FB\u9664\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u3002</p>`,
|
|
4524
|
+
text: `\u5DF2\u79FB\u9664 {{provider}} \u767B\u5165
|
|
4525
|
+
|
|
4526
|
+
\u5DF2\u7121\u6CD5\u518D\u4F7F\u7528 {{provider}} \u767B\u5165\u3002\u60A8\u7684\u96FB\u5B50\u90F5\u4EF6\u548C\u5BC6\u78BC\u4ECD\u53EF\u4F7F\u7528\u3002
|
|
4527
|
+
|
|
4528
|
+
\u5982\u679C\u662F\u60A8\u672C\u4EBA\u79FB\u9664\u7684\uFF0C\u7121\u9808\u63A1\u53D6\u4EFB\u4F55\u884C\u52D5\u3002\u5982\u679C\u4E0D\u662F\uFF0C\u8ACB\u7ACB\u5373\u806F\u7D61\u5BA2\u670D\u3002`
|
|
4529
|
+
}
|
|
4530
|
+
};
|
|
4531
|
+
|
|
4219
4532
|
// src/templates.ts
|
|
4220
4533
|
var EN_TEMPLATES = {
|
|
4221
4534
|
[MESSAGE_KEYS.emailRegistration]: {
|
|
@@ -4373,7 +4686,12 @@ change your password \u2014 someone else may be able to sign in as you.`
|
|
|
4373
4686
|
If you did this, you're all set. If not, contact support right away.`
|
|
4374
4687
|
}
|
|
4375
4688
|
};
|
|
4376
|
-
var DEFAULT_TEMPLATES = (0, import_core14.withTranslations)(EN_TEMPLATES, {
|
|
4689
|
+
var DEFAULT_TEMPLATES = (0, import_core14.withTranslations)(EN_TEMPLATES, {
|
|
4690
|
+
fr: FR_TEMPLATES,
|
|
4691
|
+
es: ES_TEMPLATES,
|
|
4692
|
+
"zh-Hans": ZH_HANS_TEMPLATES,
|
|
4693
|
+
"zh-Hant": ZH_HANT_TEMPLATES
|
|
4694
|
+
});
|
|
4377
4695
|
var SAMPLE_PAYLOADS = {
|
|
4378
4696
|
[MESSAGE_KEYS.passwordRevoked]: { provider: "Google" },
|
|
4379
4697
|
[MESSAGE_KEYS.oauthRegistration]: { provider: "Google", appName: "Fonderie" },
|
|
@@ -4408,7 +4726,9 @@ async function importUser(store, user) {
|
|
|
4408
4726
|
placeholders.push(`$${vals.length}`);
|
|
4409
4727
|
};
|
|
4410
4728
|
if (user.id !== void 0) add("id", user.id);
|
|
4411
|
-
|
|
4729
|
+
const email2 = normalizeEmailSafe(user.email);
|
|
4730
|
+
if (!email2) throw new Error(`[auth] importUser: '${user.email}' is not an email address`);
|
|
4731
|
+
add("email", email2);
|
|
4412
4732
|
if (user.passwordHash !== void 0) add("password_hash", user.passwordHash);
|
|
4413
4733
|
if (user.firstName !== void 0) add("first_name", user.firstName);
|
|
4414
4734
|
if (user.lastName !== void 0) add("last_name", user.lastName);
|