@standardagents/builder 0.23.0 → 0.24.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.
@@ -64307,14 +64307,13 @@ async function getPlatformIdentity(env2) {
64307
64307
  platformEndpoint: endpoint
64308
64308
  };
64309
64309
  }
64310
- async function mintLocalSessionForPlatformUser(env2, platformUser) {
64310
+ async function upsertReplicaUserForPlatformProfile(env2, profile) {
64311
64311
  const namespace = env2.AGENT_BUILDER;
64312
64312
  if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
64313
64313
  throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
64314
64314
  }
64315
64315
  const agentBuilder = namespace.get(namespace.idFromName("singleton"));
64316
- const profile = typeof platformUser === "string" ? { platform_user_id: platformUser, username: `sa-${platformUser.slice(0, 12)}`, role: "admin" } : platformUser;
64317
- const user = await agentBuilder.upsertPlatformReplicaUser({
64316
+ return await agentBuilder.upsertPlatformReplicaUser({
64318
64317
  platform_user_id: profile.platform_user_id,
64319
64318
  username: profile.username ?? null,
64320
64319
  display_name: profile.display_name ?? null,
@@ -64323,6 +64322,15 @@ async function mintLocalSessionForPlatformUser(env2, platformUser) {
64323
64322
  role: profile.role ?? "admin",
64324
64323
  permissions: profile.permissions ?? null
64325
64324
  });
64325
+ }
64326
+ async function mintLocalSessionForPlatformUser(env2, platformUser) {
64327
+ const namespace = env2.AGENT_BUILDER;
64328
+ if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
64329
+ throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
64330
+ }
64331
+ const agentBuilder = namespace.get(namespace.idFromName("singleton"));
64332
+ const profile = typeof platformUser === "string" ? { platform_user_id: platformUser, username: `sa-${platformUser.slice(0, 12)}`, role: "admin" } : platformUser;
64333
+ const user = await upsertReplicaUserForPlatformProfile(env2, profile);
64326
64334
  if (user.role === "api") {
64327
64335
  throw new Error("This account has API-only access. Use an API key instead of signing in.");
64328
64336
  }
@@ -70111,9 +70119,11 @@ var start_post_default = defineController2(async ({ req, env: env2 }) => {
70111
70119
  const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
70112
70120
  await agentBuilder.startDeviceLogin(await hashToken(code));
70113
70121
  const origin = new URL(req.url).origin;
70122
+ const verifyBaseRaw = env2.STANDARD_AGENTS_DEVICE_VERIFY_URL_BASE;
70123
+ const verifyBase = typeof verifyBaseRaw === "string" ? verifyBaseRaw.trim().replace(/\/+$/, "") : "";
70114
70124
  return Response.json({
70115
70125
  code,
70116
- verify_url: `${origin}/api/auth/device/${code}/approve`,
70126
+ verify_url: verifyBase ? `${verifyBase}/${code}` : `${origin}/api/auth/device/${code}/approve`,
70117
70127
  poll_url: `${origin}/api/auth/device/${code}`,
70118
70128
  interval: 2,
70119
70129
  expires_in: 600
@@ -70169,6 +70179,15 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
70169
70179
  return failRedirect(req, env2, "forbidden");
70170
70180
  }
70171
70181
  if (payload.role === "api") {
70182
+ const apiReturnTo = safeReturnTo2(url.searchParams.get("return_to"));
70183
+ if (/^\/api\/auth\/device\/[A-Za-z0-9]{8,64}\/approve$/.test(apiReturnTo)) {
70184
+ return new Response(null, {
70185
+ status: 302,
70186
+ headers: {
70187
+ Location: `${url.origin}${apiReturnTo}?handoff=${encodeURIComponent(handoff)}`
70188
+ }
70189
+ });
70190
+ }
70172
70191
  return failRedirect(req, env2, "api_only_account");
70173
70192
  }
70174
70193
  const session = await mintLocalSessionForPlatformUser(env2, {
@@ -70282,23 +70301,49 @@ function page(title, body, ok) {
70282
70301
  var approve_get_default = defineController2(async ({ req, env: env2, params }) => {
70283
70302
  const code = params.code;
70284
70303
  if (!code) return page("Missing code", "This device link is malformed.", false);
70285
- const authResult = await requireAuth(req, env2);
70286
- if (authResult instanceof Response) {
70287
- const url = new URL(req.url);
70288
- const returnTo = encodeURIComponent(url.pathname);
70289
- const hosted = Boolean(env2.STANDARD_AGENTS_HOSTED && String(env2.STANDARD_AGENTS_HOSTED) !== "0" && String(env2.STANDARD_AGENTS_HOSTED).toLowerCase() !== "false");
70290
- const target = hosted ? `/api/auth/sa/start?return_to=${returnTo}` : `/login?return_to=${returnTo}`;
70291
- return new Response(null, { status: 302, headers: { Location: `${url.origin}${target}` } });
70292
- }
70293
- if (authResult.authType === "api_key") {
70294
- return page("Sign in required", "Device logins must be approved from a signed-in browser session.", false);
70304
+ const url = new URL(req.url);
70305
+ let approvingUserId = null;
70306
+ const handoff = url.searchParams.get("handoff");
70307
+ if (handoff && isPlatformHosted(env2)) {
70308
+ const configuredProjectId = typeof env2.STANDARD_AGENTS_PROJECT_ID === "string" ? env2.STANDARD_AGENTS_PROJECT_ID : void 0;
70309
+ const payload = await verifyPlatformSignedPayload(
70310
+ handoff,
70311
+ env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY_JWK ?? env2.STANDARD_AGENTS_AUTH_PUBLIC_KEY,
70312
+ { kind: "instance_handoff", projectId: configuredProjectId }
70313
+ );
70314
+ const projectOk = payload && (configuredProjectId || payload.project_id === hostedInstanceRedirectId(req, env2));
70315
+ if (!payload || !payload.platform_user_id || !payload.role || !projectOk) {
70316
+ return page("Sign in failed", "This sign-in link is invalid or has expired. Start again from your terminal.", false);
70317
+ }
70318
+ const user = await upsertReplicaUserForPlatformProfile(env2, {
70319
+ platform_user_id: payload.platform_user_id,
70320
+ username: payload.username ?? null,
70321
+ display_name: payload.display_name ?? null,
70322
+ email: payload.email ?? null,
70323
+ avatar_url: payload.avatar_url ?? null,
70324
+ role: payload.role,
70325
+ permissions: payload.permissions ?? null
70326
+ });
70327
+ approvingUserId = user.id;
70328
+ } else {
70329
+ const authResult = await requireAuth(req, env2);
70330
+ if (authResult instanceof Response) {
70331
+ const returnTo = encodeURIComponent(url.pathname);
70332
+ const hosted = Boolean(env2.STANDARD_AGENTS_HOSTED && String(env2.STANDARD_AGENTS_HOSTED) !== "0" && String(env2.STANDARD_AGENTS_HOSTED).toLowerCase() !== "false");
70333
+ const target = hosted ? `/api/auth/sa/start?return_to=${returnTo}` : `/login?return_to=${returnTo}`;
70334
+ return new Response(null, { status: 302, headers: { Location: `${url.origin}${target}` } });
70335
+ }
70336
+ if (authResult.authType === "api_key") {
70337
+ return page("Sign in required", "Device logins must be approved from a signed-in browser session.", false);
70338
+ }
70339
+ approvingUserId = authResult.user.id;
70295
70340
  }
70296
70341
  const token = generateApiKey();
70297
70342
  const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
70298
70343
  const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
70299
70344
  const ok = await agentBuilder.approveDeviceLogin({
70300
70345
  code_hash: await hashToken(code),
70301
- user_id: authResult.user.id,
70346
+ user_id: approvingUserId,
70302
70347
  token,
70303
70348
  token_hash: await hashToken(token),
70304
70349
  key_prefix: token.slice(0, 12),