@arcblock/did-connect-service 4.1.36 → 4.1.38
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/_generated/asset-bytes.js +1 -1
- package/dist/_generated/asset-manifest.js +6 -6
- package/dist/_generated/header-bundle-string.d.ts +1 -1
- package/dist/_generated/header-bundle-string.d.ts.map +1 -1
- package/dist/_generated/header-bundle-string.js +1 -1
- package/dist/_generated/header-bundle-string.js.map +1 -1
- package/dist/_generated/login-bundle-string.d.ts +1 -1
- package/dist/_generated/login-bundle-string.d.ts.map +1 -1
- package/dist/_generated/login-bundle-string.js +1 -1
- package/dist/_generated/login-bundle-string.js.map +1 -1
- package/dist/assets/{admin-core.69147606.js → admin-core.d42d34ce.js} +20 -0
- package/dist/assets/{admin-extra.979f5e56.js → admin-extra.c7a0720f.js} +3 -3
- package/dist/assets/{admin.76aa0931.css → admin.f5f577f9.css} +27 -0
- package/dist/assets/{header.94d9e46b.js → header.8703ab26.js} +5 -5
- package/dist/assets/login.60fd0777.js +731 -0
- package/dist/assets/{login.7b12c6dc.css → login.a9c8b434.css} +11 -0
- package/dist/handler-errors.d.ts +868 -3
- package/dist/handler-errors.d.ts.map +1 -1
- package/dist/handler-errors.js +1067 -26
- package/dist/handler-errors.js.map +1 -1
- package/dist/handlers/access-key-connect-handler.d.ts.map +1 -1
- package/dist/handlers/access-key-connect-handler.js +20 -11
- package/dist/handlers/access-key-connect-handler.js.map +1 -1
- package/dist/handlers/access-key-handler.d.ts.map +1 -1
- package/dist/handlers/access-key-handler.js +18 -7
- package/dist/handlers/access-key-handler.js.map +1 -1
- package/dist/handlers/account-merge-handler.d.ts +2 -0
- package/dist/handlers/account-merge-handler.d.ts.map +1 -1
- package/dist/handlers/account-merge-handler.js +34 -29
- package/dist/handlers/account-merge-handler.js.map +1 -1
- package/dist/handlers/admin-instance-handler.d.ts.map +1 -1
- package/dist/handlers/admin-instance-handler.js +21 -17
- package/dist/handlers/admin-instance-handler.js.map +1 -1
- package/dist/handlers/auth-handler.d.ts.map +1 -1
- package/dist/handlers/auth-handler.js +17 -10
- package/dist/handlers/auth-handler.js.map +1 -1
- package/dist/handlers/blocklet-js-handler.d.ts.map +1 -1
- package/dist/handlers/blocklet-js-handler.js +2 -1
- package/dist/handlers/blocklet-js-handler.js.map +1 -1
- package/dist/handlers/branding-handler.d.ts +1 -0
- package/dist/handlers/branding-handler.d.ts.map +1 -1
- package/dist/handlers/branding-handler.js +15 -8
- package/dist/handlers/branding-handler.js.map +1 -1
- package/dist/handlers/did-connect-handler.d.ts +1 -0
- package/dist/handlers/did-connect-handler.d.ts.map +1 -1
- package/dist/handlers/did-connect-handler.js +40 -18
- package/dist/handlers/did-connect-handler.js.map +1 -1
- package/dist/handlers/email-login-handler.d.ts +81 -0
- package/dist/handlers/email-login-handler.d.ts.map +1 -1
- package/dist/handlers/email-login-handler.js +124 -23
- package/dist/handlers/email-login-handler.js.map +1 -1
- package/dist/handlers/federation-admin-handler.js +2 -2
- package/dist/handlers/federation-admin-handler.js.map +1 -1
- package/dist/handlers/oauth-handler.d.ts +1 -0
- package/dist/handlers/oauth-handler.d.ts.map +1 -1
- package/dist/handlers/oauth-handler.js +42 -53
- package/dist/handlers/oauth-handler.js.map +1 -1
- package/dist/handlers/passkey-handler.d.ts +1 -0
- package/dist/handlers/passkey-handler.d.ts.map +1 -1
- package/dist/handlers/passkey-handler.js +51 -37
- package/dist/handlers/passkey-handler.js.map +1 -1
- package/dist/handlers/team-handler.d.ts +2 -0
- package/dist/handlers/team-handler.d.ts.map +1 -1
- package/dist/handlers/team-handler.js +58 -35
- package/dist/handlers/team-handler.js.map +1 -1
- package/dist/locale.d.ts +40 -4
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +109 -34
- package/dist/locale.js.map +1 -1
- package/dist/pages/admin/i18n.d.ts.map +1 -1
- package/dist/pages/admin/i18n.js +1415 -6
- package/dist/pages/admin/i18n.js.map +1 -1
- package/dist/pages/admin/index.d.ts.map +1 -1
- package/dist/pages/admin/index.js +5 -3
- package/dist/pages/admin/index.js.map +1 -1
- package/dist/pages/admin/styles.d.ts +1 -1
- package/dist/pages/admin/styles.d.ts.map +1 -1
- package/dist/pages/admin/styles.js +27 -0
- package/dist/pages/admin/styles.js.map +1 -1
- package/dist/pages/admin/tab-branding.d.ts.map +1 -1
- package/dist/pages/admin/tab-branding.js +4 -6
- package/dist/pages/admin/tab-branding.js.map +1 -1
- package/dist/pages/admin/tab-profile-accounts.d.ts.map +1 -1
- package/dist/pages/admin/tab-profile-accounts.js +20 -0
- package/dist/pages/admin/tab-profile-accounts.js.map +1 -1
- package/dist/pages/admin-instances-page.d.ts +218 -0
- package/dist/pages/admin-instances-page.d.ts.map +1 -1
- package/dist/pages/admin-instances-page.js +133 -24
- package/dist/pages/admin-instances-page.js.map +1 -1
- package/dist/pages/error-page.d.ts +37 -0
- package/dist/pages/error-page.d.ts.map +1 -1
- package/dist/pages/error-page.js +33 -1
- package/dist/pages/error-page.js.map +1 -1
- package/dist/pages/gen-access-key-page.d.ts +126 -0
- package/dist/pages/gen-access-key-page.d.ts.map +1 -1
- package/dist/pages/gen-access-key-page.js +72 -20
- package/dist/pages/gen-access-key-page.js.map +1 -1
- package/dist/pages/homepage.d.ts +98 -0
- package/dist/pages/homepage.d.ts.map +1 -1
- package/dist/pages/homepage.js +66 -15
- package/dist/pages/homepage.js.map +1 -1
- package/dist/pages/invite-page.d.ts +90 -0
- package/dist/pages/invite-page.d.ts.map +1 -1
- package/dist/pages/invite-page.js +66 -17
- package/dist/pages/invite-page.js.map +1 -1
- package/dist/pages/login-page.d.ts +8 -0
- package/dist/pages/login-page.d.ts.map +1 -1
- package/dist/pages/login-page.js +12 -2
- package/dist/pages/login-page.js.map +1 -1
- package/dist/pages/oauth-callback-page.d.ts +52 -1
- package/dist/pages/oauth-callback-page.d.ts.map +1 -1
- package/dist/pages/oauth-callback-page.js +85 -8
- package/dist/pages/oauth-callback-page.js.map +1 -1
- package/package.json +3 -3
- package/dist/assets/login.566f858e.js +0 -720
|
@@ -21,15 +21,17 @@
|
|
|
21
21
|
* GET /.well-known/service/admin/team → admin SPA
|
|
22
22
|
* GET /.well-known/service/invite → invite page
|
|
23
23
|
*/
|
|
24
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
24
25
|
import { changeMembershipRole } from "../access/change-role.js";
|
|
25
26
|
import { PermissionError, requirePermission } from "../access/rbac.js";
|
|
27
|
+
import { handlerError, localizeKnownHandlerError } from "../handler-errors.js";
|
|
26
28
|
import { resolveInstanceRole } from "../identity/instance-role.js";
|
|
27
|
-
import { detectLocale, detectTheme } from "../locale.js";
|
|
29
|
+
import { detectLocale, detectTheme, languageRowsForCodes, loadEnabledLocales, reconciledArcLangCookie } from "../locale.js";
|
|
28
30
|
import { consoleLogger } from "../logger.js";
|
|
29
31
|
import { buildLoginUrl } from "../login-url.js";
|
|
30
32
|
import { LOGO_PREVIEW_BASE } from "../logo-paths.js";
|
|
31
33
|
import { buildAdminPageHTML } from "../pages/admin/index.js";
|
|
32
|
-
import { buildErrorPageHTML } from "../pages/error-page.js";
|
|
34
|
+
import { buildErrorPageHTML, errorPageCopy } from "../pages/error-page.js";
|
|
33
35
|
import { buildInvitePageHTML } from "../pages/invite-page.js";
|
|
34
36
|
import { parseBase64Image, sniffImageType } from "./avatar-handler.js";
|
|
35
37
|
import { resolveAccessKeyCaller } from "./passkey-handler.js";
|
|
@@ -41,6 +43,8 @@ function escapeEmailHtml(value) {
|
|
|
41
43
|
.replaceAll('"', """)
|
|
42
44
|
.replaceAll("'", "'");
|
|
43
45
|
}
|
|
46
|
+
/** Request-scoped so concurrent team fetches do not share a locale. */
|
|
47
|
+
const handlerLocale = new AsyncLocalStorage();
|
|
44
48
|
const API_BASE = "/.well-known/service/api/team";
|
|
45
49
|
const ADMIN_PAGE = "/.well-known/service/admin";
|
|
46
50
|
const INVITE_PAGE = "/.well-known/service/invite";
|
|
@@ -124,6 +128,7 @@ function shapeConnectedAccounts(rows, userSourceProvider, userDid) {
|
|
|
124
128
|
provider: a.provider,
|
|
125
129
|
id: a.id,
|
|
126
130
|
userInfo,
|
|
131
|
+
createdAt: a.createdAt ?? a.firstLoginAt ?? null,
|
|
127
132
|
lastLoginAt: a.lastLoginAt ?? null,
|
|
128
133
|
isMain: a.provider === userSourceProvider && a.did === userDid,
|
|
129
134
|
...(extra !== undefined ? { extra } : {}),
|
|
@@ -153,6 +158,9 @@ export class TeamHandler {
|
|
|
153
158
|
this.rpName = options.rpName;
|
|
154
159
|
this.logger = options.logger ?? consoleLogger;
|
|
155
160
|
}
|
|
161
|
+
async localeFor(request, instanceDid) {
|
|
162
|
+
return detectLocale(request, await loadEnabledLocales(this.store, instanceDid ?? this.instanceDid));
|
|
163
|
+
}
|
|
156
164
|
/** Resolve the portal base URL for building invitation links. */
|
|
157
165
|
resolvePortalUrl(request) {
|
|
158
166
|
if (this.portalUrl)
|
|
@@ -186,6 +194,11 @@ export class TeamHandler {
|
|
|
186
194
|
}
|
|
187
195
|
// ─── API Router ──────────────────────────────────────────────────────
|
|
188
196
|
async handleAPI(request, path, url, instanceDid, context) {
|
|
197
|
+
const enabled = await loadEnabledLocales(this.store, instanceDid ?? this.instanceDid);
|
|
198
|
+
const locale = detectLocale(request, enabled);
|
|
199
|
+
return handlerLocale.run(locale, () => this.dispatchAPI(request, path, url, instanceDid, context));
|
|
200
|
+
}
|
|
201
|
+
async dispatchAPI(request, path, url, instanceDid, context) {
|
|
189
202
|
const method = request.method;
|
|
190
203
|
try {
|
|
191
204
|
// Public endpoint: invitation info (no auth required)
|
|
@@ -215,7 +228,7 @@ export class TeamHandler {
|
|
|
215
228
|
return await this.handleEmailUpdate(caller, request, instanceDid);
|
|
216
229
|
}
|
|
217
230
|
if (method === "POST" && path === "/profile/email/verify") {
|
|
218
|
-
return await this.handleEmailVerifySend(caller, request);
|
|
231
|
+
return await this.handleEmailVerifySend(caller, request, instanceDid);
|
|
219
232
|
}
|
|
220
233
|
if (method === "PUT" && path === "/profile/email/verify") {
|
|
221
234
|
return await this.handleEmailVerifyConfirm(caller, request, instanceDid);
|
|
@@ -537,10 +550,11 @@ export class TeamHandler {
|
|
|
537
550
|
}
|
|
538
551
|
/** PUT /profile/email — update email directly (marks as unverified). */
|
|
539
552
|
async handleEmailUpdate(caller, request, instanceDid) {
|
|
553
|
+
const locale = await this.localeFor(request, instanceDid);
|
|
540
554
|
const body = await this.parseJSON(request);
|
|
541
555
|
const email = body.email?.toLowerCase().trim();
|
|
542
556
|
if (!email?.includes("@")) {
|
|
543
|
-
return this.jsonResponse({ error: "
|
|
557
|
+
return this.jsonResponse({ error: handlerError("invalidEmailAddress", locale) }, 400);
|
|
544
558
|
}
|
|
545
559
|
await this.store.updateUserProfile(caller.did, { email, emailVerified: 0 }, caller.did);
|
|
546
560
|
// Record only the domain (after the final `@`) to avoid PII leakage.
|
|
@@ -557,19 +571,20 @@ export class TeamHandler {
|
|
|
557
571
|
return this.jsonResponse({ ok: true, user });
|
|
558
572
|
}
|
|
559
573
|
/** POST /profile/email/verify — send verification code to current email. */
|
|
560
|
-
async handleEmailVerifySend(caller,
|
|
574
|
+
async handleEmailVerifySend(caller, request, instanceDid) {
|
|
575
|
+
const locale = await this.localeFor(request, instanceDid);
|
|
561
576
|
const emailConfig = await this.resolveEmailConfig();
|
|
562
577
|
if (!emailConfig) {
|
|
563
|
-
return this.jsonResponse({ error: "
|
|
578
|
+
return this.jsonResponse({ error: handlerError("emailServiceNotConfigured", locale) }, 503);
|
|
564
579
|
}
|
|
565
580
|
const userInfo = await this.store.getMemberInfo(caller.did);
|
|
566
581
|
const email = userInfo?.email;
|
|
567
582
|
if (!email) {
|
|
568
|
-
return this.jsonResponse({ error: "
|
|
583
|
+
return this.jsonResponse({ error: handlerError("noEmailOnProfile", locale) }, 400);
|
|
569
584
|
}
|
|
570
585
|
// Rate limit
|
|
571
586
|
if (await this.store.isVerifyCodeSent(email)) {
|
|
572
|
-
return this.jsonResponse({ error: "
|
|
587
|
+
return this.jsonResponse({ error: handlerError("codeAlreadySent", locale) }, 429);
|
|
573
588
|
}
|
|
574
589
|
const code = Array.from({ length: 6 }, () => Math.floor(Math.random() * 10)).join("");
|
|
575
590
|
await this.store.createVerifyCode(code, email, "email-verify");
|
|
@@ -596,32 +611,33 @@ export class TeamHandler {
|
|
|
596
611
|
if (!res.ok) {
|
|
597
612
|
const text = await res.text();
|
|
598
613
|
this.logger.warn({ message: "resend api rejected email-change verification", mod: "team", status: res.status, body: text.slice(0, 200) });
|
|
599
|
-
return this.jsonResponse({ error:
|
|
614
|
+
return this.jsonResponse({ error: handlerError("emailSendFailed", locale) }, 500);
|
|
600
615
|
}
|
|
601
616
|
}
|
|
602
617
|
catch (err) {
|
|
603
618
|
const message = err instanceof Error ? err.message : "Email send failed";
|
|
604
619
|
this.logger.error({ message: "resend network error sending email-change verification", mod: "team", err: message });
|
|
605
|
-
return this.jsonResponse({ error:
|
|
620
|
+
return this.jsonResponse({ error: handlerError("emailSendFailed", locale) }, 500);
|
|
606
621
|
}
|
|
607
622
|
await this.store.markVerifyCodeSent(code);
|
|
608
623
|
return this.jsonResponse({ ok: true });
|
|
609
624
|
}
|
|
610
625
|
/** PUT /profile/email/verify — confirm verification code, mark email as verified. */
|
|
611
626
|
async handleEmailVerifyConfirm(caller, request, instanceDid) {
|
|
627
|
+
const locale = await this.localeFor(request, instanceDid);
|
|
612
628
|
const body = await this.parseJSON(request);
|
|
613
629
|
const code = body.code?.trim();
|
|
614
630
|
if (!code) {
|
|
615
|
-
return this.jsonResponse({ error: "
|
|
631
|
+
return this.jsonResponse({ error: handlerError("verificationCodeRequired", locale) }, 400);
|
|
616
632
|
}
|
|
617
633
|
const userInfo = await this.store.getMemberInfo(caller.did);
|
|
618
634
|
const email = userInfo?.email;
|
|
619
635
|
if (!email) {
|
|
620
|
-
return this.jsonResponse({ error: "
|
|
636
|
+
return this.jsonResponse({ error: handlerError("noEmailOnProfile", locale) }, 400);
|
|
621
637
|
}
|
|
622
638
|
const verified = await this.store.consumeVerifyCode(code);
|
|
623
639
|
if (!verified || verified.subject !== email) {
|
|
624
|
-
return this.jsonResponse({ error: "
|
|
640
|
+
return this.jsonResponse({ error: handlerError("invalidOrExpiredVerificationCode", locale) }, 400);
|
|
625
641
|
}
|
|
626
642
|
await this.store.updateUserProfile(caller.did, { emailVerified: 1 }, caller.did);
|
|
627
643
|
await this.store.createAuditLog({
|
|
@@ -1495,7 +1511,8 @@ export class TeamHandler {
|
|
|
1495
1511
|
async handleSaveOAuthProvider(caller, provider, request) {
|
|
1496
1512
|
requirePermission(caller.role, "settings.edit_auth");
|
|
1497
1513
|
if (!TeamHandler.VALID_OAUTH_PROVIDERS.includes(provider)) {
|
|
1498
|
-
|
|
1514
|
+
const locale = handlerLocale.getStore() ?? "en";
|
|
1515
|
+
return this.errorResponse(handlerError("invalidSettingsProvider", locale, { provider }), 400, "VALIDATION_ERROR");
|
|
1499
1516
|
}
|
|
1500
1517
|
const body = this.sanitizeKeys(await this.parseJSON(request));
|
|
1501
1518
|
// Validate required fields based on provider
|
|
@@ -1567,7 +1584,8 @@ export class TeamHandler {
|
|
|
1567
1584
|
for (const key of ["passkey", "email", "wallet"]) {
|
|
1568
1585
|
const entry = body[key];
|
|
1569
1586
|
if (entry && typeof entry.enabled !== "boolean") {
|
|
1570
|
-
|
|
1587
|
+
const locale = handlerLocale.getStore() ?? "en";
|
|
1588
|
+
return this.errorResponse(handlerError("builtinEnabledMustBeBoolean", locale, { key }), 400, "VALIDATION_ERROR");
|
|
1571
1589
|
}
|
|
1572
1590
|
}
|
|
1573
1591
|
const did = this.settingsInstanceDid;
|
|
@@ -1647,19 +1665,25 @@ export class TeamHandler {
|
|
|
1647
1665
|
if (!user) {
|
|
1648
1666
|
return new Response(null, { status: 302, headers: { Location: loginUrl } });
|
|
1649
1667
|
}
|
|
1668
|
+
const brandingDid = instanceDid || this.instanceDid;
|
|
1669
|
+
const enabled = await loadEnabledLocales(this.store, brandingDid);
|
|
1650
1670
|
if (!user.approved) {
|
|
1651
|
-
|
|
1671
|
+
const locale = detectLocale(request, enabled);
|
|
1672
|
+
const copy = errorPageCopy(locale);
|
|
1673
|
+
return this.errorPage(403, copy.accountBlockedTitle, copy.accountBlockedMessage, url, locale);
|
|
1652
1674
|
}
|
|
1653
1675
|
// Resolve effective role for instance context
|
|
1654
1676
|
let effectiveRole = user.role ?? "guest";
|
|
1655
1677
|
if (instanceDid) {
|
|
1656
1678
|
const resolved = await resolveInstanceRole(this.store, caller.did, instanceDid, user.role ?? undefined);
|
|
1657
1679
|
if (!resolved && !opts?.isUserPage) {
|
|
1658
|
-
|
|
1680
|
+
const locale = detectLocale(request, enabled);
|
|
1681
|
+
const copy = errorPageCopy(locale);
|
|
1682
|
+
return this.errorPage(403, copy.notTeamMemberTitle, copy.notTeamMemberMessage, url, locale);
|
|
1659
1683
|
}
|
|
1660
1684
|
effectiveRole = resolved ?? effectiveRole;
|
|
1661
1685
|
}
|
|
1662
|
-
const locale = detectLocale(request);
|
|
1686
|
+
const locale = detectLocale(request, enabled);
|
|
1663
1687
|
const theme = detectTheme(request);
|
|
1664
1688
|
// Read app branding + languages for admin header.
|
|
1665
1689
|
//
|
|
@@ -1673,22 +1697,15 @@ export class TeamHandler {
|
|
|
1673
1697
|
// pick between the two URLs is no longer needed.
|
|
1674
1698
|
let appName = this.rpName || "App";
|
|
1675
1699
|
const appLogo = `${LOGO_PREVIEW_BASE}/square`;
|
|
1676
|
-
|
|
1677
|
-
const brandingDid = instanceDid || this.instanceDid;
|
|
1700
|
+
const languages = languageRowsForCodes(enabled);
|
|
1678
1701
|
if (brandingDid) {
|
|
1679
1702
|
try {
|
|
1680
|
-
const
|
|
1681
|
-
this.store.getSetting(brandingDid, "app:branding"),
|
|
1682
|
-
this.store.getSetting(brandingDid, "app:languages"),
|
|
1683
|
-
]);
|
|
1703
|
+
const brandingRaw = await this.store.getSetting(brandingDid, "app:branding");
|
|
1684
1704
|
if (brandingRaw) {
|
|
1685
1705
|
const branding = JSON.parse(brandingRaw);
|
|
1686
1706
|
if (branding.name)
|
|
1687
1707
|
appName = branding.name;
|
|
1688
1708
|
}
|
|
1689
|
-
if (langsRaw) {
|
|
1690
|
-
languages = JSON.parse(langsRaw);
|
|
1691
|
-
}
|
|
1692
1709
|
}
|
|
1693
1710
|
catch { /* use defaults */ }
|
|
1694
1711
|
}
|
|
@@ -1747,12 +1764,14 @@ export class TeamHandler {
|
|
|
1747
1764
|
passkeyLoginEnabled,
|
|
1748
1765
|
emailLoginEnabled,
|
|
1749
1766
|
});
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
"Cache-Control": "private, no-store",
|
|
1754
|
-
},
|
|
1767
|
+
const headers = new Headers({
|
|
1768
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
1769
|
+
"Cache-Control": "private, no-store",
|
|
1755
1770
|
});
|
|
1771
|
+
const localeCookie = reconciledArcLangCookie(request, locale);
|
|
1772
|
+
if (localeCookie)
|
|
1773
|
+
headers.set("Set-Cookie", localeCookie);
|
|
1774
|
+
return new Response(html, { headers });
|
|
1756
1775
|
}
|
|
1757
1776
|
async serveInvitePage(request, ctxInstanceDid) {
|
|
1758
1777
|
// Resolve federation config: if this instance is a federation member,
|
|
@@ -1768,7 +1787,8 @@ export class TeamHandler {
|
|
|
1768
1787
|
masterOAuthOrigin = (await this.store.getSetting(groupScope, "masterUrl")) ?? undefined;
|
|
1769
1788
|
}
|
|
1770
1789
|
}
|
|
1771
|
-
const
|
|
1790
|
+
const enabled = await loadEnabledLocales(this.store, effectiveDid);
|
|
1791
|
+
const locale = detectLocale(request, enabled);
|
|
1772
1792
|
const html = buildInvitePageHTML(this.apiBase, locale, {
|
|
1773
1793
|
masterOAuthOrigin,
|
|
1774
1794
|
appName: this.rpName || "App",
|
|
@@ -1781,11 +1801,12 @@ export class TeamHandler {
|
|
|
1781
1801
|
});
|
|
1782
1802
|
}
|
|
1783
1803
|
// ─── Helpers ────────────────────────────────────────────────────────
|
|
1784
|
-
errorPage(status, title, message, url) {
|
|
1804
|
+
errorPage(status, title, message, url, locale) {
|
|
1785
1805
|
const html = buildErrorPageHTML({
|
|
1786
1806
|
status,
|
|
1787
1807
|
title,
|
|
1788
1808
|
message,
|
|
1809
|
+
locale,
|
|
1789
1810
|
action: { label: "Go to Homepage", href: "/" },
|
|
1790
1811
|
secondaryAction: status === 403
|
|
1791
1812
|
? { label: "Sign in with another account", href: buildLoginUrl({ returnTo: url.pathname }) }
|
|
@@ -1806,7 +1827,9 @@ export class TeamHandler {
|
|
|
1806
1827
|
});
|
|
1807
1828
|
}
|
|
1808
1829
|
errorResponse(message, status, code) {
|
|
1809
|
-
|
|
1830
|
+
const locale = handlerLocale.getStore();
|
|
1831
|
+
const error = locale && status !== 401 ? localizeKnownHandlerError(message, locale) : message;
|
|
1832
|
+
return this.jsonResponse({ ok: false, error, code }, status);
|
|
1810
1833
|
}
|
|
1811
1834
|
async parseJSON(request) {
|
|
1812
1835
|
try {
|