@arcblock/did-connect-service 4.1.12 → 4.1.14

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.
Files changed (127) hide show
  1. package/dist/_generated/asset-bytes.js +1 -1
  2. package/dist/_generated/asset-manifest.js +4 -4
  3. package/dist/_generated/login-bundle-string.d.ts +1 -1
  4. package/dist/_generated/login-bundle-string.d.ts.map +1 -1
  5. package/dist/_generated/login-bundle-string.js +1 -1
  6. package/dist/_generated/login-bundle-string.js.map +1 -1
  7. package/dist/access/change-role.d.ts +48 -0
  8. package/dist/access/change-role.d.ts.map +1 -0
  9. package/dist/access/change-role.js +52 -0
  10. package/dist/access/change-role.js.map +1 -0
  11. package/dist/assets/{admin-core.cbbdbe6d.js → admin-core.a63bbc69.js} +16 -17
  12. package/dist/assets/{admin-extra.35b91f98.js → admin-extra.5b309e5e.js} +8 -4
  13. package/dist/assets/{admin.c26bb17a.css → admin.dfeedbe4.css} +10 -0
  14. package/dist/assets/login.76c483c2.js +720 -0
  15. package/dist/blocklet-service.d.ts.map +1 -1
  16. package/dist/blocklet-service.js +5 -1
  17. package/dist/blocklet-service.js.map +1 -1
  18. package/dist/handler-errors.d.ts +118 -0
  19. package/dist/handler-errors.d.ts.map +1 -0
  20. package/dist/handler-errors.js +38 -0
  21. package/dist/handler-errors.js.map +1 -0
  22. package/dist/handlers/access-key-connect-handler.d.ts +3 -0
  23. package/dist/handlers/access-key-connect-handler.d.ts.map +1 -1
  24. package/dist/handlers/access-key-connect-handler.js +7 -1
  25. package/dist/handlers/access-key-connect-handler.js.map +1 -1
  26. package/dist/handlers/admin-instance-handler.d.ts.map +1 -1
  27. package/dist/handlers/admin-instance-handler.js +2 -1
  28. package/dist/handlers/admin-instance-handler.js.map +1 -1
  29. package/dist/handlers/auth-handler.d.ts.map +1 -1
  30. package/dist/handlers/auth-handler.js +33 -9
  31. package/dist/handlers/auth-handler.js.map +1 -1
  32. package/dist/handlers/branding-handler.d.ts.map +1 -1
  33. package/dist/handlers/branding-handler.js +12 -9
  34. package/dist/handlers/branding-handler.js.map +1 -1
  35. package/dist/handlers/did-connect-handler.d.ts.map +1 -1
  36. package/dist/handlers/did-connect-handler.js +6 -5
  37. package/dist/handlers/did-connect-handler.js.map +1 -1
  38. package/dist/handlers/email-login-handler.d.ts +1 -1
  39. package/dist/handlers/email-login-handler.d.ts.map +1 -1
  40. package/dist/handlers/email-login-handler.js +63 -12
  41. package/dist/handlers/email-login-handler.js.map +1 -1
  42. package/dist/handlers/federation-admin-handler.d.ts +2 -0
  43. package/dist/handlers/federation-admin-handler.d.ts.map +1 -1
  44. package/dist/handlers/federation-admin-handler.js +105 -51
  45. package/dist/handlers/federation-admin-handler.js.map +1 -1
  46. package/dist/handlers/oauth-handler.d.ts.map +1 -1
  47. package/dist/handlers/oauth-handler.js +23 -12
  48. package/dist/handlers/oauth-handler.js.map +1 -1
  49. package/dist/handlers/passkey-handler.d.ts.map +1 -1
  50. package/dist/handlers/passkey-handler.js +5 -4
  51. package/dist/handlers/passkey-handler.js.map +1 -1
  52. package/dist/handlers/team-handler.d.ts.map +1 -1
  53. package/dist/handlers/team-handler.js +19 -19
  54. package/dist/handlers/team-handler.js.map +1 -1
  55. package/dist/identity/refresh-tokens.d.ts +21 -0
  56. package/dist/identity/refresh-tokens.d.ts.map +1 -0
  57. package/dist/identity/refresh-tokens.js +45 -0
  58. package/dist/identity/refresh-tokens.js.map +1 -0
  59. package/dist/identity/session-context.d.ts +12 -0
  60. package/dist/identity/session-context.d.ts.map +1 -1
  61. package/dist/identity/session-context.js +12 -0
  62. package/dist/identity/session-context.js.map +1 -1
  63. package/dist/identity/session-tokens.d.ts +15 -0
  64. package/dist/identity/session-tokens.d.ts.map +1 -0
  65. package/dist/identity/session-tokens.js +15 -0
  66. package/dist/identity/session-tokens.js.map +1 -0
  67. package/dist/locale.d.ts +1 -1
  68. package/dist/locale.d.ts.map +1 -1
  69. package/dist/og/templates.d.ts.map +1 -1
  70. package/dist/og/templates.js +33 -4
  71. package/dist/og/templates.js.map +1 -1
  72. package/dist/pages/admin/i18n.d.ts.map +1 -1
  73. package/dist/pages/admin/i18n.js +33 -9
  74. package/dist/pages/admin/i18n.js.map +1 -1
  75. package/dist/pages/admin/scripts/api-client.d.ts +1 -1
  76. package/dist/pages/admin/scripts/api-client.d.ts.map +1 -1
  77. package/dist/pages/admin/scripts/api-client.js +4 -4
  78. package/dist/pages/admin/scripts/utils.d.ts +1 -1
  79. package/dist/pages/admin/scripts/utils.d.ts.map +1 -1
  80. package/dist/pages/admin/scripts/utils.js +7 -8
  81. package/dist/pages/admin/scripts/utils.js.map +1 -1
  82. package/dist/pages/admin/styles.d.ts +1 -1
  83. package/dist/pages/admin/styles.d.ts.map +1 -1
  84. package/dist/pages/admin/styles.js +10 -0
  85. package/dist/pages/admin/styles.js.map +1 -1
  86. package/dist/pages/admin/tab-access-keys.d.ts +1 -1
  87. package/dist/pages/admin/tab-access-keys.d.ts.map +1 -1
  88. package/dist/pages/admin/tab-access-keys.js +4 -4
  89. package/dist/pages/admin/tab-invitations.d.ts +1 -1
  90. package/dist/pages/admin/tab-invitations.d.ts.map +1 -1
  91. package/dist/pages/admin/tab-invitations.js +2 -2
  92. package/dist/pages/admin/tab-members.d.ts +1 -1
  93. package/dist/pages/admin/tab-members.d.ts.map +1 -1
  94. package/dist/pages/admin/tab-members.js +7 -3
  95. package/dist/pages/admin/tab-members.js.map +1 -1
  96. package/dist/pages/admin/tab-profile-accounts.js +1 -1
  97. package/dist/pages/admin-instances-page.d.ts +1 -1
  98. package/dist/pages/admin-instances-page.d.ts.map +1 -1
  99. package/dist/pages/admin-instances-page.js +195 -65
  100. package/dist/pages/admin-instances-page.js.map +1 -1
  101. package/dist/pages/gen-access-key-page.d.ts +1 -1
  102. package/dist/pages/gen-access-key-page.d.ts.map +1 -1
  103. package/dist/pages/gen-access-key-page.js +163 -35
  104. package/dist/pages/gen-access-key-page.js.map +1 -1
  105. package/dist/pages/homepage.d.ts.map +1 -1
  106. package/dist/pages/homepage.js +0 -4
  107. package/dist/pages/homepage.js.map +1 -1
  108. package/dist/pages/invite-page.d.ts +1 -1
  109. package/dist/pages/invite-page.d.ts.map +1 -1
  110. package/dist/pages/invite-page.js +91 -21
  111. package/dist/pages/invite-page.js.map +1 -1
  112. package/dist/pages/oauth-callback-page.d.ts.map +1 -1
  113. package/dist/pages/oauth-callback-page.js +7 -3
  114. package/dist/pages/oauth-callback-page.js.map +1 -1
  115. package/dist/store/d1-store.d.ts +55 -1
  116. package/dist/store/d1-store.d.ts.map +1 -1
  117. package/dist/store/d1-store.js +162 -9
  118. package/dist/store/d1-store.js.map +1 -1
  119. package/migrations/0011_refresh_tokens.sql +23 -0
  120. package/package.json +7 -7
  121. package/dist/assets/admin-core.a13c2729.js +0 -1461
  122. package/dist/assets/admin-core.c0b5af61.js +0 -1393
  123. package/dist/assets/admin-core.e83fd379.js +0 -1397
  124. package/dist/assets/admin-extra.7ca9c16b.js +0 -2529
  125. package/dist/assets/admin-extra.841b2bbe.js +0 -2530
  126. package/dist/assets/admin-extra.afcb3651.js +0 -2528
  127. package/dist/assets/login.d3f05790.js +0 -720
@@ -2,7 +2,7 @@
2
2
  * EmailLoginHandler — email code + magic link login for Cloudflare Workers.
3
3
  *
4
4
  * Flow:
5
- * 1. POST /sendCode — generate 6-digit code, send via Resend, return { id }
5
+ * 1. POST /sendCode — generate 8-digit CSPRNG code, send via Resend, return { id }
6
6
  * 2. GET /status — poll whether code has been verified (for UX)
7
7
  * 3. POST /login — verify code (or magic token JWT), derive DID, issue JWT
8
8
  *
@@ -17,11 +17,32 @@ import { ensureInstanceMembership } from "../identity/auto-membership.js";
17
17
  import { deriveDID } from "../identity/federation.js";
18
18
  import { fetchGravatarUrl } from "../identity/gravatar.js";
19
19
  import { signJWT, verifyJWT } from "../identity/jwt.js";
20
+ import { issueSessionTokens } from "../identity/session-tokens.js";
20
21
  import { consoleLogger } from "../logger.js";
21
22
  import { downloadAndStoreAvatar } from "./avatar-handler.js";
22
23
  const PREFIX = "/.well-known/service/api/email";
23
24
  /** @deprecated Keep old prefix for backwards compatibility with existing clients. */
24
25
  const LEGACY_PREFIX = "/.well-known/service/api/user/email";
26
+ /** Verification code length (digits). 8 digits = 10^8 keyspace, generated via CSPRNG. */
27
+ const CODE_LENGTH = 8;
28
+ /** Brute-force lockout on /login, independent of /sendCode's 1/minute rate limit.
29
+ * Scoped per verify-code id (the specific pending login) and per IP (broader scan protection). */
30
+ const LOGIN_MAX_ATTEMPTS_PER_ID = 5;
31
+ const LOGIN_MAX_ATTEMPTS_PER_IP = 20;
32
+ const LOGIN_LOCKOUT_TTL_SECONDS = 15 * 60;
33
+ /** Generate a verification code using a CSPRNG (crypto.getRandomValues), not Math.random().
34
+ * Uses rejection sampling (reject bytes >= 250) so each digit is uniform over 0-9. */
35
+ function generateVerifyCode(length = CODE_LENGTH) {
36
+ const digits = [];
37
+ while (digits.length < length) {
38
+ const buf = crypto.getRandomValues(new Uint8Array(length - digits.length));
39
+ for (const b of buf) {
40
+ if (b < 250)
41
+ digits.push(b % 10);
42
+ }
43
+ }
44
+ return digits.join("");
45
+ }
25
46
  export class EmailLoginHandler {
26
47
  options;
27
48
  logger;
@@ -102,8 +123,8 @@ export class EmailLoginHandler {
102
123
  if (await this.options.store.isVerifyCodeSent(email)) {
103
124
  return jsonResponse({ error: "Code already sent, please wait" }, 429);
104
125
  }
105
- // Generate 6-digit code
106
- const code = Array.from({ length: 6 }, () => Math.floor(Math.random() * 10)).join("");
126
+ // Generate code via CSPRNG (8 digits — see generateVerifyCode())
127
+ const code = generateVerifyCode();
107
128
  const id = await this.options.store.createVerifyCode(code, email, "login");
108
129
  // Generate magic link JWT (30 min)
109
130
  const origin = new URL(request.url).origin;
@@ -127,7 +148,10 @@ export class EmailLoginHandler {
127
148
  if (!res.ok) {
128
149
  const text = await res.text();
129
150
  this.logger.error({ message: "resend api rejected verification email", mod: "email", op: "sendCode", status: res.status, body: text.slice(0, 200), emailDomain: email.split("@").pop() });
130
- return jsonResponse({ error: `Failed to send email: ${text}` }, 500);
151
+ // Never echo the upstream (Resend) response body to the unauthenticated
152
+ // caller — it can contain provider-internal details. Full text stays
153
+ // only in the truncated structured log above.
154
+ return jsonResponse({ error: "Failed to send email" }, 500);
131
155
  }
132
156
  }
133
157
  catch (err) {
@@ -166,24 +190,53 @@ export class EmailLoginHandler {
166
190
  catch {
167
191
  return jsonResponse({ error: "Invalid request body" }, 400);
168
192
  }
169
- // Resolve the verification code
193
+ // Resolve the verification code, bound to the specific verify-code row id
194
+ // (returned by /sendCode). Binding to id prevents a guessed code from matching
195
+ // ANY live code in the table — it can only ever match the session it was issued for.
170
196
  let verifyCode;
197
+ let verifyId;
171
198
  if (body.magicToken) {
172
199
  const payload = await verifyJWT(body.magicToken, this.options.jwtSecret);
173
- if (!payload || typeof payload.code !== "string") {
200
+ if (!payload || typeof payload.code !== "string" || typeof payload.id !== "number") {
174
201
  return jsonResponse({ error: "Invalid or expired magic link" }, 400);
175
202
  }
176
203
  verifyCode = payload.code;
204
+ verifyId = payload.id;
177
205
  }
178
206
  else if (body.code) {
207
+ const idNum = typeof body.id === "number" ? body.id : Number(body.id);
208
+ if (!Number.isFinite(idNum) || !Number.isInteger(idNum)) {
209
+ return jsonResponse({ error: "Missing or invalid id" }, 400);
210
+ }
179
211
  verifyCode = body.code;
212
+ verifyId = idNum;
180
213
  }
181
214
  else {
182
215
  return jsonResponse({ error: "Missing code or magicToken" }, 400);
183
216
  }
184
- // Consume verify code (single-use)
185
- const record = await this.options.store.consumeVerifyCode(verifyCode);
217
+ // Brute-force lockout on /login itself — independent of /sendCode's 1/minute rate
218
+ // limit. Scoped per verify-code id (the specific pending login) and per IP.
219
+ const { store } = this.options;
220
+ const ip = request.headers.get("CF-Connecting-IP") ?? undefined;
221
+ const idAttemptsKey = `email-login:attempts:id:${verifyId}`;
222
+ const ipAttemptsKey = `email-login:attempts:ip:${ip ?? "unknown"}`;
223
+ const [idAttemptsRaw, ipAttemptsRaw] = await Promise.all([
224
+ store.cacheGet(idAttemptsKey),
225
+ store.cacheGet(ipAttemptsKey),
226
+ ]);
227
+ const idAttempts = idAttemptsRaw ? Number(idAttemptsRaw) : 0;
228
+ const ipAttempts = ipAttemptsRaw ? Number(ipAttemptsRaw) : 0;
229
+ if (idAttempts >= LOGIN_MAX_ATTEMPTS_PER_ID || ipAttempts >= LOGIN_MAX_ATTEMPTS_PER_IP) {
230
+ this.logger.warn({ message: "email login locked out after too many failed attempts", mod: "email", op: "login", idAttempts, ipAttempts });
231
+ return jsonResponse({ error: "Too many attempts, please try again later" }, 429);
232
+ }
233
+ // Consume verify code (single-use), bound to (code, id)
234
+ const record = await store.consumeVerifyCode(verifyCode, verifyId);
186
235
  if (!record) {
236
+ await Promise.all([
237
+ store.cachePut(idAttemptsKey, String(idAttempts + 1), LOGIN_LOCKOUT_TTL_SECONDS),
238
+ store.cachePut(ipAttemptsKey, String(ipAttempts + 1), LOGIN_LOCKOUT_TTL_SECONDS),
239
+ ]);
187
240
  return jsonResponse({ error: "Invalid or expired code" }, 400);
188
241
  }
189
242
  // Derive DID from email (delegates to master in federated mode)
@@ -195,11 +248,9 @@ export class EmailLoginHandler {
195
248
  const userDid = wallet.did;
196
249
  const userPk = wallet.pk;
197
250
  // Create or update user
198
- const { store } = this.options;
199
251
  const existingUser = await store.getUserByDidOrConnectedAccount(userDid);
200
252
  const isNewUser = !existingUser;
201
253
  const primaryDid = existingUser?.did || userDid;
202
- const ip = request.headers.get("CF-Connecting-IP") ?? undefined;
203
254
  const hostname = new URL(request.url).hostname;
204
255
  // Resolve invitation from cookie (set by invite page)
205
256
  let invitedRole;
@@ -304,12 +355,12 @@ export class EmailLoginHandler {
304
355
  };
305
356
  if (jwtUser?.fullName)
306
357
  jwtPayload.fullName = jwtUser.fullName;
307
- const jwt = await signJWT(jwtPayload, this.options.jwtSecret, this.options.jwtExpiresIn);
358
+ const { sessionToken: jwt, refreshToken } = await issueSessionTokens(jwtPayload, primaryDid, { jwtSecret: this.options.jwtSecret, jwtExpiresIn: this.options.jwtExpiresIn }, store);
308
359
  let cookie = `${this.options.cookieName}=${jwt}; Path=/; Secure; SameSite=Lax; Max-Age=${this.options.jwtExpiresIn}`;
309
360
  const cookieDomain = typeof this.options.rpID === "string" ? this.options.rpID : undefined;
310
361
  if (cookieDomain?.includes("."))
311
362
  cookie += `; Domain=${cookieDomain}`;
312
- return new Response(JSON.stringify({ ok: true, sessionToken: jwt, refreshToken: jwt, did: primaryDid }), {
363
+ return new Response(JSON.stringify({ ok: true, sessionToken: jwt, refreshToken, did: primaryDid }), {
313
364
  status: 200,
314
365
  headers: {
315
366
  "Content-Type": "application/json",
@@ -1 +1 @@
1
- {"version":3,"file":"email-login-handler.js","sourceRoot":"","sources":["../../src/handlers/email-login-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAuB7D,MAAM,MAAM,GAAG,gCAAgC,CAAC;AAChD,qFAAqF;AACrF,MAAM,aAAa,GAAG,qCAAqC,CAAC;AAE5D,MAAM,OAAO,iBAAiB;IACpB,OAAO,CAA2B;IAClC,MAAM,CAAS;IAEvB,YAAY,OAAiC;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED;kEAC8D;IAC9D,KAAK,CAAC,kBAAkB,CAAC,WAAoB;QAC3C,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACxD,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACxF,CAAC;QACD,0EAA0E;QAC1E,IAAI,GAAG,GAAG,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAClD,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;YAClF,IAAI,UAAU;gBAAE,GAAG,GAAG,UAAU,CAAC,CAAC,uBAAuB;QAC3D,CAAC;QACD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YACrE,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoD,CAAC;YAClF,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;YAC9E,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,SAAS;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,WAAoB;QAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,MAAM,GAAG,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAEvD,mEAAmE;QACnE,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;YAC1C,IAAI,IAAI,KAAK,GAAG,GAAG,WAAW,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,IAAI,KAAK,GAAG,GAAG,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACzD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,IAAI,KAAK,GAAG,GAAG,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBACzD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iEAAiE;IACzD,KAAK,CAAC,QAAQ,CAAC,OAAgB,EAAE,WAAoB;QAC3D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,0CAA0C,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;YACrH,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;QAED,0CAA0C;QAC1C,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAAE,GAAG,CAAC,CAAC;QACxE,CAAC;QAED,wBAAwB;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAE3E,mCAAmC;QACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,GAAG,MAAM,yCAAyC,UAAU,EAAE,CAAC;QAEjF,sBAAsB;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,EAAE;gBACvD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,WAAW,CAAC,YAAY,EAAE;oBACnD,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,IAAI,EAAE,WAAW,CAAC,SAAS;oBAC3B,EAAE,EAAE,KAAK;oBACT,OAAO,EAAE,iBAAiB;oBAC1B,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC;iBAC7C,CAAC;aACH,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,wCAAwC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC1L,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,yBAAyB,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACzE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACnK,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,gEAAgE;IACxD,KAAK,CAAC,WAAW,CAAC,OAAgB;QACxC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE;YAAE,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAC;QACrE,uEAAuE;QACvE,sDAAsD;QACtD,OAAO,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,uEAAuE;IAC/D,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,WAAoB;QACxD,kFAAkF;QAClF,mFAAmF;QACnF,wEAAwE;QACxE,iFAAiF;QACjF,iCAAiC;QACjC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACxD,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC/C,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,qDAAqD,EAAE,EAAE,GAAG,CAAC,CAAC;QAC7F,CAAC;QAED,IAAI,IAA4C,CAAC;QACjD,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,gCAAgC;QAChC,IAAI,UAAkB,CAAC;QACvB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACzE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjD,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAAE,GAAG,CAAC,CAAC;YACvE,CAAC;YACD,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;QAED,mCAAmC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QAED,gEAAgE;QAChE,MAAM,GAAG,GAAG,SAAS,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;YAClC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;SACpC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;QAEzB,wBAAwB;QACxB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/B,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,8BAA8B,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,CAAC,YAAY,CAAC;QAChC,MAAM,UAAU,GAAG,YAAY,EAAE,GAAG,IAAI,OAAO,CAAC;QAEhD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC;QAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QAE/C,sDAAsD;QACtD,IAAI,WAA+B,CAAC;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACvE,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YAC3D,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ,IAAI,UAAU,CAAC,QAAQ,GAAG,UAAU,CAAC,OAAO,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;gBAC5I,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC;YAChC,CAAC;QACH,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,+DAA+D;YAC/D,8CAA8C;YAC9C,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;YAC7C,IAAI,SAAS,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBACpG,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,KAAK,CAAC,cAAc,CAAC;wBACzB,MAAM,EAAE,uBAAuB;wBAC/B,WAAW,EAAE,OAAO;wBACpB,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE;wBAChG,EAAE;wBACF,WAAW,EAAE,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;qBAClE,CAAC,CAAC;oBACH,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC1F,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC,UAAU,CAAC;gBACrB,GAAG,EAAE,OAAO;gBACZ,EAAE,EAAE,MAAM;gBACV,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACtC,KAAK,EAAE,MAAM,CAAC,OAAO;gBACrB,MAAM;gBACN,cAAc,EAAE,cAAc,CAAC,KAAK;gBACpC,aAAa,EAAE,CAAC;gBAChB,EAAE;gBACF,MAAM,EAAE,QAAQ;gBAChB,SAAS,EAAE,OAAO;aACnB,CAAC,CAAC;YAEH,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;gBACpB,MAAM,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YACzD,CAAC;YAED,2CAA2C;YAC3C,IAAI,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAClD,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;YACtD,2CAA2C;YAC3C,MAAM,KAAK,CAAC,iBAAiB,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9E,CAAC;QAED,6DAA6D;QAC7D,MAAM,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAE5E,2BAA2B;QAC3B,MAAM,KAAK,CAAC,sBAAsB,CAAC;YACjC,GAAG,EAAE,OAAO;YACZ,EAAE,EAAE,MAAM;YACV,OAAO,EAAE,UAAU;YACnB,QAAQ,EAAE,OAAO;YACjB,EAAE,EAAE,GAAG;YACP,KAAK,EAAE,UAAU;SAClB,CAAC,CAAC;QAEH,YAAY;QACZ,MAAM,KAAK,CAAC,cAAc,CAAC;YACzB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY;YAClD,WAAW,EAAE,UAAU;YACvB,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE;YACjD,EAAE;YACF,WAAW;SACZ,CAAC,CAAC;QAEH,4CAA4C;QAC5C,MAAM,OAAO,GAAG,YAAY,IAAI,MAAM,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,SAAS,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,OAAO,CAA+B,CAAC;QAEzE,uEAAuE;QACvE,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,IAAI,UAAU,EAAE,IAAI,EAAE,CAAC;gBACrB,SAAS,GAAG,UAAU,CAAC,IAAkC,CAAC;YAC5D,CAAC;iBAAM,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;gBAC1D,SAAS,GAAG,OAAO,CAAC;YACtB,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;YACpJ,OAAO,YAAY,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,UAAU,GAA4B;YAC1C,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,UAAU;YACf,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,MAAM;YACzB,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,GAAG,EAAE,CAAC;YACN,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,IAAI,OAAO,EAAE,QAAQ;YAAE,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC9D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAEzF,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,GAAG,2CAA2C,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QACrH,MAAM,YAAY,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,IAAI,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,YAAY,YAAY,EAAE,CAAC;QAEtE,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE;YACvG,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,YAAY,EAAE,MAAM;gBACpB,eAAe,EAAE,mBAAmB;aACrC;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAED,SAAS,YAAY,CAAC,IAAa,EAAE,MAAM,GAAG,GAAG;IAC/C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE;KACtF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,SAAiB;IAC5D,OAAO;;;oJAG2I,IAAI;;gBAExI,SAAS;;eAEV,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"email-login-handler.js","sourceRoot":"","sources":["../../src/handlers/email-login-handler.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,8 @@ export declare class FederationAdminHandler {
33
33
  private logger;
34
34
  constructor(options: FederationAdminHandlerOptions);
35
35
  fetch(request: Request, caller: CallerIdentity): Promise<Response | null>;
36
+ private persistMissingAppCredentials;
37
+ private deleteManagedAppCredentials;
36
38
  /**
37
39
  * Record a federation setting change as a federation.update audit log on the
38
40
  * current instance. Secrets (delegation JWT, app SK/PSK) must NEVER appear in
@@ -1 +1 @@
1
- {"version":3,"file":"federation-admin-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/federation-admin-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAYlD,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAuCD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,6BAA6B;IAQ5C,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA0E/E;;;;OAIG;YACW,oBAAoB;YAepB,aAAa;IAK3B,6FAA6F;YAC/E,sBAAsB;IAWpC,mFAAmF;IACnF,OAAO,CAAC,cAAc;YAaR,mBAAmB;IAsCjC;;;;OAIG;YACW,oBAAoB;YAyCpB,SAAS;YAIT,MAAM;IA+DpB;;OAEG;YACW,IAAI;IAiElB,4EAA4E;YAC9D,WAAW;IAgEzB,6CAA6C;YAC/B,UAAU;IAiCxB,2CAA2C;YAC7B,YAAY;YAsCZ,UAAU;IA8CxB,yEAAyE;YAC3D,UAAU;YA4CV,oBAAoB;YAsCpB,OAAO;YAoDP,KAAK;CAkCpB"}
1
+ {"version":3,"file":"federation-admin-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/federation-admin-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAclD,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAuCD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,6BAA6B;IAQ5C,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YA2EjE,4BAA4B;YAoC5B,2BAA2B;IAoBzC;;;;OAIG;YACW,oBAAoB;YAepB,aAAa;IAK3B,6FAA6F;YAC/E,sBAAsB;IAWpC,mFAAmF;IACnF,OAAO,CAAC,cAAc;YAaR,mBAAmB;IAsCjC;;;;OAIG;YACW,oBAAoB;YAyCpB,SAAS;YAIT,MAAM;IA8DpB;;OAEG;YACW,IAAI;IAkElB,4EAA4E;YAC9D,WAAW;IAiEzB,6CAA6C;YAC/B,UAAU;IAkCxB,2CAA2C;YAC7B,YAAY;YAuCZ,UAAU;IA+CxB,yEAAyE;YAC3D,UAAU;YA6CV,oBAAoB;YAuCpB,OAAO;YAsDP,KAAK;CAoCpB"}
@@ -15,11 +15,14 @@
15
15
  * POST /leave — leave federation (member)
16
16
  */
17
17
  import { signV2 } from "@arcblock/jwt";
18
- import { invalidateFedConfigCache } from "../blocklet-service.js";
18
+ import { invalidateConfigCache, invalidateFedConfigCache } from "../blocklet-service.js";
19
+ import { handlerError } from "../handler-errors.js";
19
20
  import { DELEGATION_EXPIRY_SECONDS, normalizeSecretKey, resolveWalletIdentity } from "../identity/wallet-identity.js";
21
+ import { detectLocale } from "../locale.js";
20
22
  import { consoleLogger } from "../logger.js";
21
23
  const FEDERATION_DELEGATION_CLAIMS = ["authPrincipal", "profile", "signature", "asset", "verifiableCredential"];
22
24
  const PREFIX = "/.well-known/service/api/team/admin/federation";
25
+ const MANAGED_APP_CREDENTIALS_KEY = "federation:managedAppCredentials";
23
26
  /** Extract origin from any URL-like string. Handles paths, trailing slashes, bare domains. */
24
27
  function normalizeOrigin(input) {
25
28
  let s = input.trim();
@@ -57,10 +60,11 @@ export class FederationAdminHandler {
57
60
  return null;
58
61
  const rest = url.pathname.slice(PREFIX.length) || "/";
59
62
  const method = request.method;
63
+ const locale = detectLocale(request);
60
64
  // All federation operations require admin+
61
65
  const isAdmin = caller.role === "owner" || caller.role === "admin";
62
66
  if (!isAdmin) {
63
- return jsonResponse({ error: "Admin access required" }, 403);
67
+ return jsonResponse({ error: handlerError("adminAccessRequired", locale) }, 403);
64
68
  }
65
69
  // Snapshot ip once; private methods read caller.ip via FederationCaller.
66
70
  const fedCaller = {
@@ -73,45 +77,95 @@ export class FederationAdminHandler {
73
77
  }
74
78
  if (rest === "/enable" && method === "POST") {
75
79
  const body = await request.json();
76
- return this.enable(body, fedCaller);
80
+ return this.enable(body, fedCaller, locale);
77
81
  }
78
82
  if (rest === "/join" && method === "POST") {
79
83
  const body = await request.json();
80
- return this.join(body, request, fedCaller);
84
+ return this.join(body, request, fedCaller, locale);
81
85
  }
82
86
  if (rest === "/toggle" && method === "PUT") {
83
87
  const body = await request.json();
84
- return this.toggleSelf(body, fedCaller);
88
+ return this.toggleSelf(body, fedCaller, locale);
85
89
  }
86
90
  // Site-specific routes: /sites/:did, /sites/:did/approve, /sites/:did/toggle
87
91
  const approveMatch = rest.match(/^\/sites\/([^/]+)\/approve$/);
88
92
  if (approveMatch && method === "POST") {
89
- return this.approveSite(decodeURIComponent(approveMatch[1]), fedCaller);
93
+ return this.approveSite(decodeURIComponent(approveMatch[1]), fedCaller, locale);
90
94
  }
91
95
  const siteToggleMatch = rest.match(/^\/sites\/([^/]+)\/toggle$/);
92
96
  if (siteToggleMatch && method === "PUT") {
93
97
  const body = await request.json();
94
- return this.toggleMember(decodeURIComponent(siteToggleMatch[1]), body, fedCaller);
98
+ return this.toggleMember(decodeURIComponent(siteToggleMatch[1]), body, fedCaller, locale);
95
99
  }
96
100
  const siteMatch = rest.match(/^\/sites\/([^/]+)$/);
97
101
  if (siteMatch && method === "PUT") {
98
102
  const body = (await request.json());
99
- return this.updateSite(decodeURIComponent(siteMatch[1]), body, fedCaller);
103
+ return this.updateSite(decodeURIComponent(siteMatch[1]), body, fedCaller, locale);
100
104
  }
101
105
  if (siteMatch && method === "DELETE") {
102
- return this.removeSite(decodeURIComponent(siteMatch[1]), fedCaller);
106
+ return this.removeSite(decodeURIComponent(siteMatch[1]), fedCaller, locale);
103
107
  }
104
108
  if (rest === "/delegation" && method === "POST") {
105
- return this.regenerateDelegation(fedCaller);
109
+ return this.regenerateDelegation(fedCaller, locale);
106
110
  }
107
111
  if (rest === "/disband" && method === "POST") {
108
- return this.disband(fedCaller);
112
+ return this.disband(fedCaller, locale);
109
113
  }
110
114
  if (rest === "/leave" && method === "POST") {
111
- return this.leave(fedCaller);
115
+ return this.leave(fedCaller, locale);
112
116
  }
113
117
  return null;
114
118
  }
119
+ async persistMissingAppCredentials(callerDid) {
120
+ const [existingSk, existingPsk] = await Promise.all([
121
+ this.store.getSetting(this.instanceDid, "app:sk"),
122
+ this.store.getSetting(this.instanceDid, "app:psk"),
123
+ ]);
124
+ // The host PSK may only be paired with the HOST SK. Writing it next to a
125
+ // tenant's OWN app:sk would re-point that tenant's DID-Connect issuer at the
126
+ // host's permanent identity — the same DID drift this method exists to
127
+ // prevent, just in the opposite direction (every wallet user of that tenant
128
+ // would get a new DID on next login). Same predicate resolveConfig() uses
129
+ // before falling back to the deployment PSK.
130
+ const skIsHostKey = !existingSk || normalizeSecretKey(existingSk) === normalizeSecretKey(this.appSk);
131
+ const managedKeys = [];
132
+ if (!existingSk)
133
+ managedKeys.push("app:sk");
134
+ if (this.appPsk && !existingPsk && skIsHostKey)
135
+ managedKeys.push("app:psk");
136
+ if (managedKeys.length === 0)
137
+ return;
138
+ // Record ownership before the writes so a later disband can safely remove
139
+ // only credentials created by federation, never pre-existing tenant keys.
140
+ await this.store.setSetting(this.instanceDid, MANAGED_APP_CREDENTIALS_KEY, JSON.stringify(managedKeys), callerDid);
141
+ if (managedKeys.includes("app:sk")) {
142
+ await this.store.setSetting(this.instanceDid, "app:sk", normalizeSecretKey(this.appSk), callerDid);
143
+ }
144
+ if (managedKeys.includes("app:psk") && this.appPsk) {
145
+ await this.store.setSetting(this.instanceDid, "app:psk", normalizeSecretKey(this.appPsk), callerDid);
146
+ }
147
+ invalidateConfigCache(this.instanceDid);
148
+ }
149
+ async deleteManagedAppCredentials(instanceDid) {
150
+ const raw = await this.store.getSetting(instanceDid, MANAGED_APP_CREDENTIALS_KEY);
151
+ if (!raw)
152
+ return;
153
+ let managedKeys = [];
154
+ try {
155
+ const parsed = JSON.parse(raw);
156
+ if (Array.isArray(parsed)) {
157
+ managedKeys = parsed.filter((key) => key === "app:sk" || key === "app:psk");
158
+ }
159
+ }
160
+ catch {
161
+ // An invalid ownership marker must never authorize secret deletion.
162
+ }
163
+ for (const key of managedKeys) {
164
+ await this.store.deleteSetting(instanceDid, key);
165
+ }
166
+ await this.store.deleteSetting(instanceDid, MANAGED_APP_CREDENTIALS_KEY);
167
+ invalidateConfigCache(instanceDid);
168
+ }
115
169
  /**
116
170
  * Record a federation setting change as a federation.update audit log on the
117
171
  * current instance. Secrets (delegation JWT, app SK/PSK) must NEVER appear in
@@ -238,11 +292,11 @@ export class FederationAdminHandler {
238
292
  async getStatus() {
239
293
  return jsonResponse(await this.buildStatusResponse());
240
294
  }
241
- async enable(body, caller) {
295
+ async enable(body, caller, locale) {
242
296
  // Check if already in a federation
243
297
  const existingRole = await this.store.getSetting(this.instanceDid, "federation:role");
244
298
  if (existingRole) {
245
- return jsonResponse({ error: "Already in a federation. Leave or disband first." }, 409);
299
+ return jsonResponse({ error: handlerError("alreadyInFederationLeaveOrDisband", locale) }, 409);
246
300
  }
247
301
  const masterUrl = body.url ? normalizeOrigin(body.url) : "";
248
302
  const name = body.name ?? "";
@@ -250,11 +304,9 @@ export class FederationAdminHandler {
250
304
  await this.store.setSetting(this.instanceDid, "federation:role", "master", caller.did);
251
305
  await this.store.setSetting(this.instanceDid, "federation:enabled", "true", caller.did);
252
306
  await this.store.setSetting(this.instanceDid, "federation:groupId", this.instanceDid, caller.did);
253
- // Persist Master's SK to D1 so member sites can read it for DID derivation.
254
- const existingSk = await this.store.getSetting(this.instanceDid, "app:sk");
255
- if (!existingSk) {
256
- await this.store.setSetting(this.instanceDid, "app:sk", normalizeSecretKey(this.appSk), caller.did);
257
- }
307
+ // Persist the host SK/PSK pair so enabling federation cannot change the
308
+ // wallet-facing identity. Ownership is tracked for safe cleanup later.
309
+ await this.persistMissingAppCredentials(caller.did);
258
310
  const groupScope = `federation:group:${this.instanceDid}`;
259
311
  // Generate federation delegation
260
312
  const identity = resolveWalletIdentity(this.appSk, this.appPsk);
@@ -286,24 +338,24 @@ export class FederationAdminHandler {
286
338
  /**
287
339
  * Sub-site initiates join request. Finds master by URL, writes pending entry.
288
340
  */
289
- async join(body, request, caller) {
341
+ async join(body, request, caller, locale) {
290
342
  if (!body.masterUrl) {
291
- return jsonResponse({ error: "masterUrl is required" }, 400);
343
+ return jsonResponse({ error: handlerError("masterUrlRequired", locale) }, 400);
292
344
  }
293
345
  // Check if already in a federation
294
346
  const existingRole = await this.store.getSetting(this.instanceDid, "federation:role");
295
347
  if (existingRole) {
296
- return jsonResponse({ error: "Already in a federation. Leave first." }, 409);
348
+ return jsonResponse({ error: handlerError("alreadyInFederationLeaveFirst", locale) }, 409);
297
349
  }
298
350
  // Find the master group by URL (handles member-URL transparent redirect)
299
351
  const group = await this.findMasterGroupByUrl(body.masterUrl);
300
352
  if (!group) {
301
- return jsonResponse({ error: "Target site has not enabled federation" }, 400);
353
+ return jsonResponse({ error: handlerError("targetNotEnabledFederation", locale) }, 400);
302
354
  }
303
355
  // Check this site isn't already in the group
304
356
  const existingSite = await this.store.getSetting(group.groupScope, `site:${this.instanceDid}`);
305
357
  if (existingSite) {
306
- return jsonResponse({ error: "Already in this federation group" }, 409);
358
+ return jsonResponse({ error: handlerError("alreadyInThisGroup", locale) }, 409);
307
359
  }
308
360
  // Derive sub-site's URL from request origin and name from D1 branding
309
361
  const siteUrl = new URL(request.url).origin;
@@ -336,22 +388,22 @@ export class FederationAdminHandler {
336
388
  return jsonResponse(await this.buildStatusResponse());
337
389
  }
338
390
  /** Master approves a pending member. Generates delegation and activates. */
339
- async approveSite(did, caller) {
391
+ async approveSite(did, caller, locale) {
340
392
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
341
393
  if (role !== "master") {
342
- return jsonResponse({ error: "Only master can approve sites" }, 403);
394
+ return jsonResponse({ error: handlerError("onlyMasterCanApprove", locale) }, 403);
343
395
  }
344
396
  const groupScope = await this.getGroupScope();
345
397
  if (!groupScope) {
346
- return jsonResponse({ error: "Federation not configured" }, 400);
398
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
347
399
  }
348
400
  const siteRaw = await this.store.getSetting(groupScope, `site:${did}`);
349
401
  if (!siteRaw) {
350
- return jsonResponse({ error: "Site not found" }, 404);
402
+ return jsonResponse({ error: handlerError("siteNotFound", locale) }, 404);
351
403
  }
352
404
  const site = JSON.parse(siteRaw);
353
405
  if (site.status !== "pending") {
354
- return jsonResponse({ error: "Site is not in pending state" }, 400);
406
+ return jsonResponse({ error: handlerError("siteNotPending", locale) }, 400);
355
407
  }
356
408
  // Generate per-member delegation
357
409
  const masterSk = await this.store.getSetting(this.instanceDid, "app:sk");
@@ -390,10 +442,10 @@ export class FederationAdminHandler {
390
442
  return jsonResponse(await this.buildStatusResponse());
391
443
  }
392
444
  /** Member self-toggles federation on/off. */
393
- async toggleSelf(body, caller) {
445
+ async toggleSelf(body, caller, locale) {
394
446
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
395
447
  if (role !== "member") {
396
- return jsonResponse({ error: "Toggle is only available for member sites" }, 400);
448
+ return jsonResponse({ error: handlerError("toggleOnlyForMembers", locale) }, 400);
397
449
  }
398
450
  const enabledStr = body.enabled ? "true" : "false";
399
451
  await this.store.setSetting(this.instanceDid, "federation:enabled", enabledStr, caller.did);
@@ -416,19 +468,19 @@ export class FederationAdminHandler {
416
468
  return jsonResponse(await this.buildStatusResponse());
417
469
  }
418
470
  /** Master toggles a member site on/off. */
419
- async toggleMember(did, body, caller) {
471
+ async toggleMember(did, body, caller, locale) {
420
472
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
421
473
  if (role !== "master") {
422
- return jsonResponse({ error: "Only master can toggle member sites" }, 403);
474
+ return jsonResponse({ error: handlerError("onlyMasterCanToggle", locale) }, 403);
423
475
  }
424
476
  // Verify the site exists and is approved
425
477
  const groupScope = await this.getGroupScope();
426
478
  if (!groupScope) {
427
- return jsonResponse({ error: "Federation not configured" }, 400);
479
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
428
480
  }
429
481
  const siteRaw = await this.store.getSetting(groupScope, `site:${did}`);
430
482
  if (!siteRaw) {
431
- return jsonResponse({ error: "Site not found" }, 404);
483
+ return jsonResponse({ error: handlerError("siteNotFound", locale) }, 404);
432
484
  }
433
485
  const enabledStr = body.enabled ? "true" : "false";
434
486
  await this.store.setSetting(did, "federation:enabled", enabledStr, caller.did);
@@ -444,18 +496,18 @@ export class FederationAdminHandler {
444
496
  });
445
497
  return jsonResponse(await this.buildStatusResponse());
446
498
  }
447
- async updateSite(did, body, caller) {
499
+ async updateSite(did, body, caller, locale) {
448
500
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
449
501
  if (role !== "master") {
450
- return jsonResponse({ error: "Only master can update sites" }, 403);
502
+ return jsonResponse({ error: handlerError("onlyMasterCanUpdate", locale) }, 403);
451
503
  }
452
504
  const groupScope = await this.getGroupScope();
453
505
  if (!groupScope) {
454
- return jsonResponse({ error: "Federation not configured" }, 400);
506
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
455
507
  }
456
508
  const existing = await this.store.getSetting(groupScope, `site:${did}`);
457
509
  if (!existing) {
458
- return jsonResponse({ error: "Site not found" }, 404);
510
+ return jsonResponse({ error: handlerError("siteNotFound", locale) }, 404);
459
511
  }
460
512
  const site = JSON.parse(existing);
461
513
  const changes = {};
@@ -479,17 +531,17 @@ export class FederationAdminHandler {
479
531
  return jsonResponse(await this.buildStatusResponse());
480
532
  }
481
533
  /** Remove a site (master rejects pending or removes approved member). */
482
- async removeSite(did, caller) {
534
+ async removeSite(did, caller, locale) {
483
535
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
484
536
  if (role !== "master") {
485
- return jsonResponse({ error: "Only master can remove sites" }, 403);
537
+ return jsonResponse({ error: handlerError("onlyMasterCanRemove", locale) }, 403);
486
538
  }
487
539
  if (did === this.instanceDid) {
488
- return jsonResponse({ error: "Cannot remove master site. Use disband instead." }, 400);
540
+ return jsonResponse({ error: handlerError("cannotRemoveMaster", locale) }, 400);
489
541
  }
490
542
  const groupScope = await this.getGroupScope();
491
543
  if (!groupScope) {
492
- return jsonResponse({ error: "Federation not configured" }, 400);
544
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
493
545
  }
494
546
  // Purge tickets
495
547
  const siteValue = await this.store.getSetting(groupScope, `site:${did}`);
@@ -512,14 +564,14 @@ export class FederationAdminHandler {
512
564
  invalidateFedConfigCache(did);
513
565
  return jsonResponse(await this.buildStatusResponse());
514
566
  }
515
- async regenerateDelegation(caller) {
567
+ async regenerateDelegation(caller, locale) {
516
568
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
517
569
  if (role !== "master") {
518
- return jsonResponse({ error: "Only master can regenerate delegation" }, 403);
570
+ return jsonResponse({ error: handlerError("onlyMasterCanRegenerate", locale) }, 403);
519
571
  }
520
572
  const groupScope = await this.getGroupScope();
521
573
  if (!groupScope) {
522
- return jsonResponse({ error: "Federation not configured" }, 400);
574
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
523
575
  }
524
576
  const identity = resolveWalletIdentity(this.appSk, this.appPsk);
525
577
  const signerAddress = identity.permanentWallet.address;
@@ -542,19 +594,20 @@ export class FederationAdminHandler {
542
594
  });
543
595
  return jsonResponse(await this.buildStatusResponse());
544
596
  }
545
- async disband(caller) {
597
+ async disband(caller, locale) {
546
598
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
547
599
  if (role !== "master") {
548
- return jsonResponse({ error: "Only master can disband federation" }, 403);
600
+ return jsonResponse({ error: handlerError("onlyMasterCanDisband", locale) }, 403);
549
601
  }
550
602
  const groupScope = await this.getGroupScope();
551
603
  if (!groupScope) {
552
- return jsonResponse({ error: "Federation not configured" }, 400);
604
+ return jsonResponse({ error: handlerError("federationNotConfigured", locale) }, 400);
553
605
  }
554
606
  const siteRows = await this.store.listSettingsByPrefix(groupScope, "site:");
555
607
  // Clean up instance-level settings for all sites
556
608
  for (const row of siteRows) {
557
609
  const siteDid = row.key.slice("site:".length);
610
+ await this.deleteManagedAppCredentials(siteDid);
558
611
  await this.store.deleteSetting(siteDid, "federation:role");
559
612
  await this.store.deleteSetting(siteDid, "federation:enabled");
560
613
  await this.store.deleteSetting(siteDid, "federation:groupId");
@@ -587,10 +640,10 @@ export class FederationAdminHandler {
587
640
  });
588
641
  return jsonResponse(await this.buildStatusResponse());
589
642
  }
590
- async leave(caller) {
643
+ async leave(caller, locale) {
591
644
  const role = await this.store.getSetting(this.instanceDid, "federation:role");
592
645
  if (role !== "member") {
593
- return jsonResponse({ error: "Only members can leave federation" }, 400);
646
+ return jsonResponse({ error: handlerError("onlyMembersCanLeave", locale) }, 400);
594
647
  }
595
648
  const groupScope = await this.getGroupScope();
596
649
  if (groupScope) {
@@ -607,6 +660,7 @@ export class FederationAdminHandler {
607
660
  await this.store.deleteSetting(this.instanceDid, "federation:role");
608
661
  await this.store.deleteSetting(this.instanceDid, "federation:enabled");
609
662
  await this.store.deleteSetting(this.instanceDid, "federation:groupId");
663
+ await this.deleteManagedAppCredentials(this.instanceDid);
610
664
  await this.writeFederationAudit(caller, {
611
665
  "federation:role": null,
612
666
  "federation:enabled": null,