@geminixiang/mikan 0.4.8 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +13 -13
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +9 -6
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +22 -22
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +6 -6
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +3 -3
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/types.d.ts +2 -2
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/intake.d.ts +2 -2
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +4 -4
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/shared.d.ts +3 -3
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +2 -2
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +10 -7
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +46 -46
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +6 -6
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +2 -2
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts +6 -6
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +3 -3
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/tools/attach.d.ts.map +1 -1
- package/dist/adapters/slack/tools/block-kit.d.ts.map +1 -1
- package/dist/adapters/slack/types.d.ts +1 -1
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/streaming.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +10 -7
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +21 -21
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +6 -6
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +3 -3
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/html.d.ts.map +1 -1
- package/dist/adapters/telegram/types.d.ts +2 -2
- package/dist/adapters/telegram/types.d.ts.map +1 -1
- package/dist/adapters/telegram/types.js.map +1 -1
- package/dist/adapters/types.d.ts +6 -6
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent-events.d.ts +5 -0
- package/dist/agent-events.d.ts.map +1 -0
- package/dist/agent-events.js +26 -0
- package/dist/agent-events.js.map +1 -0
- package/dist/agent.d.ts +7 -7
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +84 -41
- package/dist/agent.js.map +1 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +1 -1
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +3 -3
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +5 -5
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +2 -2
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/parse.d.ts.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +5 -5
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +1 -1
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +5 -5
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/utils.d.ts +3 -3
- package/dist/commands/utils.d.ts.map +1 -1
- package/dist/commands/utils.js +6 -6
- package/dist/commands/utils.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/download.d.ts.map +1 -1
- package/dist/events.d.ts +2 -2
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +35 -27
- package/dist/main.js.map +1 -1
- package/dist/model-registry.d.ts.map +1 -1
- package/dist/observability/instrument.d.ts.map +1 -1
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +27 -9
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/platform-messages.d.ts +2 -2
- package/dist/platform-messages.d.ts.map +1 -1
- package/dist/platform-messages.js +2 -2
- package/dist/platform-messages.js.map +1 -1
- package/dist/portal-shell.d.ts.map +1 -1
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/runtime/{conversation-orchestrator.d.ts → agent-run-controller.d.ts} +5 -5
- package/dist/runtime/agent-run-controller.d.ts.map +1 -0
- package/dist/runtime/{conversation-orchestrator.js → agent-run-controller.js} +17 -17
- package/dist/runtime/agent-run-controller.js.map +1 -0
- package/dist/runtime/conversation-runtime.d.ts +4 -0
- package/dist/runtime/conversation-runtime.d.ts.map +1 -0
- package/dist/runtime/{session-runtime.js → conversation-runtime.js} +12 -12
- package/dist/runtime/conversation-runtime.js.map +1 -0
- package/dist/runtime/types.d.ts +9 -9
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/errors.d.ts.map +1 -1
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/image.d.ts.map +1 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/path-context.d.ts.map +1 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sessions/{chat-session-manager.d.ts → agent-memory-file-manager.d.ts} +6 -6
- package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -0
- package/dist/sessions/{chat-session-manager.js → agent-memory-file-manager.js} +16 -16
- package/dist/sessions/agent-memory-file-manager.js.map +1 -0
- package/dist/sessions/metadata.d.ts.map +1 -1
- package/dist/sessions/policy.d.ts.map +1 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +4 -4
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +3 -3
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/store.d.ts +3 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +1 -1
- package/dist/store.js.map +1 -1
- package/dist/tool-diagnostics.d.ts.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/truncate.d.ts.map +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/trigger.d.ts +2 -2
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +1 -1
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +47 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/date.d.ts +1 -1
- package/dist/utils/date.d.ts.map +1 -1
- package/dist/utils/date.js +1 -1
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/file-guards.d.ts.map +1 -1
- package/dist/utils/fs-atomic.d.ts.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/http-body.d.ts.map +1 -1
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/routing.d.ts.map +1 -1
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +1 -1
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/provider-models.d.ts.map +1 -1
- package/dist/web/admin/store.d.ts.map +1 -1
- package/dist/web/admin/types.d.ts +1 -1
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/agent-events/portal.d.ts +3 -0
- package/dist/web/agent-events/portal.d.ts.map +1 -0
- package/dist/web/agent-events/portal.js +18 -0
- package/dist/web/agent-events/portal.js.map +1 -0
- package/dist/web/login/oauth.d.ts.map +1 -1
- package/dist/web/login/oauth.js.map +1 -1
- package/dist/web/login/portal.d.ts +2 -14
- package/dist/web/login/portal.d.ts.map +1 -1
- package/dist/web/login/portal.js +53 -130
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/login/store.d.ts.map +1 -1
- package/dist/web/login/types.d.ts.map +1 -1
- package/dist/web/request.d.ts +3 -0
- package/dist/web/request.d.ts.map +1 -0
- package/dist/web/request.js +13 -0
- package/dist/web/request.js.map +1 -0
- package/dist/web/server.d.ts +28 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +66 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/session-view/command.d.ts.map +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +8 -8
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/store.d.ts.map +1 -1
- package/dist/web/session-view/types.d.ts +4 -4
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/dist/web/token-store.d.ts.map +1 -1
- package/dist/web/types.d.ts.map +1 -1
- package/package.json +44 -20
- package/dist/runtime/conversation-orchestrator.d.ts.map +0 -1
- package/dist/runtime/conversation-orchestrator.js.map +0 -1
- package/dist/runtime/session-runtime.d.ts +0 -4
- package/dist/runtime/session-runtime.d.ts.map +0 -1
- package/dist/runtime/session-runtime.js.map +0 -1
- package/dist/sessions/chat-session-manager.d.ts.map +0 -1
- package/dist/sessions/chat-session-manager.js.map +0 -1
package/dist/web/login/portal.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "crypto";
|
|
2
|
-
import { createServer } from "http";
|
|
3
|
-
import { handleAdminRequest } from "../admin/portal.js";
|
|
4
2
|
import { escapeHtml } from "../../utils/html.js";
|
|
5
3
|
import { readRawBody } from "../../utils/http-body.js";
|
|
6
4
|
import { renderPortalShell } from "../../portal-shell.js";
|
|
7
5
|
import { resolveLinkBaseUrl } from "../../config.js";
|
|
8
|
-
import {
|
|
6
|
+
import { requestBaseUrl } from "../request.js";
|
|
9
7
|
import { getOAuthServices, resolveOAuthService, } from "./oauth.js";
|
|
10
8
|
import * as log from "../../log.js";
|
|
11
9
|
import { reportUserFacingError } from "../../observability/sentry.js";
|
|
@@ -178,7 +176,7 @@ const SECRET_PRESETS = [
|
|
|
178
176
|
],
|
|
179
177
|
},
|
|
180
178
|
];
|
|
181
|
-
// ──
|
|
179
|
+
// ── request handler ───────────────────────────────────────────────────────────
|
|
182
180
|
/**
|
|
183
181
|
* Start a small HTTP server that receives credential onboarding callbacks from the web portal.
|
|
184
182
|
*
|
|
@@ -189,137 +187,62 @@ const SECRET_PRESETS = [
|
|
|
189
187
|
* POST /api/oauth/start — creates provider OAuth redirect URL
|
|
190
188
|
* GET /oauth/callback — OAuth callback endpoint
|
|
191
189
|
*/
|
|
192
|
-
export function
|
|
190
|
+
export function createLoginRequestHandler(linkTokenStore, vaultManager, notify) {
|
|
193
191
|
const oauthStates = new Map();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
res.
|
|
200
|
-
|
|
192
|
+
return (req, res, url) => {
|
|
193
|
+
if (req.method === "GET" && url.pathname === "/link") {
|
|
194
|
+
const rawToken = url.searchParams.get("token") ?? "";
|
|
195
|
+
const linkToken = linkTokenStore.peek(rawToken);
|
|
196
|
+
if (!linkToken) {
|
|
197
|
+
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
198
|
+
res.end(renderErrorPage("This link is invalid or has expired. Ask the bot for a new /login link."));
|
|
199
|
+
return true;
|
|
201
200
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
})) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
if (await handleSessionViewRequest(req, res, url, sessionViewTokenStore, sessionViewInteractive)) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
if (req.method === "GET" && url.pathname === "/link") {
|
|
220
|
-
const rawToken = url.searchParams.get("token") ?? "";
|
|
221
|
-
const linkToken = linkTokenStore.peek(rawToken);
|
|
222
|
-
if (!linkToken) {
|
|
223
|
-
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
224
|
-
res.end(renderErrorPage("This link is invalid or has expired. Ask the bot for a new /login link."));
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
const oauthServiceHint = linkToken.providerId
|
|
228
|
-
? resolveOAuthService(linkToken.providerId)
|
|
229
|
-
: undefined;
|
|
230
|
-
const oauthServices = getOAuthServices();
|
|
231
|
-
const defaultMode = oauthServiceHint ? "oauth" : "api_key";
|
|
232
|
-
const existingSecrets = describeVaultSecrets(vaultManager, linkToken.vaultId);
|
|
233
|
-
const title = oauthServiceHint ? `${oauthServiceHint.label} OAuth` : "Store Secret";
|
|
234
|
-
const helpText = oauthServiceHint
|
|
235
|
-
? `Authorize ${oauthServiceHint.label} and store tokens in your vault.`
|
|
236
|
-
: "Set any environment variable key/value pair in your vault.";
|
|
237
|
-
const secretLabel = "Secret value";
|
|
238
|
-
const placeholder = "sk-...";
|
|
239
|
-
const initialEnvKey = "";
|
|
240
|
-
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
241
|
-
res.end(renderCredentialPage(rawToken, title, defaultMode, initialEnvKey, secretLabel, placeholder, helpText, oauthServices, oauthServiceHint?.id, existingSecrets));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
if (req.method === "POST" && url.pathname === "/api/link/complete") {
|
|
245
|
-
if (!enforceCsrf(req, res))
|
|
246
|
-
return;
|
|
247
|
-
void readJsonBody(req, res, async (body) => {
|
|
248
|
-
await handleLinkComplete(body, linkTokenStore, vaultManager, notify, res);
|
|
249
|
-
});
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (req.method === "POST" && url.pathname === "/api/oauth/start") {
|
|
253
|
-
if (!enforceCsrf(req, res))
|
|
254
|
-
return;
|
|
255
|
-
void readJsonBody(req, res, async (body) => {
|
|
256
|
-
await handleOAuthStart(body, req, linkTokenStore, oauthStates, res);
|
|
257
|
-
});
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
if (req.method === "GET" && url.pathname === "/oauth/callback") {
|
|
261
|
-
void handleOAuthCallback(url, req, linkTokenStore, vaultManager, notify, oauthStates, res).catch((err) => {
|
|
262
|
-
log.logWarning("OAuth callback failed", err.message);
|
|
263
|
-
reportUserFacingError(err, {
|
|
264
|
-
domain: "login",
|
|
265
|
-
surface: "oauth",
|
|
266
|
-
operation: "oauth_callback",
|
|
267
|
-
severity: "error",
|
|
268
|
-
context: { route: "/oauth/callback" },
|
|
269
|
-
});
|
|
270
|
-
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
271
|
-
res.end(renderErrorPage("OAuth callback failed. Please retry /login."));
|
|
272
|
-
});
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
res.writeHead(404);
|
|
276
|
-
res.end();
|
|
201
|
+
const oauthServiceHint = linkToken.providerId
|
|
202
|
+
? resolveOAuthService(linkToken.providerId)
|
|
203
|
+
: undefined;
|
|
204
|
+
const oauthServices = getOAuthServices();
|
|
205
|
+
const defaultMode = oauthServiceHint ? "oauth" : "api_key";
|
|
206
|
+
const existingSecrets = describeVaultSecrets(vaultManager, linkToken.vaultId);
|
|
207
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
208
|
+
res.end(renderCredentialPage(rawToken, oauthServiceHint ? `${oauthServiceHint.label} OAuth` : "Store Secret", defaultMode, "", "Secret value", "sk-...", oauthServiceHint
|
|
209
|
+
? `Authorize ${oauthServiceHint.label} and store tokens in your vault.`
|
|
210
|
+
: "Set any environment variable key/value pair in your vault.", oauthServices, oauthServiceHint?.id, existingSecrets));
|
|
211
|
+
return true;
|
|
277
212
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
213
|
+
if (req.method === "POST" && url.pathname === "/api/link/complete") {
|
|
214
|
+
if (!enforceCsrf(req, res))
|
|
215
|
+
return true;
|
|
216
|
+
void readJsonBody(req, res, async (body) => {
|
|
217
|
+
await handleLinkComplete(body, linkTokenStore, vaultManager, notify, res);
|
|
218
|
+
});
|
|
219
|
+
return true;
|
|
284
220
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
log.logInfo(`Link callback server listening on ${bindHost ?? "0.0.0.0"}:${port}`);
|
|
293
|
-
if (!resolveLinkBaseUrl()) {
|
|
294
|
-
log.logWarning("MIKAN_LINK_URL is not set — bound to 127.0.0.1 and OAuth redirect_uri will be " +
|
|
295
|
-
"derived from request headers (Host / X-Forwarded-*). Set " +
|
|
296
|
-
"MIKAN_LINK_URL=https://your-host.example.com for production.");
|
|
221
|
+
if (req.method === "POST" && url.pathname === "/api/oauth/start") {
|
|
222
|
+
if (!enforceCsrf(req, res))
|
|
223
|
+
return true;
|
|
224
|
+
void readJsonBody(req, res, async (body) => {
|
|
225
|
+
await handleOAuthStart(body, req, linkTokenStore, oauthStates, res);
|
|
226
|
+
});
|
|
227
|
+
return true;
|
|
297
228
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return configured;
|
|
316
|
-
const protoRaw = req.headers["x-forwarded-proto"]?.split(",")[0]?.trim();
|
|
317
|
-
const proto = protoRaw || "http";
|
|
318
|
-
const host = (req.headers["x-forwarded-host"]?.split(",")[0]?.trim() ??
|
|
319
|
-
req.headers.host ??
|
|
320
|
-
`localhost`) ||
|
|
321
|
-
`localhost`;
|
|
322
|
-
return `${proto}://${host}`;
|
|
229
|
+
if (req.method === "GET" && url.pathname === "/oauth/callback") {
|
|
230
|
+
void handleOAuthCallback(url, req, linkTokenStore, vaultManager, notify, oauthStates, res).catch((err) => {
|
|
231
|
+
log.logWarning("OAuth callback failed", err.message);
|
|
232
|
+
reportUserFacingError(err, {
|
|
233
|
+
domain: "login",
|
|
234
|
+
surface: "oauth",
|
|
235
|
+
operation: "oauth_callback",
|
|
236
|
+
severity: "error",
|
|
237
|
+
context: { route: "/oauth/callback" },
|
|
238
|
+
});
|
|
239
|
+
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
240
|
+
res.end(renderErrorPage("OAuth callback failed. Please retry /login."));
|
|
241
|
+
});
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
};
|
|
323
246
|
}
|
|
324
247
|
/**
|
|
325
248
|
* Block cross-site POSTs to the credential endpoints. Two defenses:
|