auramaxx 0.0.13 → 0.0.14
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/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +24 -24
- package/.next/app-path-routes-manifest.json +6 -6
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +36 -36
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/api/[...doc]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agent-requests/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/apps/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/apps/manifests/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/apps/static/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/docs/plain/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/import-from-openclaw/[channel]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/import-from-openclaw/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/import-from-openclaw/validate/[channel]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/update/route.js +7 -8
- package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/[id]/apps/[wid]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/[id]/apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/[id]/export/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/import/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/route_client-reference-manifest.js +1 -1
- package/.next/server/app/app-legacy-do-not-use/page_client-reference-manifest.js +1 -1
- package/.next/server/app/app-legacy-do-not-use.html +1 -1
- package/.next/server/app/app-legacy-do-not-use.rsc +1 -1
- package/.next/server/app/approve/[actionId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/docs/[...doc]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/health/page_client-reference-manifest.js +1 -1
- package/.next/server/app/health.html +1 -1
- package/.next/server/app/health.rsc +1 -1
- package/.next/server/app/hello/page_client-reference-manifest.js +1 -1
- package/.next/server/app/hello.html +1 -1
- package/.next/server/app/hello.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
- package/.next/server/app/privacy.html +1 -1
- package/.next/server/app/privacy.rsc +1 -1
- package/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/terms/page_client-reference-manifest.js +1 -1
- package/.next/server/app/terms.html +1 -1
- package/.next/server/app/terms.rsc +1 -1
- package/.next/server/app/yo/page.js +1 -1
- package/.next/server/app/yo/page_client-reference-manifest.js +1 -1
- package/.next/server/app/yo.html +1 -1
- package/.next/server/app/yo.rsc +2 -2
- package/.next/server/app-paths-manifest.json +6 -6
- package/.next/server/functions-config-manifest.json +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/app/{page-16dfcd1c7cc88bcc.js → page-617dd0e03d79e94f.js} +1 -1
- package/.next/static/chunks/app/yo/page-fceb03605805cb44.js +1 -0
- package/.next/trace +28 -28
- package/README.md +1 -1
- package/docs/AGENT_SETUP.md +1 -1
- package/docs/AUTH.md +1 -1
- package/docs/MCP.md +12 -0
- package/docs/SKILLS.md +1 -1
- package/docs/api/secrets/credentials.md +9 -0
- package/docs/external/POLICY.md +2 -2
- package/package.json +1 -1
- package/skills/auramaxx/SKILL.md +13 -31
- package/skills/auramaxx/docs/AGENT_SETUP.md +1 -1
- package/src/app/UnlockPageClient.tsx +9 -9
- package/src/app/api/update/route.ts +9 -10
- package/src/app/yo/page.tsx +1 -1
- package/src/server/cli/commands/agent.ts +58 -0
- package/src/server/cli/commands/init.ts +9 -9
- package/src/server/cli/lib/credential-resolve.ts +20 -1
- package/src/server/cli/lib/local-agent-trust.ts +4 -3
- package/src/server/lib/agent-profiles.ts +4 -3
- package/src/server/lib/update-check.ts +4 -0
- package/src/server/mcp/server.ts +83 -14
- package/src/server/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/src/server/routes/credentials.ts +48 -5
- package/src/server/tests/cli/agent-auth.test.ts +114 -0
- package/src/server/tests/cli/local-agent-trust.test.ts +11 -6
- package/src/server/tests/endpoints/credentials.test.ts +40 -18
- package/src/server/tests/endpoints/escalation-migration-gate.test.ts +1 -1
- package/src/server/tests/lib/agent-profiles.test.ts +6 -0
- package/src/server/tests/lib/update-check.test.ts +9 -1
- package/.next/static/chunks/app/yo/page-719dc5f213fdfb30.js +0 -1
- /package/.next/static/{WshFGr6RxGYP6AbWuT9OG → 8ep63d3doVXsmbm1zj5k5}/_buildManifest.js +0 -0
- /package/.next/static/{WshFGr6RxGYP6AbWuT9OG → 8ep63d3doVXsmbm1zj5k5}/_ssgManifest.js +0 -0
package/src/server/mcp/server.ts
CHANGED
|
@@ -43,7 +43,9 @@ import {
|
|
|
43
43
|
resolveDiaryDate,
|
|
44
44
|
} from '../lib/diary';
|
|
45
45
|
import {
|
|
46
|
+
canonicalizeCredentialFieldKey,
|
|
46
47
|
getCredentialFieldValue,
|
|
48
|
+
getCredentialPrimaryFieldKey,
|
|
47
49
|
NOTE_CONTENT_KEY,
|
|
48
50
|
} from '../../../shared/credential-field-schema';
|
|
49
51
|
import { defaultSecretEnvVarName, normalizeEnvVarName } from '../lib/secret-env';
|
|
@@ -1013,7 +1015,7 @@ async function resolveCredentialByName(
|
|
|
1013
1015
|
name: string,
|
|
1014
1016
|
authTokenOverride?: string,
|
|
1015
1017
|
): Promise<
|
|
1016
|
-
| { credentialId: string; credentialName: string }
|
|
1018
|
+
| { credentialId: string; credentialName: string; credentialType?: string }
|
|
1017
1019
|
| { error: string; escalation?: McpToolResponse }
|
|
1018
1020
|
> {
|
|
1019
1021
|
const base = WALLET_BASE();
|
|
@@ -1045,7 +1047,7 @@ async function resolveCredentialByName(
|
|
|
1045
1047
|
}
|
|
1046
1048
|
if (!res.ok) continue;
|
|
1047
1049
|
|
|
1048
|
-
const data = await res.json() as { credentials: Array<{ id: string; name: string; agentId: string }> };
|
|
1050
|
+
const data = await res.json() as { credentials: Array<{ id: string; name: string; type?: string; agentId: string }> };
|
|
1049
1051
|
if (!data.credentials || data.credentials.length === 0) continue;
|
|
1050
1052
|
|
|
1051
1053
|
const decision = evaluateProjectScopeAccess({
|
|
@@ -1075,7 +1077,11 @@ async function resolveCredentialByName(
|
|
|
1075
1077
|
const scopedCandidates = data.credentials.filter((c) => allowedIds.has(c.id));
|
|
1076
1078
|
if (scopedCandidates.length === 0) continue;
|
|
1077
1079
|
|
|
1078
|
-
return {
|
|
1080
|
+
return {
|
|
1081
|
+
credentialId: scopedCandidates[0].id,
|
|
1082
|
+
credentialName: scopedCandidates[0].name,
|
|
1083
|
+
credentialType: scopedCandidates[0].type,
|
|
1084
|
+
};
|
|
1079
1085
|
}
|
|
1080
1086
|
} catch (err) {
|
|
1081
1087
|
return { error: `Search failed: ${err}` };
|
|
@@ -1184,6 +1190,20 @@ function extractPrimarySecretValue(
|
|
|
1184
1190
|
return noteField || sensitiveField || fields[0]?.value || '';
|
|
1185
1191
|
}
|
|
1186
1192
|
|
|
1193
|
+
function findCredentialFieldValue(
|
|
1194
|
+
credentialType: string | undefined,
|
|
1195
|
+
fields: Array<{ key: string; value: string; type?: string; sensitive?: boolean }>,
|
|
1196
|
+
requestedField: string,
|
|
1197
|
+
): string | undefined {
|
|
1198
|
+
const trimmed = String(requestedField || '').trim();
|
|
1199
|
+
if (!trimmed) return undefined;
|
|
1200
|
+
const directMatch = fields.find((field) => field.key.toLowerCase() === trimmed.toLowerCase());
|
|
1201
|
+
if (directMatch) return directMatch.value;
|
|
1202
|
+
const canonicalKey = canonicalizeCredentialFieldKey(String(credentialType || 'custom'), trimmed).toLowerCase();
|
|
1203
|
+
const canonicalMatch = fields.find((field) => field.key.toLowerCase() === canonicalKey);
|
|
1204
|
+
return canonicalMatch?.value;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1187
1207
|
function renderSecretValue(secretValue: string, dangerPlaintext: boolean): string {
|
|
1188
1208
|
return dangerPlaintext ? secretValue : '*******';
|
|
1189
1209
|
}
|
|
@@ -1444,9 +1464,10 @@ function applyClaimResponseToPendingAuth(
|
|
|
1444
1464
|
// ── get_secret ─────────────────────────────────────────────────────────
|
|
1445
1465
|
server.tool(
|
|
1446
1466
|
'get_secret',
|
|
1447
|
-
'Look up a stored credential/secret by name or tag, inject its primary value into a default env var, and return redacted metadata unless dangerPlaintext is explicitly enabled.',
|
|
1467
|
+
'Look up a stored credential/secret by name or tag, inject its primary value (or explicit field) into a default env var, and return redacted metadata unless dangerPlaintext is explicitly enabled.',
|
|
1448
1468
|
{
|
|
1449
1469
|
name: z.string().describe('Name or tag to search for (e.g. "GitHub", "openai", "deploy")'),
|
|
1470
|
+
field: z.string().optional().describe('Optional explicit field key to read (e.g. "password", "cvv"). When omitted, reads the credential primary field.'),
|
|
1450
1471
|
command: z.array(z.string()).optional().describe('Optional command + args to spawn with injected env var (e.g. ["node", "script.js"]). If omitted, sets env var in MCP server process and returns WHATDO guidance.'),
|
|
1451
1472
|
dangerPlaintext: z.boolean().optional().describe('If true, include plaintext secret in output (unsafe). Defaults to false (masked).'),
|
|
1452
1473
|
reqId: z.string().optional().describe('Optional approval request id for one-shot claim retry binding'),
|
|
@@ -1454,11 +1475,13 @@ server.tool(
|
|
|
1454
1475
|
async (input) => {
|
|
1455
1476
|
const {
|
|
1456
1477
|
name,
|
|
1478
|
+
field,
|
|
1457
1479
|
command,
|
|
1458
1480
|
dangerPlaintext,
|
|
1459
1481
|
reqId,
|
|
1460
|
-
} = input as { name: string; command?: string[]; dangerPlaintext?: boolean; reqId?: string };
|
|
1482
|
+
} = input as { name: string; field?: string; command?: string[]; dangerPlaintext?: boolean; reqId?: string };
|
|
1461
1483
|
const revealPlaintext = dangerPlaintext === true;
|
|
1484
|
+
const requestedField = String(field || '').trim();
|
|
1462
1485
|
|
|
1463
1486
|
if (isGetSecretRateLimited()) {
|
|
1464
1487
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: 'Rate limited — too many get_secret requests. Try again in 1 minute.' }) }] };
|
|
@@ -1473,7 +1496,7 @@ server.tool(
|
|
|
1473
1496
|
const credentialNameFromBinding = authContext.mode === 'one_shot' ? authContext.binding?.credentialName : undefined;
|
|
1474
1497
|
|
|
1475
1498
|
const resolved = credentialIdFromBinding
|
|
1476
|
-
? { credentialId: credentialIdFromBinding, credentialName: credentialNameFromBinding || name }
|
|
1499
|
+
? { credentialId: credentialIdFromBinding, credentialName: credentialNameFromBinding || name, credentialType: undefined }
|
|
1477
1500
|
: await resolveCredentialByName(name, authToken);
|
|
1478
1501
|
if ('error' in resolved) {
|
|
1479
1502
|
if ('escalation' in resolved && resolved.escalation) return resolved.escalation;
|
|
@@ -1481,6 +1504,17 @@ server.tool(
|
|
|
1481
1504
|
}
|
|
1482
1505
|
|
|
1483
1506
|
const { credentialId, credentialName } = resolved;
|
|
1507
|
+
const requestedFields = requestedField
|
|
1508
|
+
? [requestedField]
|
|
1509
|
+
: resolved.credentialType
|
|
1510
|
+
? [getCredentialPrimaryFieldKey(resolved.credentialType)]
|
|
1511
|
+
: [];
|
|
1512
|
+
const readPayload = requestedFields.length > 0
|
|
1513
|
+
? { requestedFields }
|
|
1514
|
+
: {};
|
|
1515
|
+
const readBody = requestedFields.length > 0
|
|
1516
|
+
? JSON.stringify(readPayload)
|
|
1517
|
+
: undefined;
|
|
1484
1518
|
if (authContext.mode === 'one_shot' && authContext.reqId && authContext.binding) {
|
|
1485
1519
|
const bindingError = validateOneShotCredentialReadBinding({
|
|
1486
1520
|
reqId: authContext.reqId,
|
|
@@ -1499,10 +1533,12 @@ server.tool(
|
|
|
1499
1533
|
method: 'POST',
|
|
1500
1534
|
headers: {
|
|
1501
1535
|
'Authorization': `Bearer ${authToken}`,
|
|
1536
|
+
...(readBody ? { 'Content-Type': 'application/json' } : {}),
|
|
1502
1537
|
'X-Secret-Surface': 'get_secret',
|
|
1503
1538
|
'X-Credential-Name': credentialName || name,
|
|
1504
1539
|
'X-Aura-Original-Command': `mcp get_secret ${JSON.stringify(name)}`,
|
|
1505
1540
|
},
|
|
1541
|
+
...(readBody ? { body: readBody } : {}),
|
|
1506
1542
|
signal: AbortSignal.timeout(5000),
|
|
1507
1543
|
});
|
|
1508
1544
|
|
|
@@ -1516,7 +1552,7 @@ server.tool(
|
|
|
1516
1552
|
permissions: ['secret:read'],
|
|
1517
1553
|
endpoint: `/credentials/${credentialId}/read`,
|
|
1518
1554
|
method: 'POST',
|
|
1519
|
-
body:
|
|
1555
|
+
body: readPayload,
|
|
1520
1556
|
});
|
|
1521
1557
|
}
|
|
1522
1558
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Read failed (${res.status}): ${text}` }) }] };
|
|
@@ -1549,8 +1585,17 @@ server.tool(
|
|
|
1549
1585
|
}
|
|
1550
1586
|
}
|
|
1551
1587
|
|
|
1552
|
-
const
|
|
1588
|
+
const requestedValue = requestedField
|
|
1589
|
+
? findCredentialFieldValue(decrypted.type || resolved.credentialType, decrypted.fields, requestedField)
|
|
1590
|
+
: undefined;
|
|
1591
|
+
const secretValue = requestedValue !== undefined
|
|
1592
|
+
? requestedValue
|
|
1593
|
+
: extractPrimarySecretValue(decrypted.fields);
|
|
1553
1594
|
if (!secretValue) {
|
|
1595
|
+
if (requestedField && requestedValue === undefined) {
|
|
1596
|
+
const availableFields = decrypted.fields.map((entry) => entry.key).join(', ');
|
|
1597
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Field "${requestedField}" not found on credential "${credentialName || name}"`, availableFields }) }] };
|
|
1598
|
+
}
|
|
1554
1599
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Credential "${credentialName || name}" has no extractable secret value` }) }] };
|
|
1555
1600
|
}
|
|
1556
1601
|
|
|
@@ -1933,9 +1978,10 @@ server.tool(
|
|
|
1933
1978
|
// ── inject_secret ──────────────────────────────────────────────────────
|
|
1934
1979
|
server.tool(
|
|
1935
1980
|
'inject_secret',
|
|
1936
|
-
'Look up a credential by name, extract its primary secret field, and inject it into env for MCP process or a child command. Output is redacted unless dangerPlaintext is enabled.',
|
|
1981
|
+
'Look up a credential by name, extract its primary secret field (or explicit field), and inject it into env for MCP process or a child command. Output is redacted unless dangerPlaintext is enabled.',
|
|
1937
1982
|
{
|
|
1938
1983
|
name: z.string().describe('Name or tag of the credential to inject'),
|
|
1984
|
+
field: z.string().optional().describe('Optional explicit field key to inject instead of the credential primary field.'),
|
|
1939
1985
|
envVar: z.string().optional().describe('Optional environment variable name (defaults to AURA_{SECRETNAME}, e.g. "AURA_OPENAI_API_KEY")'),
|
|
1940
1986
|
command: z.array(z.string()).optional().describe('Optional command + args to spawn with injected env var (e.g. ["node", "script.js"]). If omitted, sets env var in MCP server process and returns WHATDO guidance.'),
|
|
1941
1987
|
dangerPlaintext: z.boolean().optional().describe('If true, include plaintext secret in output (unsafe). Defaults to false (masked).'),
|
|
@@ -1944,12 +1990,14 @@ server.tool(
|
|
|
1944
1990
|
async (input) => {
|
|
1945
1991
|
const {
|
|
1946
1992
|
name,
|
|
1993
|
+
field,
|
|
1947
1994
|
envVar,
|
|
1948
1995
|
command,
|
|
1949
1996
|
dangerPlaintext,
|
|
1950
1997
|
reqId,
|
|
1951
|
-
} = input as { name: string; envVar?: string; command?: string[]; dangerPlaintext?: boolean; reqId?: string };
|
|
1998
|
+
} = input as { name: string; field?: string; envVar?: string; command?: string[]; dangerPlaintext?: boolean; reqId?: string };
|
|
1952
1999
|
const revealPlaintext = dangerPlaintext === true;
|
|
2000
|
+
const requestedField = String(field || '').trim();
|
|
1953
2001
|
const resolvedEnvVar = normalizeEnvVarName(envVar || defaultSecretEnvVarName(name));
|
|
1954
2002
|
if (!resolvedEnvVar) {
|
|
1955
2003
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: 'Invalid envVar. Expected shell env var format like AURA_SECRET or GITHUB_PAT.' }) }] };
|
|
@@ -1968,7 +2016,7 @@ server.tool(
|
|
|
1968
2016
|
const credentialNameFromBinding = authContext.mode === 'one_shot' ? authContext.binding?.credentialName : undefined;
|
|
1969
2017
|
|
|
1970
2018
|
const resolved = credentialIdFromBinding
|
|
1971
|
-
? { credentialId: credentialIdFromBinding, credentialName: credentialNameFromBinding || name }
|
|
2019
|
+
? { credentialId: credentialIdFromBinding, credentialName: credentialNameFromBinding || name, credentialType: undefined }
|
|
1972
2020
|
: await resolveCredentialByName(name, authToken);
|
|
1973
2021
|
if ('error' in resolved) {
|
|
1974
2022
|
if ('escalation' in resolved && resolved.escalation) return resolved.escalation;
|
|
@@ -1976,6 +2024,17 @@ server.tool(
|
|
|
1976
2024
|
}
|
|
1977
2025
|
|
|
1978
2026
|
const base = WALLET_BASE();
|
|
2027
|
+
const requestedFields = requestedField
|
|
2028
|
+
? [requestedField]
|
|
2029
|
+
: resolved.credentialType
|
|
2030
|
+
? [getCredentialPrimaryFieldKey(resolved.credentialType)]
|
|
2031
|
+
: [];
|
|
2032
|
+
const readPayload = requestedFields.length > 0
|
|
2033
|
+
? { requestedFields }
|
|
2034
|
+
: {};
|
|
2035
|
+
const readBody = requestedFields.length > 0
|
|
2036
|
+
? JSON.stringify(readPayload)
|
|
2037
|
+
: undefined;
|
|
1979
2038
|
if (authContext.mode === 'one_shot' && authContext.reqId && authContext.binding) {
|
|
1980
2039
|
const bindingError = validateOneShotCredentialReadBinding({
|
|
1981
2040
|
reqId: authContext.reqId,
|
|
@@ -1994,11 +2053,13 @@ server.tool(
|
|
|
1994
2053
|
method: 'POST',
|
|
1995
2054
|
headers: {
|
|
1996
2055
|
'Authorization': `Bearer ${authToken}`,
|
|
2056
|
+
...(readBody ? { 'Content-Type': 'application/json' } : {}),
|
|
1997
2057
|
'X-Secret-Surface': 'inject_secret',
|
|
1998
2058
|
'X-Secret-EnvVar': resolvedEnvVar,
|
|
1999
2059
|
'X-Credential-Name': resolved.credentialName || name,
|
|
2000
2060
|
'X-Aura-Original-Command': `mcp inject_secret ${JSON.stringify(name)}`,
|
|
2001
2061
|
},
|
|
2062
|
+
...(readBody ? { body: readBody } : {}),
|
|
2002
2063
|
signal: AbortSignal.timeout(5000),
|
|
2003
2064
|
});
|
|
2004
2065
|
|
|
@@ -2012,7 +2073,7 @@ server.tool(
|
|
|
2012
2073
|
permissions: ['secret:read'],
|
|
2013
2074
|
endpoint: `/credentials/${resolved.credentialId}/read`,
|
|
2014
2075
|
method: 'POST',
|
|
2015
|
-
body:
|
|
2076
|
+
body: readPayload,
|
|
2016
2077
|
});
|
|
2017
2078
|
}
|
|
2018
2079
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Read failed (${res.status}): ${text}` }) }] };
|
|
@@ -2021,10 +2082,18 @@ server.tool(
|
|
|
2021
2082
|
const data = await res.json() as { encrypted: string };
|
|
2022
2083
|
const decrypted = decryptCredentialPayload(data.encrypted);
|
|
2023
2084
|
|
|
2024
|
-
|
|
2025
|
-
|
|
2085
|
+
const requestedValue = requestedField
|
|
2086
|
+
? findCredentialFieldValue(decrypted.type || resolved.credentialType, decrypted.fields, requestedField)
|
|
2087
|
+
: undefined;
|
|
2088
|
+
secretValue = requestedValue !== undefined
|
|
2089
|
+
? requestedValue
|
|
2090
|
+
: extractPrimarySecretValue(decrypted.fields);
|
|
2026
2091
|
|
|
2027
2092
|
if (!secretValue) {
|
|
2093
|
+
if (requestedField && requestedValue === undefined) {
|
|
2094
|
+
const availableFields = decrypted.fields.map((entry) => entry.key).join(', ');
|
|
2095
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Field "${requestedField}" not found on credential "${resolved.credentialName || name}"`, availableFields }) }] };
|
|
2096
|
+
}
|
|
2028
2097
|
return { content: [{ type: 'text' as const, text: JSON.stringify({ error: `Credential "${name}" has no extractable secret value` }) }] };
|
|
2029
2098
|
}
|
|
2030
2099
|
} catch (err) {
|
package/src/server/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"4.0.18","results":[[":tests/send.test.ts",{"duration":162.08154100000002,"failed":false}],[":tests/approve.test.ts",{"duration":257.27824999999996,"failed":false}],[":tests/unlock.test.ts",{"duration":213.61050000000003,"failed":false}],[":tests/setup.test.ts",{"duration":128.30779199999998,"failed":false}],[":tests/e2e.test.ts",{"duration":4341.373875,"failed":false}],[":tests/wallet.test.ts",{"duration":1768.446334,"failed":false}],[":tests/auth.test.ts",{"duration":174.709292,"failed":false}],[":tests/fund.test.ts",{"duration":820.6141660000001,"failed":false}],[":tests/integration/agent-flow.test.ts",{"duration":6350.61575,"failed":false}],[":tests/auth/permissions.test.ts",{"duration":6955.744291999999,"failed":false}],[":tests/auth/middleware.test.ts",{"duration":8667.608209,"failed":false}],[":tests/lib/sessions.test.ts",{"duration":100.3447920000001,"failed":false}],[":tests/lib/auth.test.ts",{"duration":4552.982083,"failed":false}],[":tests/endpoints/unlock.test.ts",{"duration":10486.351083,"failed":false}],[":tests/endpoints/wallet.test.ts",{"duration":4370.477584,"failed":false}],[":tests/endpoints/approve.test.ts",{"duration":497.64808300000004,"failed":false}],[":tests/endpoints/fund.test.ts",{"duration":1897.905,"failed":false}],[":tests/endpoints/send.test.ts",{"duration":2268.8852079999997,"failed":false}],[":tests/endpoints/auth.test.ts",{"duration":1334.914333,"failed":false}],[":tests/endpoints/setup.test.ts",{"duration":5293.225625,"failed":false}],[":tests/lib/uniswap.test.ts",{"duration":21.776292000000012,"failed":false}],[":tests/auth/apikeys.test.ts",{"duration":10995.417958,"failed":false}],[":tests/endpoints/wallet-data.test.ts",{"duration":2099.3379170000003,"failed":false}],[":tests/endpoints/swap.test.ts",{"duration":1653.693583,"failed":false}],[":tests/endpoints/token-clearing.test.ts",{"duration":1247.484042,"failed":false}],[":tests/endpoints/rate-limit.test.ts",{"duration":2154.356209,"failed":false}],[":tests/endpoints/solana-swap.test.ts",{"duration":998.2979999999999,"failed":false}],[":tests/endpoints/solana-wallet.test.ts",{"duration":1363.0256249999998,"failed":false}],[":tests/endpoints/solana-send.test.ts",{"duration":1039.8317080000002,"failed":false}],[":tests/lib/sessions-currency.test.ts",{"duration":56.1837079999998,"failed":false}],[":tests/endpoints/solana-fund.test.ts",{"duration":1418.0586249999997,"failed":false}],[":tests/lib/solana-wallet.test.ts",{"duration":161.13887499999998,"failed":false}],[":tests/lib/address.test.ts",{"duration":3.510084000000006,"failed":false}],[":tests/lib/strategy/sources.test.ts",{"duration":21.01504100000001,"failed":false}],[":tests/lib/strategy/loader.test.ts",{"duration":59.308375,"failed":false}],[":tests/lib/strategy/executor.test.ts",{"duration":7.492707999999993,"failed":false}],[":tests/lib/strategy/state.test.ts",{"duration":6.136792,"failed":false}],[":tests/lib/strategy/hooks.test.ts",{"duration":14.00120800000002,"failed":false}],[":tests/endpoints/widgets.test.ts",{"duration":2127.785625,"failed":false}],[":tests/lib/strategy/message.test.ts",{"duration":127.83229099999997,"failed":false}],[":tests/endpoints/actions.test.ts",{"duration":2396.4307919999997,"failed":false}],[":tests/endpoints/vault.test.ts",{"duration":7419.710874999999,"failed":false}],[":tests/integration/adapter-resolve.test.ts",{"duration":3486.7960000000003,"failed":false}],[":tests/lib/adapters.test.ts",{"duration":38.35904199999999,"failed":false}],[":tests/lib/strategy/tick.test.ts",{"duration":6.34379100000001,"failed":false}],[":tests/lib/relay.test.ts",{"duration":4.984791000000001,"failed":false}],[":tests/lib/ai.test.ts",{"duration":6.82841599999999,"failed":false}],[":tests/endpoints/launch.test.ts",{"duration":35837.233333,"failed":false}],[":tests/widget-installer.test.ts",{"duration":154.704459,"failed":false}],[":tests/mcp/tools.test.ts",{"duration":15.441082999999992,"failed":false}],[":tests/ai-integration/scenarios.test.ts",{"duration":7.4487499999999045,"failed":true}],[":tests/mcp/server.test.ts",{"duration":1333.480375,"failed":false}],[":tests/ai-integration/live.test.ts",{"duration":77572.38508299999,"failed":false}],[":tests/auth/apikeys-validate.test.ts",{"duration":10219.787667,"failed":false}],[":tests/lib/adapters-test.test.ts",{"duration":25429.400542,"failed":false}],[":tests/setup-integration/wizard-flow.test.ts",{"duration":124.21662500000002,"failed":false}],[":tests/setup-integration/adapter-test.test.ts",{"duration":166.0367080000001,"failed":false}],[":tests/setup-integration/edge-cases.test.ts",{"duration":156.02324999999996,"failed":false}],[":tests/setup-integration/apikey-validation.test.ts",{"duration":147.53583400000002,"failed":false}],[":tests/setup-integration/fresh-setup.test.ts",{"duration":107.81912499999999,"failed":false}],[":tests/lib/network.test.ts",{"duration":12.689417000000006,"failed":false}],[":tests/cli/process.test.ts",{"duration":33.650542,"failed":false}],[":tests/cli/init-steps.test.ts",{"duration":4.78708300000001,"failed":false}],[":tests/cli/init-flow.test.ts",{"duration":2517.034083,"failed":false}],[":tests/cli/http.test.ts",{"duration":1563.349083,"failed":false}],[":tests/lib/verified-summary.test.ts",{"duration":8.588290999999998,"failed":false}],[":tests/lib/defaults.test.ts",{"duration":89.18312500000002,"failed":false}],[":tests/endpoints/defaults.test.ts",{"duration":6137.610333,"failed":false}],[":tests/lib/adapters-chat.test.ts",{"duration":28.19304200000002,"failed":false}],[":tests/setup-integration/terminal-flow.test.ts",{"duration":248.770042,"failed":false}],[":tests/endpoints/transactions.test.ts",{"duration":1127.6649169999998,"failed":false}],[":tests/cron/scheduler.test.ts",{"duration":16.875292,"failed":false}],[":tests/endpoints/portfolio.test.ts",{"duration":381.701917,"failed":false}],[":tests/cron/native-price.test.ts",{"duration":58.4565419999999,"failed":false}],[":tests/resolve.test.ts",{"duration":13.15741700000001,"failed":false}],[":tests/lib/prices.test.ts",{"duration":103.56858299999999,"failed":false}],[":tests/swap-quote.test.ts",{"duration":945.5037500000001,"failed":false}],[":tests/send-token.test.ts",{"duration":996.399292,"failed":false}],[":tests/endpoints/price.test.ts",{"duration":61.327583000000004,"failed":false}],[":tests/lib/price.test.ts",{"duration":4.805790999999999,"failed":false}],[":tests/endpoints/token-search.test.ts",{"duration":35.89754199999993,"failed":false}],[":tests/lib/token-search.test.ts",{"duration":65.472708,"failed":false}],[":tests/lib/token-safety.test.ts",{"duration":5.724790999999996,"failed":false}],[":tests/endpoints/token-safety.test.ts",{"duration":41.85649999999987,"failed":false}],[":tests/lib/batch.test.ts",{"duration":11.763874999999999,"failed":false}],[":tests/endpoints/batch.test.ts",{"duration":48.719875,"failed":false}],[":tests/endpoints/token-balance.test.ts",{"duration":29.900082999999995,"failed":false}],[":tests/lib/events-decoder.test.ts",{"duration":4.558958999999987,"failed":false}],[":tests/lib/events-enricher.test.ts",{"duration":4.474500000000035,"failed":false}],[":tests/endpoints/address-transactions.test.ts",{"duration":962.0601669999999,"failed":false}],[":tests/endpoints/bookmarks.test.ts",{"duration":1349.6050840000003,"failed":false}],[":tests/endpoints/addressbook.test.ts",{"duration":995.706459,"failed":false}],[":tests/lib/strategy/session-logger.test.ts",{"duration":1471.763333,"failed":false}],[":tests/cron/incoming-scan.test.ts",{"duration":385.8459999999999,"failed":false}],[":tests/lib/auto-unlock.test.ts",{"duration":1104.2137500000001,"failed":false}],[":tests/lib/widget-tokens-tier.test.ts",{"duration":226.36699999999996,"failed":false}],[":tests/cron/strategy-runner.test.ts",{"duration":6.080332999999996,"failed":false}],[":tests/endpoints/strategy-routes.test.ts",{"duration":11390.736792,"failed":false}],[":tests/endpoints/apps.test.ts",{"duration":21435.455708999998,"failed":false}],[":tests/lib/events-fetcher.test.ts",{"duration":6.5429169999999885,"failed":false}],[":tests/app-installer.test.ts",{"duration":114.05204099999997,"failed":false}],[":tests/lib/app-tokens-tier.test.ts",{"duration":276.60683300000005,"failed":false}],[":tests/setup-integration/onboarding-e2e.test.ts",{"duration":445.7834579999999,"failed":true}],[":tests/cron/orphan-cleanup.test.ts",{"duration":6.764916999999997,"failed":false}],[":tests/lib/strategy/repository.test.ts",{"duration":28.425665999999865,"failed":false}],[":tests/setup-integration/autonomous-agent.test.ts",{"duration":7.406667000000027,"failed":true}],[":tests/lib/websocket-auth.test.ts",{"duration":235.461,"failed":false}],[":tests/lib/credentials.test.ts",{"duration":7320.739874999999,"failed":false}],[":tests/lib/credential-access.test.ts",{"duration":3.4029999999999916,"failed":false}],[":tests/lib/credential-scope.test.ts",{"duration":3.2806659999999965,"failed":false}],[":tests/endpoints/credential-ops.test.ts",{"duration":3004.8909169999997,"failed":false}],[":tests/endpoints/credentials.test.ts",{"duration":27923.241459,"failed":false}],[":tests/lib/credential-transport.test.ts",{"duration":138.75,"failed":false}],[":tests/lib/credential-vault.test.ts",{"duration":4433.612583,"failed":false}],[":tests/lib/resolve-action.test.ts",{"duration":4.514791000000002,"failed":false}],[":tests/credential-import.test.ts",{"duration":19.897791999999995,"failed":false}],[":tests/endpoints/passkey.test.ts",{"duration":14553.136708,"failed":false}],[":tests/lib/oauth2-refresh.test.ts",{"duration":3.752541000000008,"failed":false}],[":tests/lib/totp.test.ts",{"duration":7.506458999999992,"failed":false}],[":tests/lib/passkey-credential.test.ts",{"duration":9.192250000000001,"failed":false}],[":tests/cli/env.test.ts",{"duration":8.821500000000015,"failed":false}],[":tests/dotenv-parser.test.ts",{"duration":3.3828749999999985,"failed":false}],[":tests/cli/socket.test.ts",{"duration":164.548791,"failed":false}],[":tests/cli/vault.test.ts",{"duration":5.563457999999997,"failed":false}],[":tests/cli/credential-resolve.test.ts",{"duration":2.6654999999999944,"failed":false}],[":tests/cli/env-check-server-vault.test.ts",{"duration":239.821708,"failed":false}],[":tests/e2e-agent/validation.test.ts",{"duration":8.998582999999996,"failed":false}],[":tests/e2e-agent/artifacts.test.ts",{"duration":3.1474170000000044,"failed":false}],[":tests/e2e-agent/ci-lanes.test.ts",{"duration":1.272790999999998,"failed":false}],[":tests/lib/api-registry/validation.test.ts",{"duration":5.377708000000013,"failed":false}],[":tests/lib/aura-parser.test.ts",{"duration":10.007750000000001,"failed":false}],[":tests/lib/agent-auth/contracts.test.ts",{"duration":11.581041999999997,"failed":false}],[":tests/cli/doctor.test.ts",{"duration":9.576459,"failed":false}],[":tests/endpoints/import.test.ts",{"duration":8348.137416,"failed":false}],[":tests/endpoints/passkey-credentials.test.ts",{"duration":2573.4603340000003,"failed":false}],[":tests/lib/credential-health.test.ts",{"duration":3.1082080000000047,"failed":false}],[":tests/lib/agent-profiles.test.ts",{"duration":3.3868339999999932,"failed":false}],[":tests/mcp/profile-policy.test.ts",{"duration":3.01100000000001,"failed":false}],[":tests/endpoints/profile-parity.test.ts",{"duration":9.213209000000006,"failed":true}],[":tests/lib/profile-parity.test.ts",{"duration":1.7047079999999966,"failed":false}],[":tests/endpoints/credential-access-audit.test.ts",{"duration":1768.71025,"failed":false}],[":tests/lib/project-scope.test.ts",{"duration":8.761667000000003,"failed":false}],[":tests/docs/job-docs-validation.test.ts",{"duration":33.986999999999995,"failed":false}],[":tests/endpoints/credential-shares.test.ts",{"duration":6208.950334,"failed":false}],[":tests/lib/task-lifecycle.test.ts",{"duration":7.928124999999994,"failed":false}],[":tests/endpoints/tasks-lifecycle.test.ts",{"duration":191.46470899999997,"failed":false}],[":tests/cli/local-agent-trust.test.ts",{"duration":2.7987499999999983,"failed":false}],[":tests/cli/token.test.ts",{"duration":1.4059579999999983,"failed":false}],[":tests/endpoints/heartbeat.test.ts",{"duration":4575.689417,"failed":false}],[":tests/cli/bin-entrypoint.test.ts",{"duration":4248.5371669999995,"failed":false}],[":tests/sandbox/cli.test.ts",{"duration":332.983625,"failed":false}],[":tests/cli/vault-auth.test.ts",{"duration":195.026916,"failed":false}],[":tests/lib/encrypt.test.ts",{"duration":763.462208,"failed":false}],[":tests/cli/vault-share-gist.test.ts",{"duration":14.503625,"failed":false}],[":tests/lib/secret-gist-share.test.ts",{"duration":1.757791999999995,"failed":false}],[":tests/cli/vault-list-filters.test.ts",{"duration":14.040582999999984,"failed":false}],[":tests/cli/start.test.ts",{"duration":1.8407080000000065,"failed":false}],[":tests/cli/wallet.test.ts",{"duration":1.465874999999997,"failed":false}],[":tests/cli/prompt-select.test.ts",{"duration":4.252083999999996,"failed":false}],[":tests/cli/quickhack.test.ts",{"duration":1.982292000000001,"failed":false}],[":tests/lib/human-action-summary.test.ts",{"duration":2.1798750000000098,"failed":false}],[":tests/pipeline-db/paths.test.ts",{"duration":5.902790999999979,"failed":false}],[":tests/pipeline-db/bootstrap.test.ts",{"duration":39.007125,"failed":false}],[":tests/pipeline-db/snapshot.test.ts",{"duration":29.974833999999987,"failed":false}],[":tests/pipeline-db/dual-write.test.ts",{"duration":60.147583,"failed":false}],[":tests/pipeline-db/importer.test.ts",{"duration":33.614417,"failed":false}],[":tests/pipeline-lifecycle/service.test.ts",{"duration":32.389666000000005,"failed":false}],[":tests/pipeline-lifecycle/taskctl.test.ts",{"duration":2885.294625,"failed":false}],[":tests/pipeline-lifecycle/agent-cron-integration.test.ts",{"duration":28.44970900000004,"failed":false}],[":tests/pipeline-db/cutover-plan.test.ts",{"duration":2.5047919999999806,"failed":false}],[":tests/lib/approval-link.test.ts",{"duration":1.0141670000000005,"failed":false}],[":tests/lib/dont-ask-again-policy.test.ts",{"duration":1.2326669999999922,"failed":false}],[":tests/lib/update-check.test.ts",{"duration":1.4486670000000004,"failed":false}],[":tests/lib/auto-execute.test.ts",{"duration":108.225667,"failed":false}],[":tests/lib/auth-action.test.ts",{"duration":1998.647583,"failed":false}],[":tests/cli/auth-action-flag.test.ts",{"duration":3.1158340000000067,"failed":false}],[":tests/pipeline-lifecycle/tags.test.ts",{"duration":321.27825,"failed":false}],[":tests/endpoints/nuke.test.ts",{"duration":69.0028749999999,"failed":false}],[":tests/endpoints/apikeys.test.ts",{"duration":11085.063833,"failed":false}],[":tests/endpoints/security.test.ts",{"duration":9164.535417000001,"failed":false}],[":tests/endpoints/dashboard.test.ts",{"duration":103.2655420000001,"failed":false}],[":tests/endpoints/logs.test.ts",{"duration":183.44812500000035,"failed":false}],[":tests/endpoints/views.test.ts",{"duration":17.28716600000007,"failed":false}],[":tests/endpoints/flags.test.ts",{"duration":12.482625000000098,"failed":false}],[":tests/endpoints/lock.test.ts",{"duration":11063.760583,"failed":false}],[":tests/endpoints/backup.test.ts",{"duration":6926.148333000001,"failed":false}],[":tests/auth/approval-permissions-regression.test.ts",{"duration":2333.866833,"failed":false}],[":tests/sandbox/cli-cd-suite.test.ts",{"duration":578.572375,"failed":false}],[":tests/mcp/contract.test.ts",{"duration":78.60249999999999,"failed":false}],[":tests/lib/credential-paths.test.ts",{"duration":3899.7734170000003,"failed":false}],[":tests/runtime-vault-smoke.test.ts",{"duration":1521.938291,"failed":false}],[":tests/cli/taskctl-lock-smoke.test.ts",{"duration":0,"failed":false}],[":tests/cli/start-run.test.ts",{"duration":6.923584000000005,"failed":false}],[":tests/cli/restart-run.test.ts",{"duration":4.698082999999997,"failed":false}],[":tests/endpoints/approve-action.test.ts",{"duration":1056.1783329999998,"failed":false}],[":tests/cli/escalation.test.ts",{"duration":3.389707999999999,"failed":false}],[":tests/cli/actions-auth.test.ts",{"duration":39.753000000000014,"failed":false}],[":tests/lib/temp-policy.test.ts",{"duration":2.585374999999999,"failed":false}],[":tests/endpoints/escalation-migration-gate.test.ts",{"duration":11955.108208,"failed":false}],[":tests/lib/escalation-responder.test.ts",{"duration":24.61208400000001,"failed":false}],[":tests/cli/service.test.ts",{"duration":38.05449999999999,"failed":false}],[":tests/cli/init-runtime.test.ts",{"duration":4.873333000000002,"failed":false}],[":tests/cli/agent.test.ts",{"duration":7.902833000000001,"failed":false}],[":tests/runtime-agent-smoke.test.ts",{"duration":1154.7805830000002,"failed":false}],[":tests/endpoints/agent.test.ts",{"duration":6459.912458000001,"failed":false}],[":tests/lib/credential-agent.test.ts",{"duration":3084.496541,"failed":false}],[":tests/cli/agent-auth.test.ts",{"duration":528.433583,"failed":false}],[":tests/cli/agent-share-gist.test.ts",{"duration":16.512332999999984,"failed":false}],[":tests/cli/agent-list-filters.test.ts",{"duration":18.725041000000004,"failed":false}],[":tests/cli/env-check-server-agent.test.ts",{"duration":292.08354199999997,"failed":false}],[":tests/lib/import-from-openclaw-paths.test.ts",{"duration":0,"failed":true}],[":tests/endpoints/agent-profiles.test.ts",{"duration":3425.8750000000005,"failed":false}]]}
|
|
1
|
+
{"version":"4.0.18","results":[[":tests/send.test.ts",{"duration":162.08154100000002,"failed":false}],[":tests/approve.test.ts",{"duration":257.27824999999996,"failed":false}],[":tests/unlock.test.ts",{"duration":213.61050000000003,"failed":false}],[":tests/setup.test.ts",{"duration":128.30779199999998,"failed":false}],[":tests/e2e.test.ts",{"duration":3924.8372500000005,"failed":false}],[":tests/wallet.test.ts",{"duration":1768.446334,"failed":false}],[":tests/auth.test.ts",{"duration":174.709292,"failed":false}],[":tests/fund.test.ts",{"duration":820.6141660000001,"failed":false}],[":tests/integration/agent-flow.test.ts",{"duration":6088.6245,"failed":false}],[":tests/auth/permissions.test.ts",{"duration":6761.803000000001,"failed":false}],[":tests/auth/middleware.test.ts",{"duration":8629.632875,"failed":false}],[":tests/lib/sessions.test.ts",{"duration":171.32058299999994,"failed":false}],[":tests/lib/auth.test.ts",{"duration":4089.3444170000002,"failed":false}],[":tests/endpoints/unlock.test.ts",{"duration":10232.476333999999,"failed":false}],[":tests/endpoints/wallet.test.ts",{"duration":4418.335292,"failed":false}],[":tests/endpoints/approve.test.ts",{"duration":497.64808300000004,"failed":false}],[":tests/endpoints/fund.test.ts",{"duration":1718.8159589999998,"failed":false}],[":tests/endpoints/send.test.ts",{"duration":2154.865875,"failed":false}],[":tests/endpoints/auth.test.ts",{"duration":1208.190834,"failed":false}],[":tests/endpoints/setup.test.ts",{"duration":4987.754667,"failed":false}],[":tests/lib/uniswap.test.ts",{"duration":12.576917000000009,"failed":false}],[":tests/auth/apikeys.test.ts",{"duration":10823.350042,"failed":false}],[":tests/endpoints/wallet-data.test.ts",{"duration":2309.976375,"failed":false}],[":tests/endpoints/swap.test.ts",{"duration":2005.271917,"failed":false}],[":tests/endpoints/token-clearing.test.ts",{"duration":1286.3398750000001,"failed":false}],[":tests/endpoints/rate-limit.test.ts",{"duration":2103.539209,"failed":false}],[":tests/endpoints/solana-swap.test.ts",{"duration":1051.7639170000002,"failed":false}],[":tests/endpoints/solana-wallet.test.ts",{"duration":1333.433125,"failed":false}],[":tests/endpoints/solana-send.test.ts",{"duration":984.4620829999999,"failed":false}],[":tests/lib/sessions-currency.test.ts",{"duration":99.97837500000014,"failed":false}],[":tests/endpoints/solana-fund.test.ts",{"duration":1388.2830829999998,"failed":false}],[":tests/lib/solana-wallet.test.ts",{"duration":145.200958,"failed":false}],[":tests/lib/address.test.ts",{"duration":2.2885830000000027,"failed":false}],[":tests/lib/strategy/sources.test.ts",{"duration":20.033541,"failed":false}],[":tests/lib/strategy/loader.test.ts",{"duration":13.489082999999994,"failed":false}],[":tests/lib/strategy/executor.test.ts",{"duration":9.343333000000001,"failed":false}],[":tests/lib/strategy/state.test.ts",{"duration":9.851000000000013,"failed":false}],[":tests/lib/strategy/hooks.test.ts",{"duration":14.077292,"failed":false}],[":tests/endpoints/widgets.test.ts",{"duration":2127.785625,"failed":false}],[":tests/lib/strategy/message.test.ts",{"duration":113.09245800000002,"failed":false}],[":tests/endpoints/actions.test.ts",{"duration":2485.513375,"failed":false}],[":tests/endpoints/vault.test.ts",{"duration":7419.710874999999,"failed":false}],[":tests/integration/adapter-resolve.test.ts",{"duration":3415.2646250000003,"failed":false}],[":tests/lib/adapters.test.ts",{"duration":42.87712499999998,"failed":false}],[":tests/lib/strategy/tick.test.ts",{"duration":6.5871250000000146,"failed":false}],[":tests/lib/relay.test.ts",{"duration":5.1127500000000055,"failed":false}],[":tests/lib/ai.test.ts",{"duration":6.845791999999989,"failed":false}],[":tests/endpoints/launch.test.ts",{"duration":39822.157459,"failed":false}],[":tests/widget-installer.test.ts",{"duration":154.704459,"failed":false}],[":tests/mcp/tools.test.ts",{"duration":19.034333000000004,"failed":false}],[":tests/ai-integration/scenarios.test.ts",{"duration":7.4487499999999045,"failed":true}],[":tests/mcp/server.test.ts",{"duration":1053.348542,"failed":false}],[":tests/ai-integration/live.test.ts",{"duration":77572.38508299999,"failed":false}],[":tests/auth/apikeys-validate.test.ts",{"duration":10064.624082999999,"failed":false}],[":tests/lib/adapters-test.test.ts",{"duration":24669.032584,"failed":false}],[":tests/setup-integration/wizard-flow.test.ts",{"duration":124.21662500000002,"failed":false}],[":tests/setup-integration/adapter-test.test.ts",{"duration":166.0367080000001,"failed":false}],[":tests/setup-integration/edge-cases.test.ts",{"duration":156.02324999999996,"failed":false}],[":tests/setup-integration/apikey-validation.test.ts",{"duration":147.53583400000002,"failed":false}],[":tests/setup-integration/fresh-setup.test.ts",{"duration":107.81912499999999,"failed":false}],[":tests/lib/network.test.ts",{"duration":9.380416999999994,"failed":false}],[":tests/cli/process.test.ts",{"duration":59.56675,"failed":false}],[":tests/cli/init-steps.test.ts",{"duration":4.803083999999998,"failed":false}],[":tests/cli/init-flow.test.ts",{"duration":2356.2355420000004,"failed":false}],[":tests/cli/http.test.ts",{"duration":1539.509333,"failed":false}],[":tests/lib/verified-summary.test.ts",{"duration":6.6548329999999964,"failed":false}],[":tests/lib/defaults.test.ts",{"duration":60.831541000000016,"failed":false}],[":tests/endpoints/defaults.test.ts",{"duration":5807.414542,"failed":false}],[":tests/lib/adapters-chat.test.ts",{"duration":26.964458999999977,"failed":false}],[":tests/setup-integration/terminal-flow.test.ts",{"duration":248.770042,"failed":false}],[":tests/endpoints/transactions.test.ts",{"duration":1173.7453750000002,"failed":false}],[":tests/cron/scheduler.test.ts",{"duration":10.118041999999988,"failed":false}],[":tests/endpoints/portfolio.test.ts",{"duration":331.652916,"failed":false}],[":tests/cron/native-price.test.ts",{"duration":77.54324999999994,"failed":false}],[":tests/resolve.test.ts",{"duration":13.599375000000009,"failed":false}],[":tests/lib/prices.test.ts",{"duration":54.92983299999992,"failed":false}],[":tests/swap-quote.test.ts",{"duration":959.055208,"failed":false}],[":tests/send-token.test.ts",{"duration":953.917041,"failed":false}],[":tests/endpoints/price.test.ts",{"duration":48.3732500000001,"failed":false}],[":tests/lib/price.test.ts",{"duration":4.861209000000002,"failed":false}],[":tests/endpoints/token-search.test.ts",{"duration":41.01174999999989,"failed":false}],[":tests/lib/token-search.test.ts",{"duration":71.24962500000001,"failed":false}],[":tests/lib/token-safety.test.ts",{"duration":4.6863329999999905,"failed":false}],[":tests/endpoints/token-safety.test.ts",{"duration":42.42004199999997,"failed":false}],[":tests/lib/batch.test.ts",{"duration":5.325082999999992,"failed":false}],[":tests/endpoints/batch.test.ts",{"duration":51.468083999999976,"failed":false}],[":tests/endpoints/token-balance.test.ts",{"duration":33.105999999999995,"failed":false}],[":tests/lib/events-decoder.test.ts",{"duration":4.991375000000005,"failed":false}],[":tests/lib/events-enricher.test.ts",{"duration":5.042708000000005,"failed":false}],[":tests/endpoints/address-transactions.test.ts",{"duration":995.369167,"failed":false}],[":tests/endpoints/bookmarks.test.ts",{"duration":1299.437417,"failed":false}],[":tests/endpoints/addressbook.test.ts",{"duration":1003.398917,"failed":false}],[":tests/lib/strategy/session-logger.test.ts",{"duration":1463.488292,"failed":false}],[":tests/cron/incoming-scan.test.ts",{"duration":342.919041,"failed":false}],[":tests/lib/auto-unlock.test.ts",{"duration":995.2187919999999,"failed":false}],[":tests/lib/widget-tokens-tier.test.ts",{"duration":226.36699999999996,"failed":false}],[":tests/cron/strategy-runner.test.ts",{"duration":6.173999999999992,"failed":false}],[":tests/endpoints/strategy-routes.test.ts",{"duration":10984.715292,"failed":false}],[":tests/endpoints/apps.test.ts",{"duration":20728.988500000003,"failed":false}],[":tests/lib/events-fetcher.test.ts",{"duration":6.63654200000002,"failed":false}],[":tests/app-installer.test.ts",{"duration":121.90758300000002,"failed":false}],[":tests/lib/app-tokens-tier.test.ts",{"duration":273.176875,"failed":false}],[":tests/setup-integration/onboarding-e2e.test.ts",{"duration":445.7834579999999,"failed":true}],[":tests/cron/orphan-cleanup.test.ts",{"duration":6.969750000000005,"failed":false}],[":tests/lib/strategy/repository.test.ts",{"duration":38.93041599999992,"failed":false}],[":tests/setup-integration/autonomous-agent.test.ts",{"duration":7.406667000000027,"failed":true}],[":tests/lib/websocket-auth.test.ts",{"duration":224.16829199999998,"failed":false}],[":tests/lib/credentials.test.ts",{"duration":7162.027333,"failed":false}],[":tests/lib/credential-access.test.ts",{"duration":4.621292000000011,"failed":false}],[":tests/lib/credential-scope.test.ts",{"duration":3.140375000000006,"failed":false}],[":tests/endpoints/credential-ops.test.ts",{"duration":2956.245,"failed":false}],[":tests/endpoints/credentials.test.ts",{"duration":26834.984207999998,"failed":false}],[":tests/lib/credential-transport.test.ts",{"duration":116.04087499999997,"failed":false}],[":tests/lib/credential-vault.test.ts",{"duration":4433.612583,"failed":false}],[":tests/lib/resolve-action.test.ts",{"duration":4.583040999999994,"failed":false}],[":tests/credential-import.test.ts",{"duration":18.054874999999996,"failed":false}],[":tests/endpoints/passkey.test.ts",{"duration":13870.052208000001,"failed":false}],[":tests/lib/oauth2-refresh.test.ts",{"duration":3.757000000000005,"failed":false}],[":tests/lib/totp.test.ts",{"duration":6.120041999999998,"failed":false}],[":tests/lib/passkey-credential.test.ts",{"duration":7.424291999999994,"failed":false}],[":tests/cli/env.test.ts",{"duration":7.1997499999999945,"failed":false}],[":tests/dotenv-parser.test.ts",{"duration":7.199292,"failed":false}],[":tests/cli/socket.test.ts",{"duration":185.29004200000003,"failed":false}],[":tests/cli/vault.test.ts",{"duration":5.563457999999997,"failed":false}],[":tests/cli/credential-resolve.test.ts",{"duration":2.5222920000000073,"failed":false}],[":tests/cli/env-check-server-vault.test.ts",{"duration":239.821708,"failed":false}],[":tests/e2e-agent/validation.test.ts",{"duration":8.834457999999984,"failed":false}],[":tests/e2e-agent/artifacts.test.ts",{"duration":2.4147920000000056,"failed":false}],[":tests/e2e-agent/ci-lanes.test.ts",{"duration":1.2617089999999962,"failed":false}],[":tests/lib/api-registry/validation.test.ts",{"duration":5.282042000000004,"failed":false}],[":tests/lib/aura-parser.test.ts",{"duration":8.742790999999997,"failed":false}],[":tests/lib/agent-auth/contracts.test.ts",{"duration":7.681333000000009,"failed":false}],[":tests/cli/doctor.test.ts",{"duration":9.505791999999985,"failed":false}],[":tests/endpoints/import.test.ts",{"duration":8501.442541999999,"failed":false}],[":tests/endpoints/passkey-credentials.test.ts",{"duration":2548.2423750000003,"failed":false}],[":tests/lib/credential-health.test.ts",{"duration":2.742500000000007,"failed":false}],[":tests/lib/agent-profiles.test.ts",{"duration":4.791916000000015,"failed":false}],[":tests/mcp/profile-policy.test.ts",{"duration":3.4552499999999924,"failed":false}],[":tests/endpoints/profile-parity.test.ts",{"duration":9.213209000000006,"failed":true}],[":tests/lib/profile-parity.test.ts",{"duration":1.5870000000000033,"failed":false}],[":tests/endpoints/credential-access-audit.test.ts",{"duration":1706.509292,"failed":false}],[":tests/lib/project-scope.test.ts",{"duration":6.9360420000000005,"failed":false}],[":tests/docs/job-docs-validation.test.ts",{"duration":29.556416999999996,"failed":false}],[":tests/endpoints/credential-shares.test.ts",{"duration":5810.327,"failed":false}],[":tests/lib/task-lifecycle.test.ts",{"duration":7.928124999999994,"failed":false}],[":tests/endpoints/tasks-lifecycle.test.ts",{"duration":191.46470899999997,"failed":false}],[":tests/cli/local-agent-trust.test.ts",{"duration":4.082082999999997,"failed":false}],[":tests/cli/token.test.ts",{"duration":1.5038330000000002,"failed":false}],[":tests/endpoints/heartbeat.test.ts",{"duration":4186.430625,"failed":false}],[":tests/cli/bin-entrypoint.test.ts",{"duration":3969.1315409999997,"failed":false}],[":tests/sandbox/cli.test.ts",{"duration":289.17449999999997,"failed":false}],[":tests/cli/vault-auth.test.ts",{"duration":195.026916,"failed":false}],[":tests/lib/encrypt.test.ts",{"duration":739.814959,"failed":false}],[":tests/cli/vault-share-gist.test.ts",{"duration":14.503625,"failed":false}],[":tests/lib/secret-gist-share.test.ts",{"duration":1.593874999999997,"failed":false}],[":tests/cli/vault-list-filters.test.ts",{"duration":14.040582999999984,"failed":false}],[":tests/cli/start.test.ts",{"duration":1.595084,"failed":false}],[":tests/cli/wallet.test.ts",{"duration":1.361959000000013,"failed":false}],[":tests/cli/prompt-select.test.ts",{"duration":4.046291999999994,"failed":false}],[":tests/cli/quickhack.test.ts",{"duration":2.6738749999999953,"failed":false}],[":tests/lib/human-action-summary.test.ts",{"duration":2.1484590000000026,"failed":false}],[":tests/pipeline-db/paths.test.ts",{"duration":5.902790999999979,"failed":false}],[":tests/pipeline-db/bootstrap.test.ts",{"duration":39.007125,"failed":false}],[":tests/pipeline-db/snapshot.test.ts",{"duration":29.974833999999987,"failed":false}],[":tests/pipeline-db/dual-write.test.ts",{"duration":60.147583,"failed":false}],[":tests/pipeline-db/importer.test.ts",{"duration":33.614417,"failed":false}],[":tests/pipeline-lifecycle/service.test.ts",{"duration":32.389666000000005,"failed":false}],[":tests/pipeline-lifecycle/taskctl.test.ts",{"duration":2885.294625,"failed":false}],[":tests/pipeline-lifecycle/agent-cron-integration.test.ts",{"duration":28.44970900000004,"failed":false}],[":tests/pipeline-db/cutover-plan.test.ts",{"duration":2.5047919999999806,"failed":false}],[":tests/lib/approval-link.test.ts",{"duration":1.0255830000000046,"failed":false}],[":tests/lib/dont-ask-again-policy.test.ts",{"duration":1.217250000000007,"failed":false}],[":tests/lib/update-check.test.ts",{"duration":1.3213750000000033,"failed":false}],[":tests/lib/auto-execute.test.ts",{"duration":108.23875000000001,"failed":false}],[":tests/lib/auth-action.test.ts",{"duration":1955.904625,"failed":false}],[":tests/cli/auth-action-flag.test.ts",{"duration":3.093834000000001,"failed":false}],[":tests/pipeline-lifecycle/tags.test.ts",{"duration":321.27825,"failed":false}],[":tests/endpoints/nuke.test.ts",{"duration":69.0028749999999,"failed":false}],[":tests/endpoints/apikeys.test.ts",{"duration":11085.063833,"failed":false}],[":tests/endpoints/security.test.ts",{"duration":9164.535417000001,"failed":false}],[":tests/endpoints/dashboard.test.ts",{"duration":103.2655420000001,"failed":false}],[":tests/endpoints/logs.test.ts",{"duration":183.44812500000035,"failed":false}],[":tests/endpoints/views.test.ts",{"duration":17.28716600000007,"failed":false}],[":tests/endpoints/flags.test.ts",{"duration":12.482625000000098,"failed":false}],[":tests/endpoints/lock.test.ts",{"duration":11063.760583,"failed":false}],[":tests/endpoints/backup.test.ts",{"duration":6926.148333000001,"failed":false}],[":tests/auth/approval-permissions-regression.test.ts",{"duration":2318.2909170000003,"failed":false}],[":tests/sandbox/cli-cd-suite.test.ts",{"duration":615.319,"failed":false}],[":tests/mcp/contract.test.ts",{"duration":104.87708299999998,"failed":false}],[":tests/lib/credential-paths.test.ts",{"duration":3863.718,"failed":false}],[":tests/runtime-vault-smoke.test.ts",{"duration":1521.938291,"failed":false}],[":tests/cli/taskctl-lock-smoke.test.ts",{"duration":0,"failed":false}],[":tests/cli/start-run.test.ts",{"duration":5.826916999999995,"failed":false}],[":tests/cli/restart-run.test.ts",{"duration":4.38683300000001,"failed":false}],[":tests/endpoints/approve-action.test.ts",{"duration":1019.0898749999999,"failed":false}],[":tests/cli/escalation.test.ts",{"duration":2.666415999999998,"failed":false}],[":tests/cli/actions-auth.test.ts",{"duration":21.518292000000002,"failed":false}],[":tests/lib/temp-policy.test.ts",{"duration":2.778499999999994,"failed":false}],[":tests/endpoints/escalation-migration-gate.test.ts",{"duration":11809.859042,"failed":false}],[":tests/lib/escalation-responder.test.ts",{"duration":30.654416999999995,"failed":false}],[":tests/cli/service.test.ts",{"duration":37.195584,"failed":false}],[":tests/cli/init-runtime.test.ts",{"duration":4.815833999999995,"failed":false}],[":tests/cli/agent.test.ts",{"duration":4.056166999999988,"failed":false}],[":tests/runtime-agent-smoke.test.ts",{"duration":1155.657334,"failed":false}],[":tests/endpoints/agent.test.ts",{"duration":5853.5660419999995,"failed":false}],[":tests/lib/credential-agent.test.ts",{"duration":3026.8250000000003,"failed":false}],[":tests/cli/agent-auth.test.ts",{"duration":540.6860419999999,"failed":false}],[":tests/cli/agent-share-gist.test.ts",{"duration":27.42041599999999,"failed":false}],[":tests/cli/agent-list-filters.test.ts",{"duration":12.318375000000003,"failed":false}],[":tests/cli/env-check-server-agent.test.ts",{"duration":379.80316700000003,"failed":false}],[":tests/lib/import-from-openclaw-paths.test.ts",{"duration":0,"failed":true}],[":tests/endpoints/agent-profiles.test.ts",{"duration":3356.1236670000003,"failed":false}]]}
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
summarizeCredentialHealthFlags,
|
|
52
52
|
} from '../lib/credential-health';
|
|
53
53
|
import {
|
|
54
|
+
canonicalizeCredentialFieldKey,
|
|
54
55
|
NOTE_CONTENT_KEY,
|
|
55
56
|
getCredentialFieldValue,
|
|
56
57
|
normalizeCredentialFieldsForType,
|
|
@@ -480,6 +481,40 @@ function parseRequestedPolicyInput(body: unknown): {
|
|
|
480
481
|
};
|
|
481
482
|
}
|
|
482
483
|
|
|
484
|
+
function parseRequestedReadFieldsInput(
|
|
485
|
+
body: unknown,
|
|
486
|
+
credentialType: CredentialType,
|
|
487
|
+
): { requestedFields: string[]; requestsAllFields: boolean } {
|
|
488
|
+
const bodyPayload = body && typeof body === 'object' && !Array.isArray(body)
|
|
489
|
+
? body as Record<string, unknown>
|
|
490
|
+
: {};
|
|
491
|
+
const requestedFieldsRaw: string[] = [];
|
|
492
|
+
|
|
493
|
+
const appendRequestedField = (value: unknown): void => {
|
|
494
|
+
if (typeof value !== 'string') return;
|
|
495
|
+
const trimmed = value.trim();
|
|
496
|
+
if (!trimmed) return;
|
|
497
|
+
requestedFieldsRaw.push(trimmed);
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
if (Array.isArray(bodyPayload.requestedFields)) {
|
|
501
|
+
for (const value of bodyPayload.requestedFields) {
|
|
502
|
+
appendRequestedField(value);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
appendRequestedField(bodyPayload.requestedField);
|
|
506
|
+
appendRequestedField(bodyPayload.field);
|
|
507
|
+
|
|
508
|
+
const requestsAllFields = requestedFieldsRaw.some((value) => value === '*');
|
|
509
|
+
const requestedFields = Array.from(new Set(
|
|
510
|
+
requestedFieldsRaw
|
|
511
|
+
.filter((value) => value !== '*')
|
|
512
|
+
.map((value) => normalizeScope(canonicalizeCredentialFieldKey(credentialType, value))),
|
|
513
|
+
));
|
|
514
|
+
|
|
515
|
+
return { requestedFields, requestsAllFields };
|
|
516
|
+
}
|
|
517
|
+
|
|
483
518
|
function buildCredentialRouteContract(input: {
|
|
484
519
|
routeId: CredentialRouteContractId;
|
|
485
520
|
credentialId: string;
|
|
@@ -1817,13 +1852,21 @@ router.post('/:id/read', async (req: Request<{ id: string }>, res: Response) =>
|
|
|
1817
1852
|
? []
|
|
1818
1853
|
: resolveExcludeFields(auth.token.credentialAccess?.excludeFields, credential.type);
|
|
1819
1854
|
const baseExcludedNormalized = new Set(baseExclude.map(field => normalizeScope(field)));
|
|
1855
|
+
const requestedReadFields = parseRequestedReadFieldsInput(req.body, credential.type);
|
|
1856
|
+
const excludedFieldsPresent = Array.from(new Set(
|
|
1857
|
+
secrets
|
|
1858
|
+
.map((field) => normalizeScope(field.key))
|
|
1859
|
+
.filter((fieldKey) => baseExcludedNormalized.has(fieldKey)),
|
|
1860
|
+
));
|
|
1820
1861
|
const requestedExcludedFields = isAdmin(auth)
|
|
1821
1862
|
? []
|
|
1822
|
-
:
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
.
|
|
1826
|
-
|
|
1863
|
+
: requestedReadFields.requestsAllFields
|
|
1864
|
+
? excludedFieldsPresent
|
|
1865
|
+
: Array.from(new Set(
|
|
1866
|
+
requestedReadFields.requestedFields
|
|
1867
|
+
.map((field) => normalizeScope(field))
|
|
1868
|
+
.filter((fieldKey) => baseExcludedNormalized.has(fieldKey)),
|
|
1869
|
+
));
|
|
1827
1870
|
if (requestedExcludedFields.length > 0) {
|
|
1828
1871
|
const approvalTtl = await resolveOneShotApprovalTtl(auth);
|
|
1829
1872
|
const approvalSummaryBase = `${auth.token.agentId || 'agent'} requests excluded fields (${requestedExcludedFields.join(', ')}) from credential "${credential.name}"`;
|
|
@@ -23,6 +23,15 @@ function hasClaimSecret(init: RequestInit | undefined, expected: string): boolea
|
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function makeTestAgentToken(permissions: string[]): string {
|
|
27
|
+
const payload = Buffer.from(JSON.stringify({
|
|
28
|
+
agentId: 'cli-agent',
|
|
29
|
+
permissions,
|
|
30
|
+
exp: Date.now() + 60_000,
|
|
31
|
+
}), 'utf8').toString('base64url');
|
|
32
|
+
return `${payload}.sig`;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
const mocks = vi.hoisted(() => ({
|
|
27
36
|
bootstrapViaSocket: vi.fn(),
|
|
28
37
|
bootstrapViaAuthRequest: vi.fn(),
|
|
@@ -1234,6 +1243,44 @@ describe('agent CLI auth behavior', () => {
|
|
|
1234
1243
|
expect(getApprovalContext('req-rejected')).not.toBeNull();
|
|
1235
1244
|
});
|
|
1236
1245
|
|
|
1246
|
+
it('auth claim maps 200 rejected status to claim_rejected and clears context', async () => {
|
|
1247
|
+
process.env.WALLET_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'auramaxx-agent-auth-'));
|
|
1248
|
+
putApprovalContext({
|
|
1249
|
+
reqId: 'req-rejected-status',
|
|
1250
|
+
secret: 'sec-rejected-status',
|
|
1251
|
+
privateKeyPem: 'mock-private-key',
|
|
1252
|
+
approvalScope: 'session_token',
|
|
1253
|
+
ttlSeconds: 300,
|
|
1254
|
+
retryCommandTemplate: 'npx auramaxx agent get "github" --reqId <reqId>',
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
1258
|
+
const url = new URL(typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url);
|
|
1259
|
+
const method = init?.method || 'GET';
|
|
1260
|
+
if (url.pathname === '/auth/req-rejected-status' && method === 'GET' && hasClaimSecret(init, 'sec-rejected-status')) {
|
|
1261
|
+
return new Response(JSON.stringify({ success: true, status: 'rejected' }), {
|
|
1262
|
+
status: 200,
|
|
1263
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
throw new Error(`Unexpected fetch path: ${method} ${url.pathname}${url.search}`);
|
|
1267
|
+
});
|
|
1268
|
+
|
|
1269
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
1270
|
+
const exitCode = await runAuthCli(['claim', 'req-rejected-status', '--json']);
|
|
1271
|
+
expect(exitCode).toBe(1);
|
|
1272
|
+
|
|
1273
|
+
const payload = JSON.parse(String(logSpy.mock.calls[0][0])) as {
|
|
1274
|
+
claimStatus?: string;
|
|
1275
|
+
errorCode?: string;
|
|
1276
|
+
retryReady?: boolean;
|
|
1277
|
+
};
|
|
1278
|
+
expect(payload.claimStatus).toBe('rejected');
|
|
1279
|
+
expect(payload.errorCode).toBe('claim_rejected');
|
|
1280
|
+
expect(payload.retryReady).toBe(false);
|
|
1281
|
+
expect(getApprovalContext('req-rejected-status')).toBeNull();
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1237
1284
|
it('auth request --help exits without creating an auth request', async () => {
|
|
1238
1285
|
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(async () => {
|
|
1239
1286
|
throw new Error('fetch should not run for --help');
|
|
@@ -1489,4 +1536,71 @@ describe('agent CLI auth behavior', () => {
|
|
|
1489
1536
|
expect(mocks.createReadToken.mock.calls[0]?.[1]).toBe('fallback-auth-token');
|
|
1490
1537
|
expect(logSpy).toHaveBeenCalledWith('enc(gh-secret)');
|
|
1491
1538
|
});
|
|
1539
|
+
|
|
1540
|
+
it('skips delegated read token mint when fallback token is parseable non-admin', async () => {
|
|
1541
|
+
const nonAdminToken = makeTestAgentToken(['secret:read']);
|
|
1542
|
+
mocks.bootstrapViaSocket.mockRejectedValueOnce(new Error('Cannot connect to AuraMaxx: connect ENOENT /tmp/aura-cli.sock'));
|
|
1543
|
+
mocks.bootstrapViaAuthRequest.mockResolvedValueOnce(nonAdminToken);
|
|
1544
|
+
mocks.generateEphemeralKeypair.mockReturnValueOnce({
|
|
1545
|
+
publicKeyPem: 'ephemeral-public-key',
|
|
1546
|
+
privateKeyPem: 'ephemeral-private-key',
|
|
1547
|
+
publicKeyBase64: Buffer.from('ephemeral-public-key', 'utf8').toString('base64'),
|
|
1548
|
+
});
|
|
1549
|
+
mocks.decryptWithPrivateKey.mockImplementation((encrypted: string, privateKeyPem: string) => {
|
|
1550
|
+
expect(privateKeyPem).toBe('ephemeral-private-key');
|
|
1551
|
+
return encrypted;
|
|
1552
|
+
});
|
|
1553
|
+
|
|
1554
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
1555
|
+
const url = new URL(typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url);
|
|
1556
|
+
const method = init?.method || 'GET';
|
|
1557
|
+
|
|
1558
|
+
if (url.pathname === '/credentials' && method === 'GET' && url.searchParams.get('q') === 'github') {
|
|
1559
|
+
return new Response(JSON.stringify({
|
|
1560
|
+
credentials: [{
|
|
1561
|
+
id: 'cred-github',
|
|
1562
|
+
name: 'github',
|
|
1563
|
+
type: 'note',
|
|
1564
|
+
agentId: 'primary',
|
|
1565
|
+
meta: {},
|
|
1566
|
+
}],
|
|
1567
|
+
}), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
if (url.pathname === '/setup/agents' && method === 'GET') {
|
|
1571
|
+
return new Response(JSON.stringify({
|
|
1572
|
+
agents: [{ id: 'primary', name: 'primary', isPrimary: true }],
|
|
1573
|
+
}), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
if (url.pathname === '/setup' && method === 'GET') {
|
|
1577
|
+
return new Response(JSON.stringify({ projectScopeMode: 'auto' }), {
|
|
1578
|
+
status: 200,
|
|
1579
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
if (url.pathname === '/credentials/cred-github/read' && method === 'POST') {
|
|
1584
|
+
const headers = init?.headers as Record<string, string>;
|
|
1585
|
+
expect(headers.Authorization).toBe(`Bearer ${nonAdminToken}`);
|
|
1586
|
+
return new Response(JSON.stringify({
|
|
1587
|
+
encrypted: JSON.stringify({
|
|
1588
|
+
id: 'cred-github',
|
|
1589
|
+
agentId: 'primary',
|
|
1590
|
+
type: 'note',
|
|
1591
|
+
fields: [{ key: 'value', value: 'gh-secret', sensitive: true }],
|
|
1592
|
+
}),
|
|
1593
|
+
}), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
throw new Error(`Unexpected fetch path: ${method} ${url.pathname}${url.search}`);
|
|
1597
|
+
});
|
|
1598
|
+
|
|
1599
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
1600
|
+
const exitCode = await runAgentCli(['get', 'github']);
|
|
1601
|
+
|
|
1602
|
+
expect(exitCode).toBe(0);
|
|
1603
|
+
expect(mocks.createReadToken).not.toHaveBeenCalled();
|
|
1604
|
+
expect(logSpy).toHaveBeenCalledWith('enc(gh-secret)');
|
|
1605
|
+
});
|
|
1492
1606
|
});
|
|
@@ -19,15 +19,20 @@ describe('local agent trust helpers', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('resolves mode selection for numbered and named inputs', () => {
|
|
22
|
-
expect(resolveLocalAgentModeChoice('')).toBe('
|
|
23
|
-
expect(resolveLocalAgentModeChoice('1')).toBe('
|
|
22
|
+
expect(resolveLocalAgentModeChoice('')).toBe('admin');
|
|
23
|
+
expect(resolveLocalAgentModeChoice('1')).toBe('admin');
|
|
24
|
+
expect(resolveLocalAgentModeChoice('maxx')).toBe('admin');
|
|
25
|
+
expect(resolveLocalAgentModeChoice('work')).toBe('admin');
|
|
26
|
+
expect(resolveLocalAgentModeChoice('admin')).toBe('admin');
|
|
27
|
+
|
|
28
|
+
expect(resolveLocalAgentModeChoice('2')).toBe('dev');
|
|
29
|
+
expect(resolveLocalAgentModeChoice('mid')).toBe('dev');
|
|
24
30
|
expect(resolveLocalAgentModeChoice('dev')).toBe('dev');
|
|
25
31
|
|
|
26
|
-
expect(resolveLocalAgentModeChoice('
|
|
32
|
+
expect(resolveLocalAgentModeChoice('3')).toBe('strict');
|
|
33
|
+
expect(resolveLocalAgentModeChoice('sus')).toBe('strict');
|
|
34
|
+
expect(resolveLocalAgentModeChoice('local')).toBe('strict');
|
|
27
35
|
expect(resolveLocalAgentModeChoice('strict')).toBe('strict');
|
|
28
|
-
|
|
29
|
-
expect(resolveLocalAgentModeChoice('3')).toBe('admin');
|
|
30
|
-
expect(resolveLocalAgentModeChoice('admin')).toBe('admin');
|
|
31
36
|
});
|
|
32
37
|
|
|
33
38
|
it('derives auto-approve defaults per profile mode', () => {
|