@m1a0rz/agent-identity 0.5.1 → 0.5.2-cs
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/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +177 -24
- package/dist/src/actions/identity-actions.d.ts.map +1 -1
- package/dist/src/actions/identity-actions.js +172 -23
- package/dist/src/local-server/handlers.d.ts.map +1 -1
- package/dist/src/local-server/handlers.js +6 -1
- package/dist/src/preflight/plugin-preflight.d.ts +9 -0
- package/dist/src/preflight/plugin-preflight.d.ts.map +1 -1
- package/dist/src/preflight/plugin-preflight.js +22 -8
- package/dist/src/preflight/plugin-state.d.ts.map +1 -1
- package/dist/src/preflight/plugin-state.js +10 -4
- package/dist/src/services/identity-client.d.ts +59 -1
- package/dist/src/services/identity-client.d.ts.map +1 -1
- package/dist/src/services/identity-client.js +720 -93
- package/dist/src/services/identity-credentials.d.ts +1 -0
- package/dist/src/services/identity-credentials.d.ts.map +1 -1
- package/dist/src/services/identity-credentials.js +1 -23
- package/dist/src/services/identity-service.d.ts +3 -0
- package/dist/src/services/identity-service.d.ts.map +1 -1
- package/dist/src/services/identity-service.js +1 -0
- package/dist/src/store/credential-env-snapshot.d.ts.map +1 -1
- package/dist/src/store/credential-env-snapshot.js +2 -0
- package/dist/src/store/encryption.d.ts.map +1 -1
- package/dist/src/store/encryption.js +15 -11
- package/dist/src/store/tool-approval-store.d.ts +40 -0
- package/dist/src/store/tool-approval-store.d.ts.map +1 -0
- package/dist/src/store/tool-approval-store.js +162 -0
- package/dist/src/tools/identity-approve-tool.d.ts +15 -0
- package/dist/src/tools/identity-approve-tool.d.ts.map +1 -0
- package/dist/src/tools/identity-approve-tool.js +51 -0
- package/dist/src/types.d.ts +18 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/approval-channel.d.ts +7 -0
- package/dist/src/utils/approval-channel.d.ts.map +1 -0
- package/dist/src/utils/approval-channel.js +28 -0
- package/dist/src/utils/trust-anchor.d.ts +2 -0
- package/dist/src/utils/trust-anchor.d.ts.map +1 -0
- package/dist/src/utils/trust-anchor.js +48 -0
- package/dist/src/variant.d.ts +16 -0
- package/dist/src/variant.d.ts.map +1 -0
- package/dist/src/variant.js +18 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,7 @@
|
|
|
10
10
|
* - Tools: identity_whoami, identity_logout
|
|
11
11
|
*/
|
|
12
12
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
13
|
-
|
|
13
|
+
declare function registerImpl(api: OpenClawPluginApi): void;
|
|
14
|
+
declare const _default: typeof registerImpl;
|
|
15
|
+
export default _default;
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,qBAAqB,CAAC;AAsvB3E,iBAAS,YAAY,CAAC,GAAG,EAAE,iBAAiB,QAqC3C;wBAKwC,OAAO,YAAY;AAA5D,wBAA6D"}
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ import { createToolResultPersistHandler } from "./src/hooks/tool-result-persist.
|
|
|
30
30
|
import { createAfterToolCallHandler } from "./src/hooks/after-tool-call.js";
|
|
31
31
|
import * as skillPathStore from "./src/store/skill-path-store.js";
|
|
32
32
|
import { createOIDCCallbackHandler, createOIDCCallbackHandlerLazy, } from "./src/routes/oidc-login.js";
|
|
33
|
-
import { IdentityClient, resolveOIDCConfig, } from "./src/services/identity-client.js";
|
|
33
|
+
import { IdentityClient, IdentityDataPlaneClient, resolveOIDCConfig, } from "./src/services/identity-client.js";
|
|
34
34
|
import { IdentityService } from "./src/services/identity-service.js";
|
|
35
35
|
import { sendNotificationFeishu } from "./src/services/send-notification-feishu.js";
|
|
36
36
|
import { createIdentityConfigTool } from "./src/tools/identity-config.js";
|
|
@@ -55,7 +55,52 @@ import { createSessionPutHandler, createSessionGetHandler, } from "./src/gateway
|
|
|
55
55
|
import { logDebug, logInfo, logWarn } from "./src/utils/logger.js";
|
|
56
56
|
import { initEncryptionKey } from "./src/store/encryption.js";
|
|
57
57
|
import { startIdentitySocket, stopIdentitySocket } from "./src/local-server/identity-socket.js";
|
|
58
|
+
import fs from "node:fs";
|
|
59
|
+
import path from "node:path";
|
|
58
60
|
const PLUGIN_STORE_DIR = "~/.openclaw/plugins/identity";
|
|
61
|
+
let waitActivated = false;
|
|
62
|
+
function readPluginConfigFromStore(storeDir) {
|
|
63
|
+
try {
|
|
64
|
+
const p = path.join(storeDir, "config.json");
|
|
65
|
+
if (!fs.existsSync(p))
|
|
66
|
+
return null;
|
|
67
|
+
const raw = fs.readFileSync(p, "utf8");
|
|
68
|
+
const data = JSON.parse(raw);
|
|
69
|
+
return data ?? null;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function parseServerEndpoint(pluginConfig) {
|
|
76
|
+
const serviceId = pluginConfig.identity?.serviceId?.trim() ?? "id";
|
|
77
|
+
const region = pluginConfig.identity?.region?.trim() ?? "cn-beijing";
|
|
78
|
+
const userPoolId = pluginConfig.userpool?.userPoolId?.trim();
|
|
79
|
+
if (userPoolId) {
|
|
80
|
+
const userPoolEndpoint = `https://userpool-${userPoolId}.userpool.auth.${serviceId}.${region}.volces.com`;
|
|
81
|
+
pluginConfig.userpool = { ...(pluginConfig.userpool ?? {}), userPoolEndpoint };
|
|
82
|
+
}
|
|
83
|
+
const workloadPoolId = pluginConfig?.identity?.workloadPoolId?.trim() ??
|
|
84
|
+
pluginConfig.identity?.workloadPoolName?.trim();
|
|
85
|
+
if (workloadPoolId) {
|
|
86
|
+
const workloadEndpoint = `https://auth.${serviceId}.${region}.volces.com/workloadpool/${workloadPoolId}`;
|
|
87
|
+
pluginConfig.identity = { ...(pluginConfig.identity ?? {}), workloadEndpoint };
|
|
88
|
+
}
|
|
89
|
+
const endpoint = `https://auth.${serviceId}.${region}.volces.com/public/v1`;
|
|
90
|
+
pluginConfig.identity = { ...(pluginConfig.identity ?? {}), endpoint };
|
|
91
|
+
}
|
|
92
|
+
function mergePluginConfig(target, patch) {
|
|
93
|
+
Object.assign(target, patch);
|
|
94
|
+
if (patch.identity) {
|
|
95
|
+
target.identity = { ...(target.identity ?? {}), ...patch.identity };
|
|
96
|
+
}
|
|
97
|
+
if (patch.userpool) {
|
|
98
|
+
target.userpool = { ...(target.userpool ?? {}), ...patch.userpool };
|
|
99
|
+
}
|
|
100
|
+
if (patch.authz) {
|
|
101
|
+
target.authz = { ...(target.authz ?? {}), ...patch.authz };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
59
104
|
/**
|
|
60
105
|
* Whether Identity should be enabled.
|
|
61
106
|
*/
|
|
@@ -75,9 +120,28 @@ function hasAnyIdentityConfig(identity) {
|
|
|
75
120
|
identity.audience?.length ||
|
|
76
121
|
identity.durationSeconds);
|
|
77
122
|
}
|
|
78
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Guard against jiti module duplication.
|
|
125
|
+
*
|
|
126
|
+
* OpenClaw ≥ v2026.3.28 may create multiple jiti instances with independent
|
|
127
|
+
* module caches. If this file is loaded twice, module-level state (Maps,
|
|
128
|
+
* flags, cached promises) in transitive imports splits into two copies and
|
|
129
|
+
* silently diverges. By pinning the register function on globalThis, the
|
|
130
|
+
* second load re-exports the first load's function, whose closures reference
|
|
131
|
+
* the first module graph — keeping all 27+ mutable module-level variables in
|
|
132
|
+
* a single, consistent copy.
|
|
133
|
+
*/
|
|
134
|
+
const PLUGIN_REGISTER_KEY = Symbol.for("openclaw-identity.pluginRegister");
|
|
135
|
+
function registerImplRun(api) {
|
|
79
136
|
const pluginConfig = (api.pluginConfig ?? {});
|
|
80
137
|
const storeDir = api.resolvePath(PLUGIN_STORE_DIR);
|
|
138
|
+
if (pluginConfig.identity?.pluginType === "clawsentry" || pluginConfig.identity?.pluginType === "private") {
|
|
139
|
+
const data = readPluginConfigFromStore(storeDir);
|
|
140
|
+
if (data && typeof data === "object") {
|
|
141
|
+
mergePluginConfig(pluginConfig, data);
|
|
142
|
+
}
|
|
143
|
+
parseServerEndpoint(pluginConfig);
|
|
144
|
+
}
|
|
81
145
|
initEncryptionKey(storeDir);
|
|
82
146
|
const identityCfg = pluginConfig.identity;
|
|
83
147
|
setPersonalSessionMode(identityCfg?.personalSessionMode === true);
|
|
@@ -87,21 +151,41 @@ export default function register(api) {
|
|
|
87
151
|
const hasIdentity = hasAnyIdentityConfig(identityCfg);
|
|
88
152
|
const userpool = pluginConfig.userpool;
|
|
89
153
|
const identityClient = hasIdentity
|
|
90
|
-
?
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
154
|
+
? (pluginConfig.identity?.pluginType === "clawsentry"
|
|
155
|
+
? new IdentityDataPlaneClient({
|
|
156
|
+
endpoint: identityCfg?.endpoint,
|
|
157
|
+
regionMetadataUrl: identityCfg?.regionMetadataUrl,
|
|
158
|
+
accessKeyId: identityCfg?.accessKeyId,
|
|
159
|
+
secretAccessKey: identityCfg?.secretAccessKey,
|
|
160
|
+
sessionToken: identityCfg?.sessionToken,
|
|
161
|
+
credentialsFile: identityCfg?.credentialsFile,
|
|
162
|
+
credentialsMetadataUrl: identityCfg?.credentialsMetadataUrl,
|
|
163
|
+
roleTrn: identityCfg?.roleTrn,
|
|
164
|
+
serviceCode: "id",
|
|
165
|
+
storeDir,
|
|
166
|
+
workloadName: identityCfg?.workloadName,
|
|
167
|
+
workloadEndpoint: identityCfg?.workloadEndpoint,
|
|
168
|
+
trustAnchorName: identityCfg?.trustAnchorName,
|
|
169
|
+
audience: identityCfg?.audience,
|
|
170
|
+
})
|
|
171
|
+
: new IdentityClient({
|
|
172
|
+
endpoint: identityCfg?.endpoint,
|
|
173
|
+
regionMetadataUrl: identityCfg?.regionMetadataUrl,
|
|
174
|
+
accessKeyId: identityCfg?.accessKeyId,
|
|
175
|
+
secretAccessKey: identityCfg?.secretAccessKey,
|
|
176
|
+
sessionToken: identityCfg?.sessionToken,
|
|
177
|
+
credentialsFile: identityCfg?.credentialsFile,
|
|
178
|
+
credentialsMetadataUrl: identityCfg?.credentialsMetadataUrl,
|
|
179
|
+
roleTrn: identityCfg?.roleTrn,
|
|
180
|
+
serviceCode: "id",
|
|
181
|
+
}))
|
|
101
182
|
: {
|
|
102
183
|
getWorkloadAccessTokenForJWT: async () => {
|
|
103
184
|
throw new Error("Identity not configured.");
|
|
104
185
|
},
|
|
186
|
+
getWorkloadAccessToken: async () => {
|
|
187
|
+
throw new Error("Identity not configured.");
|
|
188
|
+
},
|
|
105
189
|
getResourceOauth2Token: async () => {
|
|
106
190
|
throw new Error("Identity not configured.");
|
|
107
191
|
},
|
|
@@ -171,11 +255,13 @@ export default function register(api) {
|
|
|
171
255
|
audience: identityCfg?.audience,
|
|
172
256
|
durationSeconds: identityCfg?.durationSeconds,
|
|
173
257
|
roleTrn: identityCfg?.roleTrn,
|
|
258
|
+
trustAnchorName: identityCfg?.trustAnchorName,
|
|
259
|
+
trustAnchorToken: identityCfg?.trustAnchorToken,
|
|
174
260
|
});
|
|
175
261
|
const dynamicOidcEnabled = !!(userpool?.userPoolName &&
|
|
176
262
|
userpool?.clientName &&
|
|
177
263
|
userpool?.callbackUrl &&
|
|
178
|
-
hasIdentity);
|
|
264
|
+
hasIdentity) || !!(userpool?.clientId && userpool?.clientSecret);
|
|
179
265
|
const explicitOidcEnabled = !!(userpool?.discoveryUrl &&
|
|
180
266
|
userpool?.clientId &&
|
|
181
267
|
userpool?.callbackUrl);
|
|
@@ -191,6 +277,8 @@ export default function register(api) {
|
|
|
191
277
|
redirectUri: userpool.callbackUrl,
|
|
192
278
|
scope: userpool.scope ?? "openid profile email offline_access",
|
|
193
279
|
autoCreate: userpool.autoCreate ?? true,
|
|
280
|
+
userPoolConfig: userpool,
|
|
281
|
+
pluginType: identityCfg?.pluginType,
|
|
194
282
|
});
|
|
195
283
|
return cached;
|
|
196
284
|
};
|
|
@@ -492,10 +580,13 @@ export default function register(api) {
|
|
|
492
580
|
api.registerGatewayMethod("identity.session.get", createSessionGetHandler(sessionMethodDeps));
|
|
493
581
|
logInfo(api.logger, "gateway methods: identity.session.put, identity.session.get (webchat session exchange)");
|
|
494
582
|
}
|
|
495
|
-
// Preflight:
|
|
496
|
-
//
|
|
583
|
+
// Preflight: deferred to gateway_start hook so all subsystems (gateway,
|
|
584
|
+
// plugins, channels, …) have finished their synchronous plugin loading.
|
|
585
|
+
// Running inside register() would race against the next subsystem's sync
|
|
586
|
+
// load, whose event-loop blocking delays our fetch response callbacks and
|
|
587
|
+
// causes false timeouts (observed: ListUserPools 6836 ms → 55 ms once warm).
|
|
497
588
|
const authzEnabled = !!(authz?.agentCheck || authz?.toolCheck || authz?.requireRiskApproval);
|
|
498
|
-
|
|
589
|
+
const preflightDeps = {
|
|
499
590
|
pluginConfig,
|
|
500
591
|
identityClient,
|
|
501
592
|
hasIdentity,
|
|
@@ -517,14 +608,29 @@ export default function register(api) {
|
|
|
517
608
|
authzEnabled,
|
|
518
609
|
namespaceName: authz?.namespaceName ?? "default",
|
|
519
610
|
logger: api.logger,
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
611
|
+
};
|
|
612
|
+
const runPreflightSafe = async () => {
|
|
613
|
+
try {
|
|
614
|
+
if (identityCfg?.pluginType === "clawsentry")
|
|
615
|
+
return;
|
|
616
|
+
const result = await runPluginPreflight(preflightDeps);
|
|
617
|
+
if (!result.ok) {
|
|
618
|
+
pluginState.degraded = true;
|
|
619
|
+
pluginState.failures = result.failures;
|
|
620
|
+
}
|
|
524
621
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
622
|
+
catch (err) {
|
|
623
|
+
logWarn(api.logger, `[identity] preflight threw unexpectedly: ${String(err)}`);
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
if (waitActivated) {
|
|
627
|
+
runPreflightSafe();
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
api.on("gateway_start", async () => {
|
|
631
|
+
await runPreflightSafe();
|
|
632
|
+
});
|
|
633
|
+
}
|
|
528
634
|
// Local UDS server: lets other processes on the same machine retrieve
|
|
529
635
|
// TIP tokens via HTTP-over-UDS (no network exposure, 0600 socket).
|
|
530
636
|
// Registered as a proper service so OpenClaw manages start/stop lifecycle.
|
|
@@ -551,3 +657,50 @@ export default function register(api) {
|
|
|
551
657
|
});
|
|
552
658
|
}
|
|
553
659
|
}
|
|
660
|
+
function registerImpl(api) {
|
|
661
|
+
const pluginConfig = (api.pluginConfig ?? {});
|
|
662
|
+
const storeDir = api.resolvePath(PLUGIN_STORE_DIR);
|
|
663
|
+
const identityCfg = pluginConfig.identity;
|
|
664
|
+
if (identityCfg?.pluginType === "clawsentry" || identityCfg?.pluginType === "private") {
|
|
665
|
+
logInfo(api.logger, `${identityCfg?.pluginType} plugin mode`);
|
|
666
|
+
try {
|
|
667
|
+
const data = readPluginConfigFromStore(storeDir);
|
|
668
|
+
if (data?.identity?.activeEnabled) {
|
|
669
|
+
logInfo(api.logger, "clawsentry already activeEnabled,go to registerImplRun");
|
|
670
|
+
registerImplRun(api);
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
api.on("gateway_start", () => {
|
|
674
|
+
const timer = setInterval(() => {
|
|
675
|
+
try {
|
|
676
|
+
logInfo(api.logger, "waiting clawsentry activeEnabled");
|
|
677
|
+
if (waitActivated)
|
|
678
|
+
return;
|
|
679
|
+
const d = readPluginConfigFromStore(storeDir);
|
|
680
|
+
if (d?.identity?.activeEnabled) {
|
|
681
|
+
logInfo(api.logger, "waiting clawsentry activeEnabled finished, start registerImpl");
|
|
682
|
+
waitActivated = true;
|
|
683
|
+
clearInterval(timer);
|
|
684
|
+
registerImplRun(api);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
catch (e) {
|
|
688
|
+
logWarn(api.logger, `waiting activeEnabled error: ${String(e)}`);
|
|
689
|
+
}
|
|
690
|
+
}, 5_000);
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
catch (err) {
|
|
694
|
+
logWarn(api.logger, `registerImpl: merge config.json failed: ${String(err)}`);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
logInfo(api.logger, "arkclaw plugin mode");
|
|
699
|
+
registerImplRun(api);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
const g = globalThis;
|
|
703
|
+
if (!g[PLUGIN_REGISTER_KEY]) {
|
|
704
|
+
g[PLUGIN_REGISTER_KEY] = registerImpl;
|
|
705
|
+
}
|
|
706
|
+
export default g[PLUGIN_REGISTER_KEY];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-actions.d.ts","sourceRoot":"","sources":["../../../src/actions/identity-actions.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAgB/E,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"identity-actions.d.ts","sourceRoot":"","sources":["../../../src/actions/identity-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,18 +18,149 @@ import { getOrRefreshTIPToken } from "../services/tip-with-refresh.js";
|
|
|
18
18
|
import { fetchOIDCDiscovery, buildAuthorizationUrl, generateState, generatePKCE, generateNonce, } from "../services/oidc-client.js";
|
|
19
19
|
import { loadCredentialEnvBindings, loadAllCredentialEnvBindings, setCredentialEnvBinding, deleteCredentialEnvBinding, } from "../store/credential-env-bindings.js";
|
|
20
20
|
import { loadCredentials, setCredential, getCredential, deleteCredentialsForSession, } from "../store/credential-store.js";
|
|
21
|
-
import { deleteSession } from "../store/session-store.js";
|
|
21
|
+
import { deleteSession, setSession } from "../store/session-store.js";
|
|
22
22
|
import { getSessionWithRefresh } from "../services/session-refresh.js";
|
|
23
23
|
import { createState } from "../store/oidc-state-store.js";
|
|
24
24
|
import { getAllTIPTokens, deleteTIPToken } from "../store/tip-store.js";
|
|
25
25
|
import { extractDelegationChainFromJwt } from "../utils/auth.js";
|
|
26
26
|
import { resolveAgentId, } from "../utils/derive-session-key.js";
|
|
27
|
+
async function deviceAuthorizationRequest(deps) {
|
|
28
|
+
const issuer = deps.pluginConfig?.userpool?.userPoolEndpoint;
|
|
29
|
+
let deviceAuthEndpoint = issuer + "/device_authorization";
|
|
30
|
+
let tokenEndpoint = issuer + "/token";
|
|
31
|
+
const discoveryUrl = `${issuer}/.well-known/openid-configuration`;
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch(discoveryUrl);
|
|
34
|
+
if (res.ok) {
|
|
35
|
+
const doc = (await res.json());
|
|
36
|
+
const da = doc["device_authorization_endpoint"];
|
|
37
|
+
const te = doc["token_endpoint"];
|
|
38
|
+
if (typeof da === "string" && da)
|
|
39
|
+
deviceAuthEndpoint = da;
|
|
40
|
+
if (typeof te === "string" && te)
|
|
41
|
+
tokenEndpoint = te;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
logWarn(deps.logger, `Failed to fetch discoveryUrl: ${discoveryUrl}`);
|
|
46
|
+
}
|
|
47
|
+
const scope = deps.pluginConfig?.userpool?.scope ?? "openid profile email offline_access";
|
|
48
|
+
const clientId = deps.pluginConfig?.userpool?.clientId ?? "";
|
|
49
|
+
const clientSecret = deps.pluginConfig?.userpool?.clientSecret ?? "";
|
|
50
|
+
const body = new URLSearchParams();
|
|
51
|
+
body.set("scope", scope);
|
|
52
|
+
body.set("client_id", clientId);
|
|
53
|
+
if (clientSecret)
|
|
54
|
+
body.set("client_secret", clientSecret);
|
|
55
|
+
const resp = await fetch(deviceAuthEndpoint, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
58
|
+
body: body.toString(),
|
|
59
|
+
});
|
|
60
|
+
if (!resp.ok) {
|
|
61
|
+
const text = await resp.text();
|
|
62
|
+
throw new Error(`Device authorization request failed ${resp.status}: ${text}`);
|
|
63
|
+
}
|
|
64
|
+
const json = (await resp.json());
|
|
65
|
+
const deviceCode = json.device_code ?? "";
|
|
66
|
+
const tokenUrl = tokenEndpoint;
|
|
67
|
+
const verificationUri = json.verification_uri_complete ??
|
|
68
|
+
(json.verification_uri && json.user_code
|
|
69
|
+
? `${json.verification_uri}?user_code=${encodeURIComponent(json.user_code)}`
|
|
70
|
+
: null);
|
|
71
|
+
if (!verificationUri) {
|
|
72
|
+
throw new Error("Device authorization response missing verification URI");
|
|
73
|
+
}
|
|
74
|
+
return { verificationUri, deviceCode, tokenUrl, interval: json.interval ?? 5, expiresIn: json.expires_in };
|
|
75
|
+
}
|
|
76
|
+
function startDeviceTokenPolling(params) {
|
|
77
|
+
let intervalMs = Math.max(1000, Math.floor((params.intervalSec ?? 10) * 1000));
|
|
78
|
+
let stopped = false;
|
|
79
|
+
const schedule = (delayMs) => {
|
|
80
|
+
setTimeout(async () => {
|
|
81
|
+
if (stopped)
|
|
82
|
+
return;
|
|
83
|
+
try {
|
|
84
|
+
const tokenBody = new URLSearchParams();
|
|
85
|
+
tokenBody.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
|
|
86
|
+
tokenBody.set("device_code", params.deviceCode);
|
|
87
|
+
tokenBody.set("client_id", params.clientId);
|
|
88
|
+
if (params.clientSecret)
|
|
89
|
+
tokenBody.set("client_secret", params.clientSecret);
|
|
90
|
+
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
|
|
91
|
+
if (params.clientSecret) {
|
|
92
|
+
const creds = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString("base64");
|
|
93
|
+
headers["Authorization"] = `Basic ${creds}`;
|
|
94
|
+
}
|
|
95
|
+
const r = await fetch(params.tokenUrl, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers,
|
|
98
|
+
body: tokenBody.toString(),
|
|
99
|
+
});
|
|
100
|
+
const txt = await r.text();
|
|
101
|
+
let j;
|
|
102
|
+
try {
|
|
103
|
+
j = JSON.parse(txt);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
j = {};
|
|
107
|
+
}
|
|
108
|
+
if (r.ok && j["id_token"]) {
|
|
109
|
+
const idToken = j["id_token"];
|
|
110
|
+
const refreshToken = j["refresh_token"];
|
|
111
|
+
const expiresIn = typeof j["expires_in"] === "number" ? j["expires_in"] : 3600;
|
|
112
|
+
if (idToken) {
|
|
113
|
+
let sub = null;
|
|
114
|
+
try {
|
|
115
|
+
const parts = idToken.split(".");
|
|
116
|
+
if (parts.length >= 2) {
|
|
117
|
+
const b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
118
|
+
const payloadStr = Buffer.from(b64, "base64").toString("utf8");
|
|
119
|
+
const payload = JSON.parse(payloadStr);
|
|
120
|
+
if (typeof payload.sub === "string")
|
|
121
|
+
sub = payload.sub;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
}
|
|
126
|
+
if (sub) {
|
|
127
|
+
await setSession(params.storeDir, params.sessionKey, {
|
|
128
|
+
userToken: idToken,
|
|
129
|
+
sub,
|
|
130
|
+
refreshToken: refreshToken,
|
|
131
|
+
loginAt: Date.now(),
|
|
132
|
+
expiresAt: Date.now() + expiresIn * 1000,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
stopped = true;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const err = j["error"] ?? "";
|
|
140
|
+
if (err === "authorization_pending") {
|
|
141
|
+
schedule(intervalMs);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (err === "slow_down") {
|
|
145
|
+
intervalMs += 5000;
|
|
146
|
+
schedule(intervalMs);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
stopped = true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
schedule(intervalMs);
|
|
153
|
+
}
|
|
154
|
+
}, delayMs);
|
|
155
|
+
};
|
|
156
|
+
schedule(intervalMs);
|
|
157
|
+
}
|
|
27
158
|
function inferFlowFromProvider(info) {
|
|
28
159
|
if (info.Type === "api_key")
|
|
29
160
|
return "apikey";
|
|
30
161
|
if (info.Type === "oauth2" && info.Flow === "M2M")
|
|
31
162
|
return "oauth2-m2m";
|
|
32
|
-
return "
|
|
163
|
+
return "apikey";
|
|
33
164
|
}
|
|
34
165
|
function buildTipRefreshOptions(deps, ctxAgentId, errorHolder) {
|
|
35
166
|
if (!deps.getOidcConfigForRefresh)
|
|
@@ -144,27 +275,45 @@ export async function runLogin(deps, sessionKey, options) {
|
|
|
144
275
|
};
|
|
145
276
|
}
|
|
146
277
|
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
278
|
+
let authUrl = "";
|
|
279
|
+
if (deps.pluginConfig?.userpool?.grantType === "device_code") {
|
|
280
|
+
const { verificationUri, deviceCode, tokenUrl, interval } = await deviceAuthorizationRequest(deps);
|
|
281
|
+
authUrl = verificationUri;
|
|
282
|
+
const clientId = deps.pluginConfig?.userpool?.clientId ?? "";
|
|
283
|
+
const clientSecret = deps.pluginConfig?.userpool?.clientSecret ?? "";
|
|
284
|
+
startDeviceTokenPolling({
|
|
285
|
+
tokenUrl,
|
|
286
|
+
deviceCode,
|
|
287
|
+
clientId,
|
|
288
|
+
clientSecret,
|
|
289
|
+
storeDir: deps.storeDir,
|
|
290
|
+
sessionKey,
|
|
291
|
+
intervalSec: interval,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
const oidcConfig = await getOidcConfig();
|
|
296
|
+
const discovery = await fetchOIDCDiscovery(oidcConfig.discoveryUrl);
|
|
297
|
+
// Prefer explicit config, then fall back to what resolveOIDCConfig already cached
|
|
298
|
+
const identityProvider = deps.pluginConfig?.userpool?.identityProvider ?? oidcConfig.identityProvider;
|
|
299
|
+
const workloadName = deps.configWorkloadName;
|
|
300
|
+
const state = await generateState({ target: workloadName });
|
|
301
|
+
const { codeVerifier, codeChallenge } = await generatePKCE();
|
|
302
|
+
const nonce = await generateNonce();
|
|
303
|
+
createState(sessionKey, "", state, deliveryTarget, { codeVerifier, nonce });
|
|
304
|
+
authUrl = buildAuthorizationUrl({
|
|
305
|
+
authorizationEndpoint: discovery.authorization_endpoint,
|
|
306
|
+
clientId: oidcConfig.clientId,
|
|
307
|
+
redirectUri: oidcConfig.callbackUrl,
|
|
308
|
+
scope: oidcConfig.scope ?? "openid profile email offline_access",
|
|
309
|
+
state,
|
|
310
|
+
codeChallenge,
|
|
311
|
+
codeChallengeMethod: "S256",
|
|
312
|
+
nonce,
|
|
313
|
+
redirectRelayUri: deps.pluginConfig?.userpool?.useRelayCallback ? oidcConfig.callbackUrl : undefined,
|
|
314
|
+
identityProvider,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
168
317
|
logInfo(logger, `login returning IdP URL for sessionKey=${sessionKey.slice(0, 24)}...`);
|
|
169
318
|
return { kind: "auth_url", authUrl };
|
|
170
319
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/local-server/handlers.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/local-server/handlers.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAUrD,oEAAoE;AACpE,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrH,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,cAAc,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9D,MAAM,EAAE;QACN,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC9B,CAAC;IACF,oEAAoE;IACpE,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACvD,CAAC;AAwBF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,IAc1C,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CA+IxE"}
|
|
@@ -17,6 +17,7 @@ import { getOrRefreshTIPToken } from "../services/tip-with-refresh.js";
|
|
|
17
17
|
import { getSessionWithRefresh } from "../services/session-refresh.js";
|
|
18
18
|
import { getAllTIPTokens } from "../store/tip-store.js";
|
|
19
19
|
import { isPersonalSessionModeEnabled, PERSONAL_SESSION_STORAGE_KEY, } from "../store/sender-session-store.js";
|
|
20
|
+
import { pluginState } from "../preflight/plugin-state.js";
|
|
20
21
|
const MAIN_SESSION_KEY = "agent:main:main";
|
|
21
22
|
function resolveMainSessionKey() {
|
|
22
23
|
if (isPersonalSessionModeEnabled())
|
|
@@ -129,7 +130,11 @@ export function createRequestHandler(deps) {
|
|
|
129
130
|
ttlSec: Math.max(0, Math.floor((entry.expiresAt - now) / 1000)),
|
|
130
131
|
}));
|
|
131
132
|
json(res, 200, {
|
|
132
|
-
ok:
|
|
133
|
+
ok: !pluginState.degraded,
|
|
134
|
+
degraded: pluginState.degraded,
|
|
135
|
+
failures: pluginState.failures.length > 0
|
|
136
|
+
? pluginState.failures.map((f) => ({ check: f.check, reason: f.reason }))
|
|
137
|
+
: undefined,
|
|
133
138
|
personalSessionMode: isPersonalSessionModeEnabled(),
|
|
134
139
|
mainSessionKey: resolveMainSessionKey(),
|
|
135
140
|
activeSessions: sessions.length,
|
|
@@ -61,5 +61,14 @@ export type PreflightDeps = {
|
|
|
61
61
|
info?: (msg: string) => void;
|
|
62
62
|
};
|
|
63
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Run preflight checks.
|
|
66
|
+
*
|
|
67
|
+
* Expected to be called from the `gateway_start` hook, which fires after
|
|
68
|
+
* ALL subsystems (gateway, plugins, channels, …) have finished their
|
|
69
|
+
* synchronous plugin loading and the server is listening. This guarantees
|
|
70
|
+
* the event loop is free and network requests complete promptly — no yield
|
|
71
|
+
* loops or retry hacks needed.
|
|
72
|
+
*/
|
|
64
73
|
export declare function runPluginPreflight(deps: PreflightDeps): Promise<PreflightResult>;
|
|
65
74
|
//# sourceMappingURL=plugin-preflight.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-preflight.d.ts","sourceRoot":"","sources":["../../../src/preflight/plugin-preflight.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAG9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAO9E,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,4CAA4C,CAC1D,GAAG,EAAE,YAAY,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA0BxC;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,qFAAqF;IACrF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,+CAA+C;IAC/C,cAAc,EAAE,uBAAuB,CAAC;IACxC,8DAA8D;IAC9D,WAAW,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;QAC7B,mBAAmB;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,oBAAoB;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACzE,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-preflight.d.ts","sourceRoot":"","sources":["../../../src/preflight/plugin-preflight.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAG9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAO9E,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,4CAA4C,CAC1D,GAAG,EAAE,YAAY,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA0BxC;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,qFAAqF;IACrF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,+CAA+C;IAC/C,cAAc,EAAE,uBAAuB,CAAC;IACxC,8DAA8D;IAC9D,WAAW,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;QAC7B,mBAAmB;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,oBAAoB;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACzE,CAAC;AA2JF;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAwEtF"}
|