openmeld 0.3.205 → 0.3.206
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/{add-me-membership-jhCNTfdl.js → add-me-membership-BkHWMxE4.js} +2 -2
- package/dist/{add-me-membership-jhCNTfdl.js.map → add-me-membership-BkHWMxE4.js.map} +1 -1
- package/dist/{agents-9krfNX_L.js → agents-BOTlKiwS.js} +901 -499
- package/dist/agents-BOTlKiwS.js.map +1 -0
- package/dist/{api-client-foundation-BguumKMv.js → api-client-foundation-6ms5gSu8.js} +1 -1
- package/dist/{api-client-foundation-BMPOo4bG.js → api-client-foundation-DpgDs0rw.js} +17 -7
- package/dist/api-client-foundation-DpgDs0rw.js.map +1 -0
- package/dist/{auth-session-wmefguut.js → auth-session-BjSqMLTz.js} +187 -56
- package/dist/auth-session-BjSqMLTz.js.map +1 -0
- package/dist/auth-session-ahQ5VXiF.js +4 -0
- package/dist/{base-url-jWXPssF_.js → base-url-9A557X2K.js} +2 -2
- package/dist/{base-url-jWXPssF_.js.map → base-url-9A557X2K.js.map} +1 -1
- package/dist/{base-url-C89TOpPV.js → base-url-CRAYNW-4.js} +1 -1
- package/dist/{command-DKM3wO3V.js → command-CkbzbvXy.js} +10 -10
- package/dist/{command-DKM3wO3V.js.map → command-CkbzbvXy.js.map} +1 -1
- package/dist/{computer-setup-continuation-Dad0lLP9.js → computer-setup-continuation-Cd9nhLQ-.js} +4 -4
- package/dist/{computer-setup-continuation-Dad0lLP9.js.map → computer-setup-continuation-Cd9nhLQ-.js.map} +1 -1
- package/dist/dist-0boZRalP.js +4 -0
- package/dist/{dist-CkixulB-.js → dist-CxadJClH.js} +3692 -3557
- package/dist/dist-CxadJClH.js.map +1 -0
- package/dist/{elapsed-time-CjAPqg-B.js → elapsed-time-C7P-nWIO.js} +3 -3
- package/dist/{elapsed-time-CjAPqg-B.js.map → elapsed-time-C7P-nWIO.js.map} +1 -1
- package/dist/{installer-CZyyvNZr.js → installation-inventory-P49sTjhe.js} +359 -359
- package/dist/installation-inventory-P49sTjhe.js.map +1 -0
- package/dist/{openmeld-DVThrV4O.js → openmeld-ChOHuaqH.js} +20 -16
- package/dist/openmeld-ChOHuaqH.js.map +1 -0
- package/dist/openmeld-dev.js +1 -1
- package/dist/{openmeld-maintenance-worker-Cxp6fwB5.js → openmeld-maintenance-worker-C7WykyDt.js} +5 -5
- package/dist/{openmeld-maintenance-worker-Cxp6fwB5.js.map → openmeld-maintenance-worker-C7WykyDt.js.map} +1 -1
- package/dist/{openmeld-tools-update-coordinator-DJ65uI3O.js → openmeld-tools-update-coordinator-BBZhGo1A.js} +12 -12
- package/dist/{openmeld-tools-update-coordinator-DJ65uI3O.js.map → openmeld-tools-update-coordinator-BBZhGo1A.js.map} +1 -1
- package/dist/openmeld.js +3 -3
- package/dist/{prepare-session-executor-aE1YARgn.js → prepare-session-executor-CLmDoHom.js} +9 -9
- package/dist/{prepare-session-executor-aE1YARgn.js.map → prepare-session-executor-CLmDoHom.js.map} +1 -1
- package/dist/{profiles-Dx3gaXgQ.js → profiles-BCecj4Pj.js} +397 -397
- package/dist/profiles-BCecj4Pj.js.map +1 -0
- package/dist/upgrade-BKEAZKre.js +4 -0
- package/dist/{upgrade-Bk8t5oav.js → upgrade-l_5Tge_z.js} +4 -4
- package/dist/{upgrade-Bk8t5oav.js.map → upgrade-l_5Tge_z.js.map} +1 -1
- package/dist/{urls-4D7CaXe3.js → urls-CY2uzH2-.js} +2 -1
- package/dist/urls-CY2uzH2-.js.map +1 -0
- package/package.json +1 -1
- package/dist/agents-9krfNX_L.js.map +0 -1
- package/dist/api-client-foundation-BMPOo4bG.js.map +0 -1
- package/dist/auth-session-CpPqG8Xz.js +0 -4
- package/dist/auth-session-wmefguut.js.map +0 -1
- package/dist/dist-BFbC-9BX.js +0 -4
- package/dist/dist-CkixulB-.js.map +0 -1
- package/dist/installer-CZyyvNZr.js.map +0 -1
- package/dist/openmeld-DVThrV4O.js.map +0 -1
- package/dist/profiles-Dx3gaXgQ.js.map +0 -1
- package/dist/upgrade-BFGKy5He.js +0 -4
- package/dist/urls-4D7CaXe3.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { t as normalizeBaseUrl } from "./urls-
|
|
3
|
+
import { t as normalizeBaseUrl } from "./urls-CY2uzH2-.js";
|
|
4
4
|
import { t as isLoopbackHostname } from "./loopback-hostname-DHQPKq8N.js";
|
|
5
|
-
import { Gt as createOpenMeldApiClient,
|
|
6
|
-
import { I as
|
|
7
|
-
import crypto from "node:crypto";
|
|
5
|
+
import { Gt as createOpenMeldApiClient, Ln as buildOpenMeldRequestContextHeaders, Pn as OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID } from "./dist-CxadJClH.js";
|
|
6
|
+
import { I as MAX_SPACE_REQUEST_TIMEOUT_MS, N as DEFAULT_SPACE_REQUEST_TIMEOUT_MS, R as MIN_SPACE_REQUEST_TIMEOUT_MS, l as getAuthSessionState, w as resolveAuthSessionExpiryEligibility } from "./auth-session-BjSqMLTz.js";
|
|
7
|
+
import crypto, { createHash } from "node:crypto";
|
|
8
8
|
//#region src/config/auth-request-compatibility.ts
|
|
9
9
|
function resolveAuthRequestCompatibility(input) {
|
|
10
10
|
const requestUrl = parseUrlOrNull(input.requestUrl);
|
|
@@ -145,7 +145,11 @@ function normalizeOptionalText(value) {
|
|
|
145
145
|
//#region src/config/request-headers.ts
|
|
146
146
|
const DEFAULT_TOKEN_TYPE = "Bearer";
|
|
147
147
|
const AUTHORIZATION_HEADER = "Authorization";
|
|
148
|
+
function fingerprintRequestAuthorization(authorization) {
|
|
149
|
+
return createHash("sha256").update(authorization).digest("hex");
|
|
150
|
+
}
|
|
148
151
|
var AuthRequestCredentialError = class extends Error {
|
|
152
|
+
retryAfterMs;
|
|
149
153
|
authHost;
|
|
150
154
|
expectedGatewayHost;
|
|
151
155
|
reason;
|
|
@@ -159,6 +163,7 @@ var AuthRequestCredentialError = class extends Error {
|
|
|
159
163
|
this.reason = input.reason;
|
|
160
164
|
this.requestHost = input.requestHost;
|
|
161
165
|
this.droppedAttachment = input.droppedAttachment;
|
|
166
|
+
this.retryAfterMs = input.retryAfterMs;
|
|
162
167
|
}
|
|
163
168
|
};
|
|
164
169
|
async function buildRequestAuthHeaders(input) {
|
|
@@ -231,6 +236,7 @@ function requireAuthTokenAttachment(input) {
|
|
|
231
236
|
}
|
|
232
237
|
async function attachAuthHeader(headers, input) {
|
|
233
238
|
const session = await resolveAuthSessionForHeaders(input);
|
|
239
|
+
if (input.expectedOwnerUserId && session?.user?.id !== input.expectedOwnerUserId) throw new Error("auth.session_owner_changed");
|
|
234
240
|
if (session === null) return;
|
|
235
241
|
let attachment;
|
|
236
242
|
try {
|
|
@@ -258,6 +264,7 @@ async function resolveAuthSessionForHeaders(input) {
|
|
|
258
264
|
if (sessionState.state === "missing") return null;
|
|
259
265
|
if (sessionState.state !== "valid" || sessionState.session === null) {
|
|
260
266
|
const error = new AuthRequestCredentialError({
|
|
267
|
+
retryAfterMs: sessionState.retryAfterMs,
|
|
261
268
|
authHost: null,
|
|
262
269
|
expectedGatewayHost: null,
|
|
263
270
|
reason: sessionState.reasonCode ?? (sessionState.state === "revoked" ? "session_revoked" : "session_invalid"),
|
|
@@ -428,7 +435,10 @@ function createCliApiClientFoundation(baseUrl, options = {}) {
|
|
|
428
435
|
timeoutMs: request.timeoutMs
|
|
429
436
|
}),
|
|
430
437
|
getAuthHeaders: async ({ requestUrl }) => {
|
|
431
|
-
const headers = await buildRequestAuthHeaders({
|
|
438
|
+
const headers = await buildRequestAuthHeaders({
|
|
439
|
+
requestUrl,
|
|
440
|
+
expectedOwnerUserId: options.expectedOwnerUserId
|
|
441
|
+
});
|
|
432
442
|
if (options.organizationId) headers[OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID] = options.organizationId;
|
|
433
443
|
options.onAuthHeadersResolved?.(headers);
|
|
434
444
|
return headers;
|
|
@@ -440,6 +450,6 @@ function createCliApiClientFoundation(baseUrl, options = {}) {
|
|
|
440
450
|
});
|
|
441
451
|
}
|
|
442
452
|
//#endregion
|
|
443
|
-
export { buildOpenMeldProfileIdentityRequestHeadersWithAuth as a, buildRequestAuthHeaders as c,
|
|
453
|
+
export { buildOpenMeldProfileIdentityRequestHeadersWithAuth as a, buildRequestAuthHeaders as c, buildOpenMeldRequestContextFromProfile as d, buildOpenMeldRequestContextFromProfileIdentity as f, AuthRequestCredentialError as i, canAttachAuthTokenToRequest as l, resolveAuthRequestCompatibility as m, fetchSpaceRequestWithTimeout as n, buildOpenMeldProfileRequestHeadersWithAuth as o, deriveAuthBaseUrlFromGatewayUrl as p, resolveSpaceRequestTimeoutMsForDiagnostics as r, buildOpenMeldRequestContextHeadersWithAuth as s, createCliApiClientFoundation as t, fingerprintRequestAuthorization as u };
|
|
444
454
|
|
|
445
|
-
//# sourceMappingURL=api-client-foundation-
|
|
455
|
+
//# sourceMappingURL=api-client-foundation-DpgDs0rw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client-foundation-DpgDs0rw.js","names":["resolveSpaceRequestTimeoutMsForDiagnostics","resolveSpaceRequestTimeoutMsForCliDiagnostics"],"sources":["../src/config/auth-request-compatibility.ts","../src/config/openmeld-request-context.ts","../src/config/request-headers.ts","../src/space/request-timeout.ts","../src/space/fetch-with-timeout.ts","../src/space/api-client-foundation.ts"],"sourcesContent":["import { normalizeBaseUrl } from \"../protocol/urls\";\nimport type { StoredAuthSession } from \"./auth-session\";\nimport { isLoopbackHostname } from \"./loopback-hostname\";\n\nexport type AuthRequestCompatibilityReason =\n | \"invalid_request_url\"\n | \"invalid_auth_url\"\n | \"insecure_transport\"\n | \"host_mismatch\"\n | \"loopback\"\n | \"same_host\"\n | \"gateway_sibling\";\n\nexport type AuthRequestCompatibility = {\n compatible: boolean;\n reason: AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n};\n\nexport function resolveAuthRequestCompatibility(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthRequestCompatibility {\n const requestUrl = parseUrlOrNull(input.requestUrl);\n if (!requestUrl) {\n return {\n compatible: false,\n reason: \"invalid_request_url\",\n requestHost: null,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const authBaseUrl = parseUrlOrNull(input.session.authBaseUrl);\n if (!authBaseUrl) {\n return {\n compatible: false,\n reason: \"invalid_auth_url\",\n requestHost: requestUrl.host,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const expectedGatewayHost = deriveGatewayHost(authBaseUrl);\n const requestHost = requestUrl.host;\n const authHost = authBaseUrl.host;\n\n if (\n (isLoopbackHostname(requestUrl.hostname) &&\n isLoopbackHostname(authBaseUrl.hostname)) ||\n // Isolated worktrees share a hostname across Auth and Gateway ports.\n // Never treat different named localhost lanes as interchangeable.\n (requestUrl.hostname.endsWith(\".localhost\") &&\n requestUrl.hostname === authBaseUrl.hostname &&\n isHttpTransportProtocol(authBaseUrl.protocol) &&\n [\"http:\", \"https:\", \"ws:\", \"wss:\"].includes(requestUrl.protocol))\n ) {\n return {\n compatible: true,\n reason: \"loopback\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (!isSecureTransportProtocol(requestUrl.protocol)) {\n return {\n compatible: false,\n reason: \"insecure_transport\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (requestHost === authHost) {\n return {\n compatible: true,\n reason: \"same_host\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (expectedGatewayHost && requestHost === expectedGatewayHost) {\n return {\n compatible: true,\n reason: \"gateway_sibling\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n return {\n compatible: false,\n reason: \"host_mismatch\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n}\n\nexport function deriveAuthBaseUrlFromGatewayUrl(\n gatewayUrl: string\n): string | null {\n const parsed = parseUrlOrNull(gatewayUrl);\n if (!parsed) {\n return null;\n }\n if (!isHttpTransportProtocol(parsed.protocol)) {\n return null;\n }\n if (!parsed.hostname.startsWith(\"gateway.\")) {\n return null;\n }\n\n const authUrl = new URL(parsed.toString());\n authUrl.hostname = `auth.${parsed.hostname.slice(\"gateway.\".length)}`;\n authUrl.pathname = \"/\";\n authUrl.search = \"\";\n authUrl.hash = \"\";\n return normalizeBaseUrl(authUrl.toString());\n}\n\nfunction deriveGatewayHost(authBaseUrl: URL): string | null {\n if (!authBaseUrl.hostname.startsWith(\"auth.\")) {\n return null;\n }\n\n const gatewayUrl = new URL(authBaseUrl.toString());\n gatewayUrl.hostname = `gateway.${authBaseUrl.hostname.slice(\"auth.\".length)}`;\n return gatewayUrl.host;\n}\n\nfunction parseUrlOrNull(value: string): URL | null {\n try {\n return new URL(value);\n } catch {\n return null;\n }\n}\n\nfunction isSecureTransportProtocol(protocol: string): boolean {\n return protocol === \"https:\" || protocol === \"wss:\";\n}\n\nfunction isHttpTransportProtocol(protocol: string): boolean {\n return protocol === \"http:\" || protocol === \"https:\";\n}\n","import crypto from \"node:crypto\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\n\nexport type OpenMeldRequestContextProfileIdentity = {\n openMeldProfileId: string;\n profileKind?: \"human\" | \"agent\" | \"system\";\n kind?: \"human\" | \"agent\";\n profileHandle?: string;\n profileName: string;\n ownerUserId?: string;\n ownerName?: string;\n agentControllerConversationId?: string;\n};\n\nexport function buildOpenMeldRequestContextFromProfile(input: {\n openMeldProfile: OpenMeldProfile;\n requestId?: string;\n agentControllerConversationId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const agentControllerConversationId = normalizeOptionalText(\n input.agentControllerConversationId\n );\n const ownerName = normalizeOptionalText(input.openMeldProfile.ownerName);\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.openMeldProfile.openMeldProfileId,\n profileKind: input.openMeldProfile.profileKind,\n profileHandle: input.openMeldProfile.profileHandle,\n profileName: input.openMeldProfile.profileName,\n ownerUserId: input.openMeldProfile.ownerUserId,\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nexport function buildOpenMeldRequestContextFromProfileIdentity(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const profileHandle = normalizeOptionalText(\n input.profileIdentity.profileHandle\n );\n const ownerUserId = normalizeOptionalText(input.profileIdentity.ownerUserId);\n const ownerName = normalizeOptionalText(input.profileIdentity.ownerName);\n const agentControllerConversationId = normalizeOptionalText(\n input.profileIdentity.agentControllerConversationId\n );\n const profileKind =\n input.profileIdentity.profileKind ??\n (input.profileIdentity.kind === \"human\" ||\n input.profileIdentity.kind === \"agent\"\n ? input.profileIdentity.kind\n : \"system\");\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.profileIdentity.openMeldProfileId,\n profileKind,\n ...(profileHandle ? { profileHandle } : {}),\n profileName: input.profileIdentity.profileName,\n ...(ownerUserId ? { ownerUserId } : {}),\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nfunction normalizeOptionalText(value: unknown): string | null {\n const normalized = String(value ?? \"\").trim();\n return normalized.length > 0 ? normalized : null;\n}\n","import { createHash } from \"node:crypto\";\nimport {\n buildOpenMeldRequestContextHeaders,\n type OpenMeldRequestContextHeadersInput,\n} from \"@openmeld/gateway-contract\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport {\n type AuthRequestCompatibilityReason,\n resolveAuthRequestCompatibility,\n} from \"./auth-request-compatibility\";\nimport {\n type AuthSessionStateReasonCode,\n getAuthSessionState,\n type StoredAuthSession,\n} from \"./auth-session\";\nimport { resolveAuthSessionExpiryEligibility } from \"./auth-session-expiry\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\nimport {\n buildOpenMeldRequestContextFromProfile,\n buildOpenMeldRequestContextFromProfileIdentity,\n type OpenMeldRequestContextProfileIdentity,\n} from \"./openmeld-request-context\";\n\nconst DEFAULT_TOKEN_TYPE = \"Bearer\";\nconst AUTHORIZATION_HEADER = \"Authorization\";\n\n// Ephemeral correlation for the exact credential attached to a request/socket.\n// Never include this fingerprint in persisted or uploaded diagnostics.\nexport function fingerprintRequestAuthorization(authorization: string): string {\n return createHash(\"sha256\").update(authorization).digest(\"hex\");\n}\n\ntype RequestAuthHeadersInput = {\n authSession?: StoredAuthSession | null;\n expectedOwnerUserId?: string;\n requestUrl: string;\n};\n\ntype OpenMeldRequestContextHeadersWithAuthInput =\n OpenMeldRequestContextHeadersInput & {\n authSession?: StoredAuthSession | null;\n requestUrl: string;\n };\n\nexport type AuthTokenAttachment =\n | {\n status: \"attachable\";\n token: string;\n tokenType: string;\n }\n | {\n status: \"dropped\";\n reason:\n | \"empty_token\"\n | \"session_expired\"\n | \"session_expiry_invalid\"\n | AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n };\n\nexport type DroppedAuthTokenAttachment = Extract<\n AuthTokenAttachment,\n { status: \"dropped\" }\n>;\n\nexport type AuthRequestCredentialFailureReason =\n | DroppedAuthTokenAttachment[\"reason\"]\n | AuthSessionStateReasonCode\n | \"session_invalid\"\n | \"session_revoked\";\n\nexport class AuthRequestCredentialError extends Error {\n readonly retryAfterMs?: number;\n readonly authHost: string | null;\n readonly expectedGatewayHost: string | null;\n readonly reason: AuthRequestCredentialFailureReason;\n readonly requestHost: string | null;\n readonly droppedAttachment?: DroppedAuthTokenAttachment;\n\n constructor(input: {\n retryAfterMs?: number;\n authHost: string | null;\n expectedGatewayHost: string | null;\n reason: AuthRequestCredentialFailureReason;\n requestHost: string | null;\n droppedAttachment?: DroppedAuthTokenAttachment;\n }) {\n super(\n `OpenMeld refused to send a request with unusable stored credentials (${input.reason}).`\n );\n this.name = \"AuthRequestCredentialError\";\n this.authHost = input.authHost;\n this.expectedGatewayHost = input.expectedGatewayHost;\n this.reason = input.reason;\n this.requestHost = input.requestHost;\n this.droppedAttachment = input.droppedAttachment;\n this.retryAfterMs = input.retryAfterMs;\n }\n}\n\nexport async function buildRequestAuthHeaders(\n input: RequestAuthHeadersInput\n): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldRequestContextHeadersWithAuth(\n input: OpenMeldRequestContextHeadersWithAuthInput\n): Promise<Record<string, string>> {\n const headers = buildOpenMeldRequestContextHeaders(input);\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldProfileRequestHeadersWithAuth(input: {\n openMeldProfile: OpenMeldProfile;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n agentControllerConversationId?: string;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfile({\n openMeldProfile: input.openMeldProfile,\n agentControllerConversationId: input.agentControllerConversationId,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport async function buildOpenMeldProfileIdentityRequestHeadersWithAuth(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfileIdentity({\n profileIdentity: input.profileIdentity,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport function withSpacePassword(\n requestContext: OpenMeldRequestContext,\n spacePassword?: string\n): OpenMeldRequestContextHeadersInput {\n return {\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n };\n}\n\n// One decision for \"can this stored session authenticate this request\", with\n// the drop reason preserved. Header building and the daemon stream connect\n// gate must share this so they cannot drift apart.\nexport function resolveAuthTokenAttachment(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthTokenAttachment {\n const compatibility = resolveAuthRequestCompatibility({\n session: input.session,\n requestUrl: input.requestUrl,\n });\n const token = normalizeAccessToken(input.session);\n if (!token) {\n return {\n status: \"dropped\",\n reason: \"empty_token\",\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n if (!compatibility.compatible) {\n return {\n status: \"dropped\",\n reason: compatibility.reason,\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n const expiryReason = resolveSessionExpiryReason(input.session);\n if (expiryReason) {\n return {\n status: \"dropped\",\n reason: expiryReason,\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n return {\n status: \"attachable\",\n token,\n tokenType: normalizeTokenType(input.session.tokenType),\n };\n}\n\nexport function requireAuthTokenAttachment(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): Extract<AuthTokenAttachment, { status: \"attachable\" }> {\n const attachment = resolveAuthTokenAttachment(input);\n if (attachment.status === \"dropped\") {\n throw createAuthRequestCredentialError(attachment);\n }\n return attachment;\n}\n\nasync function attachAuthHeader(\n headers: Record<string, string>,\n input: RequestAuthHeadersInput\n): Promise<void> {\n const session = await resolveAuthSessionForHeaders(input);\n if (\n input.expectedOwnerUserId &&\n session?.user?.id !== input.expectedOwnerUserId\n ) {\n throw new Error(\"auth.session_owner_changed\");\n }\n if (session === null) {\n // No stored credentials exist, so there is nothing to strip: the caller\n // is knowingly sending an unauthenticated request.\n return;\n }\n\n let attachment: Extract<AuthTokenAttachment, { status: \"attachable\" }>;\n try {\n attachment = requireAuthTokenAttachment({\n session,\n requestUrl: input.requestUrl,\n });\n } catch (error) {\n if (error instanceof AuthRequestCredentialError) {\n logRejectedAuthRequestCredential(error);\n }\n throw error;\n }\n headers[AUTHORIZATION_HEADER] = `${attachment.tokenType} ${attachment.token}`;\n}\n\nfunction logRejectedAuthRequestCredential(\n error: AuthRequestCredentialError\n): void {\n console.error(\"[openmeld.auth.request_credential_rejected]\", {\n authHost: error.authHost,\n expectedGatewayHost: error.expectedGatewayHost,\n reason: error.reason,\n requestHost: error.requestHost,\n });\n}\n\nasync function resolveAuthSessionForHeaders(\n input: RequestAuthHeadersInput\n): Promise<StoredAuthSession | null> {\n if (input.authSession !== undefined) {\n return input.authSession;\n }\n\n const sessionState = await getAuthSessionState({ refreshExpired: true });\n if (sessionState.state === \"missing\") {\n return null;\n }\n if (sessionState.state !== \"valid\" || sessionState.session === null) {\n const error = new AuthRequestCredentialError({\n retryAfterMs: sessionState.retryAfterMs,\n authHost: null,\n expectedGatewayHost: null,\n reason:\n sessionState.reasonCode ??\n (sessionState.state === \"revoked\"\n ? \"session_revoked\"\n : \"session_invalid\"),\n requestHost: parseRequestHost(input.requestUrl),\n });\n logRejectedAuthRequestCredential(error);\n throw error;\n }\n\n return sessionState.session;\n}\n\nfunction createAuthRequestCredentialError(\n attachment: DroppedAuthTokenAttachment\n): AuthRequestCredentialError {\n return new AuthRequestCredentialError({\n authHost: attachment.authHost,\n expectedGatewayHost: attachment.expectedGatewayHost,\n reason: attachment.reason,\n requestHost: attachment.requestHost,\n droppedAttachment: attachment,\n });\n}\n\nfunction parseRequestHost(requestUrl: string): string | null {\n try {\n return new URL(requestUrl).host || null;\n } catch {\n return null;\n }\n}\n\nfunction normalizeAccessToken(session: StoredAuthSession): string {\n return String(session.accessToken ?? \"\").trim();\n}\n\nfunction normalizeTokenType(tokenType: string | undefined): string {\n const normalized = String(tokenType ?? \"\").trim();\n return normalized.length > 0 ? normalized : DEFAULT_TOKEN_TYPE;\n}\n\nfunction resolveSessionExpiryReason(\n session: StoredAuthSession\n): \"session_expired\" | \"session_expiry_invalid\" | null {\n const eligibility = resolveAuthSessionExpiryEligibility(session.expiresAt);\n if (eligibility.status === \"invalid\") {\n return \"session_expiry_invalid\";\n }\n return eligibility.status === \"expired\" ? \"session_expired\" : null;\n}\n\nexport function canAttachAuthTokenToRequest(\n session: StoredAuthSession,\n requestUrl: string\n): boolean {\n return (\n resolveAuthTokenAttachment({\n session,\n requestUrl,\n }).status === \"attachable\"\n );\n}\n","import {\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS,\n DEFAULT_SPACE_REQUEST_TIMEOUT_MS,\n MAX_SPACE_REQUEST_TIMEOUT_MS,\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n} from \"../strategy-constants\";\n\nconst SPACE_REQUEST_TIMEOUT_ENV_KEY = \"OPENMELD_SPACE_REQUEST_TIMEOUT_MS\";\n\nexport function resolveSpaceRequestTimeoutMs(override?: number): number {\n if (isFinitePositiveNumber(override)) {\n return clampSpaceRequestTimeoutMs(override);\n }\n\n const fromEnv = Number.parseInt(\n String(process.env[SPACE_REQUEST_TIMEOUT_ENV_KEY] ?? \"\"),\n 10\n );\n if (isFinitePositiveNumber(fromEnv)) {\n return clampSpaceRequestTimeoutMs(fromEnv);\n }\n\n return DEFAULT_SPACE_REQUEST_TIMEOUT_MS;\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMs(undefined);\n}\n\nexport function resolveSpaceConversationValidateTimeoutMs(): number {\n return Math.max(\n resolveSpaceRequestTimeoutMs(undefined),\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS\n );\n}\n\nfunction clampSpaceRequestTimeoutMs(value: number): number {\n const normalized = Math.trunc(value);\n return Math.max(\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n Math.min(MAX_SPACE_REQUEST_TIMEOUT_MS, normalized)\n );\n}\n\nfunction isFinitePositiveNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n","import {\n resolveSpaceRequestTimeoutMs,\n resolveSpaceRequestTimeoutMsForDiagnostics as resolveSpaceRequestTimeoutMsForCliDiagnostics,\n} from \"./request-timeout\";\n\nexport async function fetchSpaceRequestWithTimeout(input: {\n url: string;\n operation: string;\n init?: RequestInit;\n timeoutMs?: number;\n}): Promise<Response> {\n const timeoutMs = resolveSpaceRequestTimeoutMs(input.timeoutMs);\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const composed = composeAbortSignals(input.init?.signal, timeoutSignal);\n\n try {\n try {\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n } catch (error) {\n // A keep-alive connection that a proxy silently dropped fails exactly\n // once and undici evicts it; the retry rides a fresh connection. This\n // is what keeps a long-lived service working behind flaky proxies\n // without asking users to touch their network config.\n if (\n timeoutSignal.aborted ||\n composed.signal.aborted ||\n !shouldWrapNetworkRequestError(error)\n ) {\n throw error;\n }\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n }\n } catch (error) {\n if (timeoutSignal.aborted) {\n throw createSpaceRequestTimeoutError({\n operation: input.operation,\n timeoutMs,\n cause: error,\n });\n }\n if (shouldWrapNetworkRequestError(error)) {\n throw createSpaceRequestNetworkError({\n operation: input.operation,\n url: input.url,\n cause: error,\n });\n }\n throw error;\n } finally {\n composed.cleanup();\n }\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMsForCliDiagnostics();\n}\n\nfunction createSpaceRequestTimeoutError(input: {\n operation: string;\n timeoutMs: number;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request timed out after ${input.timeoutMs}ms`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.timeout\";\n return error;\n}\n\nfunction createSpaceRequestNetworkError(input: {\n operation: string;\n url: string;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request could not reach ${describeRequestTarget(input.url)} (${toErrorMessage(input.cause)})`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.request_failed\";\n return error;\n}\n\nfunction composeAbortSignals(\n parent: AbortSignal | null | undefined,\n timeout: AbortSignal\n): { signal: AbortSignal; cleanup: () => void } {\n if (!parent) {\n return {\n signal: timeout,\n cleanup: () => undefined,\n };\n }\n\n if (parent.aborted || timeout.aborted) {\n const controller = new AbortController();\n controller.abort();\n return {\n signal: controller.signal,\n cleanup: () => undefined,\n };\n }\n\n const controller = new AbortController();\n const abort = () => {\n controller.abort();\n };\n\n parent.addEventListener(\"abort\", abort, { once: true });\n timeout.addEventListener(\"abort\", abort, { once: true });\n\n return {\n signal: controller.signal,\n cleanup: () => {\n parent.removeEventListener(\"abort\", abort);\n timeout.removeEventListener(\"abort\", abort);\n },\n };\n}\n\nfunction describeRequestTarget(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return url;\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n const message = error.message.trim();\n return message.length > 0 ? message : \"request failed\";\n }\n const message = String(error ?? \"\").trim();\n return message.length > 0 ? message : \"request failed\";\n}\n\nfunction shouldWrapNetworkRequestError(error: unknown): boolean {\n if (error instanceof TypeError) {\n return true;\n }\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n error.code.startsWith(\"ERR_SSL_\")\n ) {\n return true;\n }\n const message = toErrorMessage(error).toLowerCase();\n return (\n message.includes(\"fetch failed\") ||\n message.includes(\"failed to fetch\") ||\n message.includes(\"network request failed\") ||\n message.includes(\"ssl_decryption_failed_or_bad_record_mac\")\n );\n}\n","import {\n createOpenMeldApiClient,\n type OpenMeldApiClientFoundation,\n} from \"@openmeld/api-client\";\nimport {\n buildOpenMeldRequestContextHeaders,\n OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID,\n} from \"@openmeld/gateway-contract\";\nimport { buildRequestAuthHeaders } from \"../config/request-headers\";\nimport { fetchSpaceRequestWithTimeout } from \"./fetch-with-timeout\";\n\nexport function createCliApiClientFoundation(\n baseUrl: string,\n options: {\n onAuthHeadersResolved?: (headers: Record<string, string>) => void;\n organizationId?: string;\n expectedOwnerUserId?: string;\n } = {}\n): OpenMeldApiClientFoundation {\n return createOpenMeldApiClient({\n baseUrl,\n transport: async (request) =>\n await fetchSpaceRequestWithTimeout({\n url: request.url,\n operation: request.operation,\n init: request.init,\n timeoutMs: request.timeoutMs,\n }),\n getAuthHeaders: async ({ requestUrl }) => {\n const headers = await buildRequestAuthHeaders({\n requestUrl,\n expectedOwnerUserId: options.expectedOwnerUserId,\n });\n if (options.organizationId) {\n headers[OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID] =\n options.organizationId;\n }\n options.onAuthHeadersResolved?.(headers);\n return headers;\n },\n getRequestContextHeaders: async ({ requestContext, spacePassword }) =>\n buildOpenMeldRequestContextHeaders({\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n }),\n });\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { t as isLoopbackHostname } from "./loopback-hostname-DHQPKq8N.js";
|
|
4
4
|
import { S as isProcessIdentityAlive, r as isOpenMeldLockError, t as acquireLock, tt as openMeldRootDir, u as runWithHeldLock, x as CURRENT_PROCESS_START_IDENTITY } from "./lock-CvBnBcFK.js";
|
|
5
|
-
import { $r as int,
|
|
5
|
+
import { $r as int, Jr as boolean, Oi as openMeldProfileIdSchema, Qr as enumFactory, Xr as discriminatedUnion, _ as localAgentCatalogSchema, ci as record, d as START_BOUNDED_ID_SCHEMA, ei as iso, f as START_BOUNDED_VERSION_SCHEMA, h as startReplyReadinessSummarySchema, i as authProfileManagedRoleSchema, ii as nullFactory, li as strictObject, mi as unknown, ni as literal, oi as object, p as START_ISO_DATE_TIME_SCHEMA, pi as union, qr as array, r as authProfileKindSchema, ui as string, y as CURRENT_DAEMON_EXECUTION_CONTRACT_EPOCH } from "./profiles-BCecj4Pj.js";
|
|
6
6
|
import { r as daemonServiceLaneSchema } from "./service-contract-CRyDcIIf.js";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -816,6 +816,9 @@ let unresponsiveKeychainError = null;
|
|
|
816
816
|
let keychainRetryAt = 0;
|
|
817
817
|
let lastKeychainFailureCode = null;
|
|
818
818
|
const MAC_OS_KEYCHAIN_RETRY_DELAY_MS = 3e4;
|
|
819
|
+
function getMacOsKeychainRetryAfterMs() {
|
|
820
|
+
return Math.max(0, keychainRetryAt - Date.now());
|
|
821
|
+
}
|
|
819
822
|
async function storeMacOsNativeKeychainToken(input) {
|
|
820
823
|
if (isBinaryDistribution()) {
|
|
821
824
|
await runBoundedMacOsNativeKeychainRequest({
|
|
@@ -1172,6 +1175,7 @@ async function readAccessToken(ref) {
|
|
|
1172
1175
|
} catch (error) {
|
|
1173
1176
|
return {
|
|
1174
1177
|
errorMessage: toErrorMessage$1(error),
|
|
1178
|
+
...ref.provider === "macos-keychain" ? { retryAfterMs: getMacOsKeychainRetryAfterMs() } : {},
|
|
1175
1179
|
status: "unavailable"
|
|
1176
1180
|
};
|
|
1177
1181
|
}
|
|
@@ -1447,13 +1451,50 @@ var AuthSessionTransitionConflictError = class extends Error {
|
|
|
1447
1451
|
};
|
|
1448
1452
|
const TRAILING_SLASHES_RE = /\/+$/u;
|
|
1449
1453
|
let cachedAuthSession = null;
|
|
1454
|
+
const pendingCredentialReads = /* @__PURE__ */ new Map();
|
|
1455
|
+
const credentialAvailabilityListeners = /* @__PURE__ */ new Set();
|
|
1456
|
+
function onAuthSessionCredentialAvailable(notify) {
|
|
1457
|
+
const listener = {
|
|
1458
|
+
path: authSessionPath(),
|
|
1459
|
+
notify
|
|
1460
|
+
};
|
|
1461
|
+
credentialAvailabilityListeners.add(listener);
|
|
1462
|
+
return () => {
|
|
1463
|
+
credentialAvailabilityListeners.delete(listener);
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1450
1466
|
const activeAuthSessionTransitionIds = /* @__PURE__ */ new Set();
|
|
1467
|
+
const credentialObservationListeners = /* @__PURE__ */ new Set();
|
|
1468
|
+
function onAuthSessionCredentialObservation(notify) {
|
|
1469
|
+
const listener = {
|
|
1470
|
+
path: authSessionPath(),
|
|
1471
|
+
notify
|
|
1472
|
+
};
|
|
1473
|
+
credentialObservationListeners.add(listener);
|
|
1474
|
+
return () => {
|
|
1475
|
+
credentialObservationListeners.delete(listener);
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
function observeCredential(reason) {
|
|
1479
|
+
const path = authSessionPath();
|
|
1480
|
+
for (const listener of credentialObservationListeners) if (listener.path === path) try {
|
|
1481
|
+
listener.notify(reason);
|
|
1482
|
+
} catch {}
|
|
1483
|
+
}
|
|
1451
1484
|
async function getAuthSessionState(options = {}) {
|
|
1452
|
-
|
|
1485
|
+
const result = await getAuthSessionStateWithCandidateRefreshFence(options, false);
|
|
1486
|
+
if (result.reasonCode === "session_metadata_invalid") observeCredential("metadata_unavailable");
|
|
1487
|
+
return {
|
|
1488
|
+
state: result.state,
|
|
1489
|
+
session: result.session,
|
|
1490
|
+
...result.reasonCode ? { reasonCode: result.reasonCode } : {},
|
|
1491
|
+
...result.errorMessage ? { errorMessage: result.errorMessage } : {},
|
|
1492
|
+
...result.retryAfterMs !== void 0 ? { retryAfterMs: result.retryAfterMs } : {}
|
|
1493
|
+
};
|
|
1453
1494
|
}
|
|
1454
1495
|
async function getAuthSessionStateWithCandidateRefreshFence(options, candidateRefreshFenceHeld) {
|
|
1455
1496
|
const localState = await getLocalAuthSessionState();
|
|
1456
|
-
const localPayloadKey =
|
|
1497
|
+
const localPayloadKey = "payloadKey" in localState ? localState.payloadKey : null;
|
|
1457
1498
|
const shouldValidateRemote = options.validateRemote === true || options.refreshExpired === true && localState.state === "expired";
|
|
1458
1499
|
switch (localState.state) {
|
|
1459
1500
|
case "missing":
|
|
@@ -2124,65 +2165,59 @@ async function getLocalAuthSessionState(options = {}) {
|
|
|
2124
2165
|
try {
|
|
2125
2166
|
payload = options.recover === false ? await readSessionPayloadFile() : await readSessionPayload();
|
|
2126
2167
|
} catch (error) {
|
|
2127
|
-
if (error instanceof AuthSessionStorageError)
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2168
|
+
if (error instanceof AuthSessionStorageError) {
|
|
2169
|
+
cachedAuthSession = null;
|
|
2170
|
+
return {
|
|
2171
|
+
errorMessage: error.message,
|
|
2172
|
+
reasonCode: "session_metadata_invalid",
|
|
2173
|
+
state: "invalid",
|
|
2174
|
+
session: null
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
throw error;
|
|
2178
|
+
}
|
|
2179
|
+
if (payload?.v !== 1) {
|
|
2180
|
+
cachedAuthSession = null;
|
|
2181
|
+
return {
|
|
2182
|
+
reasonCode: "session_missing",
|
|
2183
|
+
state: "missing",
|
|
2131
2184
|
session: null
|
|
2132
2185
|
};
|
|
2133
|
-
throw error;
|
|
2134
2186
|
}
|
|
2135
|
-
if (payload?.v !== 1) return {
|
|
2136
|
-
reasonCode: "session_missing",
|
|
2137
|
-
state: "missing",
|
|
2138
|
-
session: null
|
|
2139
|
-
};
|
|
2140
2187
|
const tokenRef = normalizeTokenRef(payload.tokenRef);
|
|
2141
|
-
if (!tokenRef)
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2188
|
+
if (!tokenRef) {
|
|
2189
|
+
cachedAuthSession = null;
|
|
2190
|
+
return {
|
|
2191
|
+
reasonCode: "session_token_ref_invalid",
|
|
2192
|
+
state: "invalid",
|
|
2193
|
+
session: null
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2146
2196
|
const tokenType = normalizeOptionalString(payload.tokenType);
|
|
2147
2197
|
const authBaseUrl = normalizeOptionalString(payload.authBaseUrl);
|
|
2148
2198
|
const clientId = normalizeOptionalString(payload.clientId);
|
|
2149
2199
|
const createdAt = normalizeOptionalString(payload.createdAt);
|
|
2150
|
-
if (!(tokenType && authBaseUrl && clientId && createdAt))
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
};
|
|
2155
|
-
let session = readCachedAuthSession(payload);
|
|
2156
|
-
if (!session) {
|
|
2157
|
-
const accessToken = await readAccessToken(tokenRef);
|
|
2158
|
-
if (accessToken.status === "missing") return {
|
|
2159
|
-
reasonCode: "session_token_missing",
|
|
2160
|
-
state: "invalid",
|
|
2161
|
-
session: null
|
|
2162
|
-
};
|
|
2163
|
-
if (accessToken.status === "unavailable") return {
|
|
2164
|
-
errorMessage: accessToken.errorMessage,
|
|
2165
|
-
reasonCode: "session_token_unavailable",
|
|
2200
|
+
if (!(tokenType && authBaseUrl && clientId && createdAt)) {
|
|
2201
|
+
cachedAuthSession = null;
|
|
2202
|
+
return {
|
|
2203
|
+
reasonCode: "session_metadata_invalid",
|
|
2166
2204
|
state: "invalid",
|
|
2167
2205
|
session: null
|
|
2168
2206
|
};
|
|
2169
|
-
session = buildStoredAuthSession({
|
|
2170
|
-
accessToken: accessToken.accessToken,
|
|
2171
|
-
payload: {
|
|
2172
|
-
...payload,
|
|
2173
|
-
v: 1,
|
|
2174
|
-
tokenRef,
|
|
2175
|
-
tokenType,
|
|
2176
|
-
authBaseUrl,
|
|
2177
|
-
clientId,
|
|
2178
|
-
createdAt
|
|
2179
|
-
}
|
|
2180
|
-
});
|
|
2181
|
-
cacheAuthSession({
|
|
2182
|
-
payload,
|
|
2183
|
-
session
|
|
2184
|
-
});
|
|
2185
2207
|
}
|
|
2208
|
+
const session = readCachedAuthSession(payload);
|
|
2209
|
+
if (!session) return await loadCurrentSessionCredential({
|
|
2210
|
+
...payload,
|
|
2211
|
+
v: 1,
|
|
2212
|
+
tokenRef,
|
|
2213
|
+
tokenType,
|
|
2214
|
+
authBaseUrl,
|
|
2215
|
+
clientId,
|
|
2216
|
+
createdAt
|
|
2217
|
+
}, options);
|
|
2218
|
+
return resolveLocalStoredSessionState(session, buildAuthSessionPayloadKey(payload));
|
|
2219
|
+
}
|
|
2220
|
+
function resolveLocalStoredSessionState(session, payloadKey) {
|
|
2186
2221
|
const expiryEligibility = resolveAuthSessionExpiryEligibility(session.expiresAt);
|
|
2187
2222
|
if (expiryEligibility.status === "invalid") return {
|
|
2188
2223
|
reasonCode: "session_expiry_invalid",
|
|
@@ -2192,13 +2227,68 @@ async function getLocalAuthSessionState(options = {}) {
|
|
|
2192
2227
|
if (expiryEligibility.status === "expired") return {
|
|
2193
2228
|
reasonCode: "session_expired",
|
|
2194
2229
|
state: "expired",
|
|
2230
|
+
payloadKey,
|
|
2195
2231
|
session
|
|
2196
2232
|
};
|
|
2197
2233
|
return {
|
|
2198
2234
|
state: "valid",
|
|
2235
|
+
payloadKey,
|
|
2199
2236
|
session
|
|
2200
2237
|
};
|
|
2201
2238
|
}
|
|
2239
|
+
async function loadCurrentSessionCredential(payload, options) {
|
|
2240
|
+
const credentialKey = buildAuthSessionCredentialCacheKey(payload);
|
|
2241
|
+
const accessToken = await readSessionCredential(credentialKey, payload.tokenRef);
|
|
2242
|
+
let currentPayload;
|
|
2243
|
+
try {
|
|
2244
|
+
currentPayload = options.recover === false ? await readSessionPayloadFile() : await readSessionPayload();
|
|
2245
|
+
} catch (error) {
|
|
2246
|
+
if (!(error instanceof AuthSessionStorageError)) throw error;
|
|
2247
|
+
cachedAuthSession = null;
|
|
2248
|
+
return {
|
|
2249
|
+
state: "invalid",
|
|
2250
|
+
session: null,
|
|
2251
|
+
reasonCode: "session_metadata_invalid",
|
|
2252
|
+
errorMessage: error.message
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
if (!currentPayload || buildAuthSessionCredentialCacheKey(currentPayload) !== credentialKey) {
|
|
2256
|
+
if ((options.reloadCount ?? 0) >= 2) {
|
|
2257
|
+
cachedAuthSession = null;
|
|
2258
|
+
return {
|
|
2259
|
+
state: "invalid",
|
|
2260
|
+
session: null,
|
|
2261
|
+
reasonCode: "session_metadata_invalid",
|
|
2262
|
+
errorMessage: "The local login changed while reading its credentials. Try again."
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
2265
|
+
return await getLocalAuthSessionState({
|
|
2266
|
+
...options,
|
|
2267
|
+
reloadCount: (options.reloadCount ?? 0) + 1
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
if (accessToken.status === "missing") return {
|
|
2271
|
+
reasonCode: "session_token_missing",
|
|
2272
|
+
state: "invalid",
|
|
2273
|
+
session: null
|
|
2274
|
+
};
|
|
2275
|
+
if (accessToken.status === "unavailable") return {
|
|
2276
|
+
errorMessage: accessToken.errorMessage,
|
|
2277
|
+
retryAfterMs: accessToken.retryAfterMs,
|
|
2278
|
+
reasonCode: "session_token_unavailable",
|
|
2279
|
+
state: "invalid",
|
|
2280
|
+
session: null
|
|
2281
|
+
};
|
|
2282
|
+
const session = buildStoredAuthSession({
|
|
2283
|
+
accessToken: accessToken.accessToken,
|
|
2284
|
+
payload: currentPayload
|
|
2285
|
+
});
|
|
2286
|
+
cacheAuthSession({
|
|
2287
|
+
payload: currentPayload,
|
|
2288
|
+
session
|
|
2289
|
+
});
|
|
2290
|
+
return resolveLocalStoredSessionState(session, buildAuthSessionPayloadKey(currentPayload));
|
|
2291
|
+
}
|
|
2202
2292
|
async function assertStoredAccessTokenReloads(input) {
|
|
2203
2293
|
const reloaded = await readAccessToken(input.tokenRef);
|
|
2204
2294
|
if (reloaded.status === "found" && reloaded.accessToken === input.accessToken) return;
|
|
@@ -2243,14 +2333,55 @@ async function cleanupTransitionTokensNotReferencedByCurrentSession(input) {
|
|
|
2243
2333
|
}
|
|
2244
2334
|
}
|
|
2245
2335
|
function cacheAuthSession(input) {
|
|
2336
|
+
const credentialKey = buildAuthSessionCredentialCacheKey(input.payload);
|
|
2337
|
+
const becameAvailable = cachedAuthSession?.credentialKey !== credentialKey;
|
|
2338
|
+
const previous = cachedAuthSession;
|
|
2246
2339
|
cachedAuthSession = {
|
|
2247
|
-
|
|
2340
|
+
credentialKey,
|
|
2248
2341
|
session: input.session
|
|
2249
2342
|
};
|
|
2343
|
+
if (!previous) observeCredential("credential_available");
|
|
2344
|
+
else if (previous.session.user?.id !== input.session.user?.id) observeCredential("account_changed");
|
|
2345
|
+
else if (becameAvailable) observeCredential("credential_changed");
|
|
2346
|
+
else if (JSON.stringify([previous.session.activeOrganization, previous.session.user]) !== JSON.stringify([input.session.activeOrganization, input.session.user])) observeCredential("context_changed");
|
|
2347
|
+
if (becameAvailable) {
|
|
2348
|
+
const path = authSessionPath();
|
|
2349
|
+
for (const listener of credentialAvailabilityListeners) if (listener.path === path) listener.notify();
|
|
2350
|
+
}
|
|
2250
2351
|
}
|
|
2251
2352
|
function readCachedAuthSession(payload) {
|
|
2252
|
-
|
|
2253
|
-
|
|
2353
|
+
if (cachedAuthSession?.credentialKey !== buildAuthSessionCredentialCacheKey(payload)) return null;
|
|
2354
|
+
const session = buildStoredAuthSession({
|
|
2355
|
+
accessToken: cachedAuthSession.session.accessToken,
|
|
2356
|
+
payload
|
|
2357
|
+
});
|
|
2358
|
+
cacheAuthSession({
|
|
2359
|
+
payload,
|
|
2360
|
+
session
|
|
2361
|
+
});
|
|
2362
|
+
return session;
|
|
2363
|
+
}
|
|
2364
|
+
function buildAuthSessionCredentialCacheKey(payload) {
|
|
2365
|
+
return `${authSessionPath()}\n${JSON.stringify({
|
|
2366
|
+
v: payload.v,
|
|
2367
|
+
tokenRef: payload.tokenRef,
|
|
2368
|
+
tokenType: payload.tokenType,
|
|
2369
|
+
authBaseUrl: payload.authBaseUrl,
|
|
2370
|
+
clientId: payload.clientId,
|
|
2371
|
+
createdAt: payload.createdAt,
|
|
2372
|
+
expiresAt: payload.expiresAt,
|
|
2373
|
+
scope: payload.scope,
|
|
2374
|
+
ownerUserId: payload.user?.id
|
|
2375
|
+
})}`;
|
|
2376
|
+
}
|
|
2377
|
+
async function readSessionCredential(key, ref) {
|
|
2378
|
+
const pending = pendingCredentialReads.get(key);
|
|
2379
|
+
if (pending) return await pending;
|
|
2380
|
+
const read = readAccessToken(ref).finally(() => {
|
|
2381
|
+
if (pendingCredentialReads.get(key) === read) pendingCredentialReads.delete(key);
|
|
2382
|
+
});
|
|
2383
|
+
pendingCredentialReads.set(key, read);
|
|
2384
|
+
return await read;
|
|
2254
2385
|
}
|
|
2255
2386
|
function buildAuthSessionPayloadKey(payload) {
|
|
2256
2387
|
return `${authSessionPath()}\n${JSON.stringify(payload)}`;
|
|
@@ -2292,7 +2423,7 @@ async function persistCommittedRemoteSessionRefresh(input) {
|
|
|
2292
2423
|
const refresh = await prepareRemoteSessionRefresh({
|
|
2293
2424
|
...input,
|
|
2294
2425
|
payload,
|
|
2295
|
-
uniqueTokenRef:
|
|
2426
|
+
uniqueTokenRef: true
|
|
2296
2427
|
});
|
|
2297
2428
|
if (!refresh) return null;
|
|
2298
2429
|
try {
|
|
@@ -2873,6 +3004,6 @@ async function removeSessionFile() {
|
|
|
2873
3004
|
await rm(authSessionPath(), { force: true });
|
|
2874
3005
|
}
|
|
2875
3006
|
//#endregion
|
|
2876
|
-
export {
|
|
3007
|
+
export { redactPrepareStepDiagnosticsBundle as $, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as A, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as B, resolveOpenMeldDistribution as C, DAEMON_RUNTIME_CONTRACT_EPOCH as D, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as E, MAX_HEARTBEAT_INTERVAL_MS as F, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as G, REGISTER_RESPONSE_TIMEOUT_MS as H, MAX_SPACE_REQUEST_TIMEOUT_MS as I, prepareSessionResponseSchema as J, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as K, MIN_HEARTBEAT_INTERVAL_MS as L, DEFAULT_HEARTBEAT_INTERVAL_MS as M, DEFAULT_SPACE_REQUEST_TIMEOUT_MS as N, DAEMON_STREAM_CONNECT_TIMEOUT_MS as O, HEARTBEAT_RESPONSE_TIMEOUT_MS as P, prepareStepDiagnosticsBundleSchema as Q, MIN_SPACE_REQUEST_TIMEOUT_MS as R, isBinaryDistribution as S, CATALOG_SYNC_RETRY_INTERVAL_MS as T, ROUTE_CATALOG_LOAD_TIMEOUT_MS as U, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as V, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as W, prepareSessionWithTokenResponseSchema as X, prepareSessionStreamServerFrameSchema as Y, prepareSetupBootstrapWriteSchema as Z, recordInterruptedComputerAuthSessionRecoveryFailure as _, beginAuthSessionTransition as a, updateAuthSessionActiveOrganization as b, getAuthSessionMetadata as c, getInterruptedComputerAuthSessionRecovery as d, redactPrepareStepDiagnosticsText as et, hasPendingComputerSetupContinuation as f, onAuthSessionCredentialObservation as g, onAuthSessionCredentialAvailable as h, assertAuthSessionMutationAvailable as i, DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS as j, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as k, getAuthSessionState as l, normalizeStoredActiveOrganization as m, AuthSessionRecoveryInProgressError as n, clearAuthSession as o, markInterruptedComputerAuthSessionRecovery as p, PREPARE_STEP_DIAGNOSTICS_MAX_CHARS as q, AuthSessionTransitionConflictError as r, completeInterruptedComputerAuthSessionRecovery as s, AuthSessionChangedBeforeTransitionError as t, redactPrepareStepDiagnosticsValue as tt, getCurrentAuthOwnerUserId as u, resumeInterruptedComputerSetup as v, resolveAuthSessionExpiryEligibility as w, runMacOsNativeKeychainHelperIfRequested as x, setAuthSession as y, OPENCLAW_CLI_TIMEOUT_MS as z };
|
|
2877
3008
|
|
|
2878
|
-
//# sourceMappingURL=auth-session-
|
|
3009
|
+
//# sourceMappingURL=auth-session-BjSqMLTz.js.map
|