
























@@ -74,6 +74,7 @@ type SelectedConnectAuth = {
7474authBootstrapToken?: string;
7575authDeviceToken?: string;
7676authPassword?: string;
77+authApprovalRuntimeToken?: string;
7778signatureToken?: string;
7879resolvedDeviceToken?: string;
7980storedToken?: string;
@@ -130,6 +131,7 @@ export type GatewayClientOptions = {
130131bootstrapToken?: string;
131132deviceToken?: string;
132133password?: string;
134+approvalRuntimeToken?: string;
133135instanceId?: string;
134136clientName?: GatewayClientName;
135137clientDisplayName?: string;
@@ -221,6 +223,8 @@ export class GatewayClient {
221223private reconnectTimer: NodeJS.Timeout | null = null;
222224private pendingDeviceTokenRetry = false;
223225private deviceTokenRetryBudgetUsed = false;
226+private approvalRuntimeTokenCompatibilityDisabled = false;
227+private approvalRuntimeTokenRetryBudgetUsed = false;
224228private pendingStartupReconnectDelayMs: number | null = null;
225229private pendingConnectErrorDetailCode: string | null = null;
226230private pendingConnectErrorDetails: unknown = null;
@@ -506,6 +510,7 @@ export class GatewayClient {
506510 authBootstrapToken,
507511 authDeviceToken,
508512 authPassword,
513+ authApprovalRuntimeToken,
509514 signatureToken,
510515 resolvedDeviceToken,
511516 storedToken,
@@ -516,12 +521,17 @@ export class GatewayClient {
516521this.pendingDeviceTokenRetry = false;
517522}
518523const auth =
519-authToken || authBootstrapToken || authPassword || resolvedDeviceToken
524+authToken ||
525+authBootstrapToken ||
526+authPassword ||
527+resolvedDeviceToken ||
528+authApprovalRuntimeToken
520529 ? {
521530token: authToken,
522531bootstrapToken: authBootstrapToken,
523532deviceToken: authDeviceToken ?? resolvedDeviceToken,
524533password: authPassword,
534+approvalRuntimeToken: authApprovalRuntimeToken,
525535}
526536 : undefined;
527537const signedAtMs = Date.now();
@@ -646,6 +656,19 @@ export class GatewayClient {
646656this.ws?.close(1013, "gateway starting");
647657return;
648658}
659+if (
660+this.shouldRetryWithoutApprovalRuntimeToken({
661+error: err,
662+ authApprovalRuntimeToken,
663+})
664+) {
665+this.approvalRuntimeTokenCompatibilityDisabled = true;
666+this.approvalRuntimeTokenRetryBudgetUsed = true;
667+this.backoffMs = Math.min(this.backoffMs, 250);
668+logDebug("gateway rejected approval runtime auth field; retrying without it");
669+this.ws?.close(1008, "connect retry");
670+return;
671+}
649672this.opts.onConnectError?.(err instanceof Error ? err : new Error(String(err)));
650673const msg = `gateway connect failed: ${String(err)}`;
651674if (this.opts.mode === GATEWAY_CLIENT_MODES.PROBE || isGatewayClientStoppedError(err)) {
@@ -763,6 +786,26 @@ export class GatewayClient {
763786);
764787}
765788789+private shouldRetryWithoutApprovalRuntimeToken(params: {
790+error: unknown;
791+authApprovalRuntimeToken?: string;
792+}): boolean {
793+if (this.approvalRuntimeTokenRetryBudgetUsed) {
794+return false;
795+}
796+if (!params.authApprovalRuntimeToken) {
797+return false;
798+}
799+if (!(params.error instanceof GatewayClientRequestError)) {
800+return false;
801+}
802+if (params.error.gatewayCode !== "INVALID_REQUEST") {
803+return false;
804+}
805+const message = normalizeLowercaseStringOrEmpty(params.error.message);
806+return message.includes("invalid connect params") && message.includes("approvalruntimetoken");
807+}
808+766809private isTrustedDeviceRetryEndpoint(): boolean {
767810const rawUrl = this.opts.url ?? "ws://127.0.0.1:18789";
768811try {
@@ -787,6 +830,9 @@ export class GatewayClient {
787830const explicitBootstrapToken = normalizeOptionalString(this.opts.bootstrapToken);
788831const explicitDeviceToken = normalizeOptionalString(this.opts.deviceToken);
789832const authPassword = normalizeOptionalString(this.opts.password);
833+const authApprovalRuntimeToken = this.approvalRuntimeTokenCompatibilityDisabled
834+ ? undefined
835+ : normalizeOptionalString(this.opts.approvalRuntimeToken);
790836const storedAuth = this.loadStoredDeviceAuth(role);
791837const storedToken = storedAuth?.token ?? null;
792838const storedScopes = storedAuth?.scopes;
@@ -819,6 +865,7 @@ export class GatewayClient {
819865 authBootstrapToken,
820866authDeviceToken: shouldUseDeviceRetryToken ? (storedToken ?? undefined) : undefined,
821867 authPassword,
868+ authApprovalRuntimeToken,
822869signatureToken: authToken ?? authBootstrapToken ?? undefined,
823870 resolvedDeviceToken,
824871storedToken: storedToken ?? undefined,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。