openyida 2026.8.19 → 2026.8.25
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/bin/yida.js +3 -7
- package/lib/app-permission/app-permission.js +25 -6
- package/lib/auth/org.js +8 -8
- package/lib/auth/profile.js +6 -6
- package/lib/auth/token-auth.js +39 -28
- package/lib/auth/token-store.js +58 -34
- package/lib/core/agent-capabilities.js +14 -102
- package/lib/core/locales/en.js +55 -1
- package/lib/core/locales/zh.js +55 -1
- package/lib/core/query-data.js +21 -0
- package/lib/core/utils.js +15 -11
- package/lib/corp-manager/api.js +15 -3
- package/lib/corp-manager/corp-manager.js +34 -4
- package/lib/integration/connector-presets.js +2 -3
- package/lib/integration/integration-create.js +161 -80
- package/lib/integration/integration-process-builder.js +177 -48
- package/lib/integration/integration-spec-builder.js +171 -48
- package/lib/integration/integration-view-builder.js +26 -25
- package/lib/page-config/save-share-config.js +111 -10
- package/lib/permission/get-permission.js +15 -0
- package/lib/permission/matrix-service.js +56 -0
- package/lib/permission/save-permission.js +470 -68
- package/lib/process/configure-process.js +114 -71
- package/lib/process/create-process.js +4 -1
- package/lib/process/services/process-compiler.js +53 -28
- package/package.json +5 -1
- package/yida-skills/skills/yida-app-permission/SKILL.md +39 -47
- package/yida-skills/skills/yida-corp-manager/SKILL.md +45 -34
- package/yida-skills/skills/yida-data-management/SKILL.md +1 -0
- package/yida-skills/skills/yida-form-permission/SKILL.md +108 -77
- package/yida-skills/skills/yida-integration/references/integration-node-schemas.md +2 -2
- package/yida-skills/skills/yida-page-config/SKILL.md +54 -79
package/bin/yida.js
CHANGED
|
@@ -670,15 +670,13 @@ async function main() {
|
|
|
670
670
|
|
|
671
671
|
case 'login': {
|
|
672
672
|
const loginArgs = applyLoginEnvironmentFlags(args, { inferTargetUrl: true });
|
|
673
|
-
const { getAuthStatus
|
|
673
|
+
const { getAuthStatus } = require('../lib/core/utils');
|
|
674
674
|
if (hasHelpFlag(loginArgs)) {
|
|
675
675
|
printLoginHelp();
|
|
676
676
|
} else {
|
|
677
677
|
assertNoUnsupportedLegacyLoginFlags(rawArgs, loginArgs);
|
|
678
678
|
if (loginArgs.includes('--check-only')) {
|
|
679
679
|
console.log(JSON.stringify(getAuthStatus(buildTokenLoginOptions(loginArgs)), null, 2));
|
|
680
|
-
} else if (isEnvAuthMode()) {
|
|
681
|
-
printLoginResult(getAuthStatus(buildTokenLoginOptions(loginArgs)));
|
|
682
680
|
} else {
|
|
683
681
|
const { tokenLogin } = require('../lib/auth/token-auth');
|
|
684
682
|
const result = await tokenLogin(buildTokenLoginOptions(loginArgs));
|
|
@@ -697,7 +695,7 @@ async function main() {
|
|
|
697
695
|
case 'auth': {
|
|
698
696
|
const subCommand = args[0];
|
|
699
697
|
const authArgs = applyLoginEnvironmentFlags(args.slice(1), { inferTargetUrl: true });
|
|
700
|
-
const { getAuthStatus
|
|
698
|
+
const { getAuthStatus } = require('../lib/core/utils');
|
|
701
699
|
const { tokenLogin, tokenLogout, tokenRefresh } = require('../lib/auth/token-auth');
|
|
702
700
|
if (!subCommand || subCommand === '--help' || subCommand === '-h') {
|
|
703
701
|
printAuthHelp();
|
|
@@ -720,9 +718,7 @@ async function main() {
|
|
|
720
718
|
printLoginHelp();
|
|
721
719
|
} else {
|
|
722
720
|
assertNoUnsupportedLegacyLoginFlags(rawArgs.slice(1), authArgs);
|
|
723
|
-
const result =
|
|
724
|
-
? getAuthStatus(buildTokenLoginOptions(authArgs))
|
|
725
|
-
: await tokenLogin(buildTokenLoginOptions(authArgs));
|
|
721
|
+
const result = await tokenLogin(buildTokenLoginOptions(authArgs));
|
|
726
722
|
printLoginResult(result);
|
|
727
723
|
}
|
|
728
724
|
} else if (subCommand === 'refresh') {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { createAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
4
4
|
const { CliError } = require('../core/cli-error');
|
|
5
|
+
const { t } = require('../core/i18n');
|
|
5
6
|
const { searchUsers } = require('../corp-manager/api');
|
|
6
7
|
|
|
7
8
|
const ROLE_CONFIGS = {
|
|
@@ -140,6 +141,12 @@ function unique(values) {
|
|
|
140
141
|
return [...new Set((values || []).map(value => String(value).trim()).filter(Boolean))];
|
|
141
142
|
}
|
|
142
143
|
|
|
144
|
+
function sameUserIds(left, right) {
|
|
145
|
+
const leftIds = unique(left).sort();
|
|
146
|
+
const rightIds = unique(right).sort();
|
|
147
|
+
return JSON.stringify(leftIds) === JSON.stringify(rightIds);
|
|
148
|
+
}
|
|
149
|
+
|
|
143
150
|
function toPositiveInt(value, defaultValue) {
|
|
144
151
|
const parsed = Number.parseInt(value || `${defaultValue}`, 10);
|
|
145
152
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
@@ -310,11 +317,7 @@ async function updateRoleManagers(options = {}, authRef = getAuthRef()) {
|
|
|
310
317
|
const action = options.action || 'set';
|
|
311
318
|
const inputUserIds = unique(options.userIds || options.users || []);
|
|
312
319
|
|
|
313
|
-
if (action
|
|
314
|
-
return saveRoleManagers({ appType, roleType, userIds: inputUserIds }, authRef);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (inputUserIds.length === 0) {
|
|
320
|
+
if (action !== 'set' && inputUserIds.length === 0) {
|
|
318
321
|
throw new Error(`${action} 操作必须提供 --users`);
|
|
319
322
|
}
|
|
320
323
|
|
|
@@ -323,7 +326,9 @@ async function updateRoleManagers(options = {}, authRef = getAuthRef()) {
|
|
|
323
326
|
const previousUserIds = current.roles[roleKey].userIds;
|
|
324
327
|
let nextUserIds;
|
|
325
328
|
|
|
326
|
-
if (action === '
|
|
329
|
+
if (action === 'set') {
|
|
330
|
+
nextUserIds = inputUserIds;
|
|
331
|
+
} else if (action === 'add') {
|
|
327
332
|
nextUserIds = unique(previousUserIds.concat(inputUserIds));
|
|
328
333
|
} else if (action === 'remove') {
|
|
329
334
|
const removeSet = new Set(inputUserIds);
|
|
@@ -387,9 +392,22 @@ async function runUpdate(action, positionals, options) {
|
|
|
387
392
|
});
|
|
388
393
|
const current = await getAppPermission(appType);
|
|
389
394
|
const roleKey = ROLE_CONFIGS[saved.roleType].key;
|
|
395
|
+
if (!sameUserIds(saved.userIds, current.roles[roleKey].userIds)) {
|
|
396
|
+
throw new CliError(t('app_permission.verify_failed'), {
|
|
397
|
+
code: 'APP_PERMISSION_VERIFY_FAILED',
|
|
398
|
+
details: {
|
|
399
|
+
expected: saved.userIds,
|
|
400
|
+
actual: current.roles[roleKey].userIds,
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
}
|
|
390
404
|
|
|
391
405
|
printJson({
|
|
392
406
|
...saved,
|
|
407
|
+
before: {
|
|
408
|
+
userIds: saved.previousUserIds,
|
|
409
|
+
},
|
|
410
|
+
after: current.roles[roleKey],
|
|
393
411
|
currentRole: current.roles[roleKey],
|
|
394
412
|
});
|
|
395
413
|
}
|
|
@@ -420,6 +438,7 @@ module.exports = {
|
|
|
420
438
|
USAGE,
|
|
421
439
|
parseCliOptions,
|
|
422
440
|
splitList,
|
|
441
|
+
sameUserIds,
|
|
423
442
|
normalizeRole,
|
|
424
443
|
normalizeText,
|
|
425
444
|
normalizeMember,
|
package/lib/auth/org.js
CHANGED
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
loadTokenSession,
|
|
14
14
|
normalizeCorpName,
|
|
15
15
|
resolveTokenSession,
|
|
16
|
-
|
|
16
|
+
isEnvTokenAuthMode,
|
|
17
17
|
saveAuthProfilePointer,
|
|
18
18
|
saveProjectLegacyTokenSession,
|
|
19
19
|
saveTokenSession,
|
|
@@ -70,15 +70,15 @@ function createProfileRequiredError(targetCorpId, resolution = {}) {
|
|
|
70
70
|
return error;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function
|
|
73
|
+
function createEnvTokenSwitchError(targetCorpId, currentSession, resolution = {}) {
|
|
74
74
|
const actualCorpId = currentSession && currentSession.corp_id;
|
|
75
|
-
const error = new Error(
|
|
76
|
-
error.code = '
|
|
77
|
-
error.status = '
|
|
75
|
+
const error = new Error(`当前为 env token 登录态,不能通过 OAuth 切换组织:target=${targetCorpId}, actual=${actualCorpId || 'unknown'}`);
|
|
76
|
+
error.code = 'ORG_SWITCH_ENV_TOKEN_MISMATCH';
|
|
77
|
+
error.status = 'env_token_mismatch';
|
|
78
78
|
error.targetCorpId = targetCorpId;
|
|
79
79
|
error.actualCorpId = actualCorpId;
|
|
80
80
|
error.auth_source = resolution.auth_source || (currentSession && currentSession.auth_source) || 'env';
|
|
81
|
-
error.auth_store = resolution.auth_store || (currentSession && currentSession.auth_store) || '
|
|
81
|
+
error.auth_store = resolution.auth_store || (currentSession && currentSession.auth_store) || 'env';
|
|
82
82
|
error.can_auto_use = false;
|
|
83
83
|
return error;
|
|
84
84
|
}
|
|
@@ -220,8 +220,8 @@ async function switchOrganization(targetCorpId, options = {}) {
|
|
|
220
220
|
if (targetResolution.status === 'profile_required') {
|
|
221
221
|
throw createProfileRequiredError(targetCorpId, targetResolution);
|
|
222
222
|
}
|
|
223
|
-
if (
|
|
224
|
-
throw
|
|
223
|
+
if (isEnvTokenAuthMode(projectOptions.env)) {
|
|
224
|
+
throw createEnvTokenSwitchError(targetCorpId, currentSession, targetResolution);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
const loginOptions = {
|
package/lib/auth/profile.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { CliError } = require('../core/cli-error');
|
|
4
4
|
const {
|
|
5
|
-
|
|
5
|
+
isEnvTokenAuthMode,
|
|
6
6
|
listUserAuthProfiles,
|
|
7
7
|
loadAuthProfilePointer,
|
|
8
8
|
loadTokenSession,
|
|
@@ -129,14 +129,14 @@ function resolveSwitchTarget(target, options = {}) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function switchAuthProfile(target, options = {}) {
|
|
132
|
-
if (
|
|
132
|
+
if (isEnvTokenAuthMode(options.env || process.env)) {
|
|
133
133
|
throw new CliError(
|
|
134
|
-
'
|
|
134
|
+
'env token mode cannot switch local auth profiles',
|
|
135
135
|
{
|
|
136
|
-
code: '
|
|
136
|
+
code: 'AUTH_PROFILE_SWITCH_ENV_TOKEN',
|
|
137
137
|
details: {
|
|
138
|
-
nextStep: 'Ask the
|
|
139
|
-
next_step: 'Ask the
|
|
138
|
+
nextStep: 'Ask the runtime to inject the target organization token instead of switching local profiles.',
|
|
139
|
+
next_step: 'Ask the runtime to inject the target organization token instead of switching local profiles.',
|
|
140
140
|
},
|
|
141
141
|
}
|
|
142
142
|
);
|
package/lib/auth/token-auth.js
CHANGED
|
@@ -15,14 +15,13 @@ const {
|
|
|
15
15
|
clearAllUserAuthProfiles,
|
|
16
16
|
clearTokenSession,
|
|
17
17
|
deleteUserAuthProfile,
|
|
18
|
-
|
|
18
|
+
isEnvTokenAuthMode,
|
|
19
19
|
listUserAuthProfiles,
|
|
20
20
|
loadLocalTokenSession,
|
|
21
21
|
loadTokenSession,
|
|
22
22
|
loadUserProfileFile,
|
|
23
23
|
maskToken,
|
|
24
24
|
normalizeCorpName,
|
|
25
|
-
normalizeTokenSession,
|
|
26
25
|
resolveTokenSession,
|
|
27
26
|
saveBusinessContext,
|
|
28
27
|
saveTokenSession,
|
|
@@ -274,6 +273,32 @@ function isRefreshAuthRequired(value) {
|
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
async function tokenLogin(options = {}) {
|
|
276
|
+
const env = options.env || process.env;
|
|
277
|
+
if (isEnvTokenAuthMode(env)) {
|
|
278
|
+
const status = tokenStatus(options);
|
|
279
|
+
if (status && status.can_auto_use) {
|
|
280
|
+
return {
|
|
281
|
+
...status,
|
|
282
|
+
ok: true,
|
|
283
|
+
status: 'ok',
|
|
284
|
+
can_auto_use: true,
|
|
285
|
+
message: 'env token bootstrap credentials are already available; OAuth login was skipped',
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
...status,
|
|
290
|
+
ok: false,
|
|
291
|
+
auth_mode: 'token',
|
|
292
|
+
auth_source: status && status.auth_source ? status.auth_source : 'env',
|
|
293
|
+
auth_store: status && status.auth_store ? status.auth_store : 'env',
|
|
294
|
+
status: status && status.status ? status.status : 'not_logged_in',
|
|
295
|
+
can_auto_use: false,
|
|
296
|
+
message: status && status.message
|
|
297
|
+
? status.message
|
|
298
|
+
: 'env token bootstrap credential is missing. Ask the runtime to inject OPENYIDA_ACCESS_TOKEN or OPENYIDA_REFRESH_TOKEN.',
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
277
302
|
const baseUrl = resolveTokenBaseUrl(options);
|
|
278
303
|
const authBaseUrl = appendPath(baseUrl, DEFAULT_AUTH_PATH_PREFIX);
|
|
279
304
|
const clientId = options.clientId || process.env.OPENYIDA_DINGTALK_CLIENT_ID || DINGTALK_OAUTH_CLIENT_ID;
|
|
@@ -315,21 +340,21 @@ function tokenStatus(options = {}) {
|
|
|
315
340
|
const session = resolution.session;
|
|
316
341
|
if (!session || (!session.access_token && !session.refresh_token)) {
|
|
317
342
|
const env = options.env || process.env;
|
|
318
|
-
const
|
|
343
|
+
const envTokenMode = isEnvTokenAuthMode(env);
|
|
319
344
|
const status = {
|
|
320
345
|
ok: false,
|
|
321
346
|
auth_mode: 'token',
|
|
322
|
-
auth_source: resolution.auth_source || (
|
|
347
|
+
auth_source: resolution.auth_source || (envTokenMode ? 'env' : undefined),
|
|
323
348
|
auth_store: resolution.auth_store,
|
|
324
349
|
auth_profile: resolution.auth_profile,
|
|
325
350
|
status: resolution.status === 'profile_required' ? 'profile_required' : 'not_logged_in',
|
|
326
351
|
can_auto_use: false,
|
|
327
|
-
failure_reason:
|
|
328
|
-
message: resolution.message || (
|
|
329
|
-
? '
|
|
352
|
+
failure_reason: envTokenMode ? 'env_token_missing' : resolution.status,
|
|
353
|
+
message: resolution.message || (envTokenMode
|
|
354
|
+
? 'env token bootstrap credential is missing. Ask the runtime to inject OPENYIDA_ACCESS_TOKEN or OPENYIDA_REFRESH_TOKEN.'
|
|
330
355
|
: undefined),
|
|
331
|
-
next_step: resolution.next_step || (
|
|
332
|
-
? 'Ask the
|
|
356
|
+
next_step: resolution.next_step || (envTokenMode
|
|
357
|
+
? 'Ask the runtime to inject OPENYIDA_ACCESS_TOKEN or OPENYIDA_REFRESH_TOKEN; stop until credentials are available.'
|
|
333
358
|
: 'Run openyida login to add an auth profile.'),
|
|
334
359
|
next_step_commands: resolution.next_step_commands,
|
|
335
360
|
candidate_count: resolution.candidate_count,
|
|
@@ -338,7 +363,7 @@ function tokenStatus(options = {}) {
|
|
|
338
363
|
persistence_scope: resolution.persistence_scope,
|
|
339
364
|
warning: resolution.warning,
|
|
340
365
|
};
|
|
341
|
-
if (!
|
|
366
|
+
if (!envTokenMode) {
|
|
342
367
|
status.token_file = require('./token-store').getTokenFilePath(options);
|
|
343
368
|
}
|
|
344
369
|
return status;
|
|
@@ -353,7 +378,7 @@ function tokenStatus(options = {}) {
|
|
|
353
378
|
persistence_scope: session.persistence_scope,
|
|
354
379
|
user_auth_store_writable: session.user_auth_store_writable,
|
|
355
380
|
warning: session.warning,
|
|
356
|
-
status: '
|
|
381
|
+
status: 'ok',
|
|
357
382
|
can_auto_use: true,
|
|
358
383
|
refresh_token: maskToken(session.refresh_token),
|
|
359
384
|
base_url: session.base_url,
|
|
@@ -446,7 +471,7 @@ async function tokenRefresh(options = {}) {
|
|
|
446
471
|
}
|
|
447
472
|
}
|
|
448
473
|
const env = options.env || process.env;
|
|
449
|
-
if (
|
|
474
|
+
if (isEnvTokenAuthMode(env) && ['env', 'project_legacy'].includes(session.auth_source)) {
|
|
450
475
|
env.OPENYIDA_ACCESS_TOKEN = normalized.access_token;
|
|
451
476
|
if (normalized.refresh_token) {
|
|
452
477
|
env.OPENYIDA_REFRESH_TOKEN = normalized.refresh_token;
|
|
@@ -454,10 +479,10 @@ async function tokenRefresh(options = {}) {
|
|
|
454
479
|
if (normalized.expires_at) {
|
|
455
480
|
env.OPENYIDA_ACCESS_TOKEN_EXPIRES_AT = String(normalized.expires_at);
|
|
456
481
|
}
|
|
457
|
-
return
|
|
482
|
+
return saveTokenSession({
|
|
458
483
|
...normalized,
|
|
459
484
|
auth_source: 'env',
|
|
460
|
-
});
|
|
485
|
+
}, options);
|
|
461
486
|
}
|
|
462
487
|
return saveTokenSession(normalized, options);
|
|
463
488
|
}
|
|
@@ -496,20 +521,6 @@ function toLogoutProfileSummary(session = {}) {
|
|
|
496
521
|
}
|
|
497
522
|
|
|
498
523
|
async function tokenLogout(options = {}) {
|
|
499
|
-
const env = options.env || process.env;
|
|
500
|
-
if (isHostInjectedTokenMode(env)) {
|
|
501
|
-
return {
|
|
502
|
-
ok: true,
|
|
503
|
-
auth_mode: 'token',
|
|
504
|
-
status: 'host_injected_noop',
|
|
505
|
-
can_auto_use: false,
|
|
506
|
-
auth_source: 'env',
|
|
507
|
-
auth_store: 'host_injected',
|
|
508
|
-
persistence_scope: 'host',
|
|
509
|
-
message: 'host-injected token mode does not write or delete local auth profiles',
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
|
|
513
524
|
const authProfile = options.authProfile || options.profile;
|
|
514
525
|
const deleteAllProfiles = options.allProfiles === true || options.all === true;
|
|
515
526
|
if (deleteAllProfiles) {
|
package/lib/auth/token-store.js
CHANGED
|
@@ -394,6 +394,7 @@ function buildAuthProfileNextStep(status) {
|
|
|
394
394
|
|
|
395
395
|
function getAuthProfileSelector(options = {}) {
|
|
396
396
|
const env = options.env || process.env;
|
|
397
|
+
const envTokenMode = isEnvTokenAuthMode(env);
|
|
397
398
|
return {
|
|
398
399
|
authProfile: sanitizeProfileName(
|
|
399
400
|
options.authProfile ||
|
|
@@ -401,8 +402,18 @@ function getAuthProfileSelector(options = {}) {
|
|
|
401
402
|
env.OPENYIDA_AUTH_PROFILE ||
|
|
402
403
|
''
|
|
403
404
|
),
|
|
404
|
-
corpId: String(
|
|
405
|
-
|
|
405
|
+
corpId: String(
|
|
406
|
+
options.corpId ||
|
|
407
|
+
env.OPENYIDA_AUTH_CORP_ID ||
|
|
408
|
+
(envTokenMode ? env.OPENYIDA_TOKEN_CORP_ID : '') ||
|
|
409
|
+
''
|
|
410
|
+
).trim(),
|
|
411
|
+
userId: String(
|
|
412
|
+
options.userId ||
|
|
413
|
+
env.OPENYIDA_AUTH_USER_ID ||
|
|
414
|
+
(envTokenMode ? env.OPENYIDA_TOKEN_USER_ID : '') ||
|
|
415
|
+
''
|
|
416
|
+
).trim(),
|
|
406
417
|
};
|
|
407
418
|
}
|
|
408
419
|
|
|
@@ -585,13 +596,8 @@ function saveUserTokenSession(session, options = {}) {
|
|
|
585
596
|
function saveTokenSession(session, options = {}) {
|
|
586
597
|
const env = options.env || process.env;
|
|
587
598
|
const normalized = normalizeTokenSession(session);
|
|
588
|
-
if (
|
|
589
|
-
return
|
|
590
|
-
auth_source: 'env',
|
|
591
|
-
auth_store: 'host_injected',
|
|
592
|
-
persistence_scope: 'host',
|
|
593
|
-
user_auth_store_writable: null,
|
|
594
|
-
});
|
|
599
|
+
if (isEnvTokenAuthMode(env) && normalized.auth_source === 'env') {
|
|
600
|
+
return saveProjectLegacyTokenSession(normalized, options);
|
|
595
601
|
}
|
|
596
602
|
|
|
597
603
|
try {
|
|
@@ -616,9 +622,15 @@ function saveTokenSession(session, options = {}) {
|
|
|
616
622
|
}
|
|
617
623
|
}
|
|
618
624
|
|
|
619
|
-
function
|
|
620
|
-
|
|
621
|
-
|
|
625
|
+
function isEnvTokenAuthMode(env = process.env) {
|
|
626
|
+
return String(env.OPENYIDA_AUTH_MODE || '').trim().toLowerCase() === 'token';
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function hasEnvTokenCredential(env = process.env) {
|
|
630
|
+
return !!(
|
|
631
|
+
String(env.OPENYIDA_ACCESS_TOKEN || '').trim() ||
|
|
632
|
+
String(env.OPENYIDA_REFRESH_TOKEN || '').trim()
|
|
633
|
+
);
|
|
622
634
|
}
|
|
623
635
|
|
|
624
636
|
function loadEnvTokenSession(env = process.env) {
|
|
@@ -773,29 +785,40 @@ function resolveTokenSession(options = {}) {
|
|
|
773
785
|
const env = options.env || process.env;
|
|
774
786
|
const selector = getAuthProfileSelector(options);
|
|
775
787
|
const envSession = applyBusinessContextToEnvSession(loadEnvTokenSession(env), options);
|
|
776
|
-
if (
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
788
|
+
if (isEnvTokenAuthMode(env)) {
|
|
789
|
+
const localSession = loadLocalTokenSession(options);
|
|
790
|
+
if (
|
|
791
|
+
localSession &&
|
|
792
|
+
(localSession.access_token || localSession.refresh_token) &&
|
|
793
|
+
sessionMatchesSelector(localSession, selector)
|
|
794
|
+
) {
|
|
795
|
+
return {
|
|
796
|
+
session: localSession,
|
|
797
|
+
status: 'ok',
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
if (
|
|
801
|
+
hasEnvTokenCredential(env) &&
|
|
802
|
+
envSession &&
|
|
803
|
+
(envSession.access_token || envSession.refresh_token) &&
|
|
804
|
+
sessionMatchesSelector(envSession, selector, { allowMissingIdentity: true })
|
|
805
|
+
) {
|
|
806
|
+
return {
|
|
807
|
+
session: attachAuthStoreMetadata(envSession, {
|
|
808
|
+
auth_source: 'env',
|
|
809
|
+
auth_store: 'env',
|
|
810
|
+
persistence_scope: 'process',
|
|
811
|
+
user_auth_store_writable: null,
|
|
812
|
+
}),
|
|
813
|
+
status: 'ok',
|
|
814
|
+
};
|
|
815
|
+
}
|
|
793
816
|
return {
|
|
794
817
|
session: null,
|
|
795
818
|
status: 'env_token_missing',
|
|
796
819
|
auth_source: 'env',
|
|
797
|
-
auth_store: '
|
|
798
|
-
persistence_scope: '
|
|
820
|
+
auth_store: 'env',
|
|
821
|
+
persistence_scope: 'process',
|
|
799
822
|
user_auth_store_writable: null,
|
|
800
823
|
};
|
|
801
824
|
}
|
|
@@ -807,7 +830,7 @@ function resolveTokenSession(options = {}) {
|
|
|
807
830
|
return {
|
|
808
831
|
session: attachAuthStoreMetadata(envSession, {
|
|
809
832
|
auth_source: 'env',
|
|
810
|
-
auth_store: '
|
|
833
|
+
auth_store: 'env',
|
|
811
834
|
persistence_scope: 'process',
|
|
812
835
|
user_auth_store_writable: getUserAuthStoreWritable(options),
|
|
813
836
|
}),
|
|
@@ -895,7 +918,7 @@ function resolveTokenSession(options = {}) {
|
|
|
895
918
|
return {
|
|
896
919
|
session: attachAuthStoreMetadata(envSession, {
|
|
897
920
|
auth_source: 'env',
|
|
898
|
-
auth_store: '
|
|
921
|
+
auth_store: 'env',
|
|
899
922
|
persistence_scope: 'process',
|
|
900
923
|
user_auth_store_writable: getUserAuthStoreWritable(options),
|
|
901
924
|
}),
|
|
@@ -975,7 +998,8 @@ module.exports = {
|
|
|
975
998
|
loadEnvTokenSession,
|
|
976
999
|
loadLocalTokenSession,
|
|
977
1000
|
saveProjectLegacyTokenSession,
|
|
978
|
-
|
|
1001
|
+
isEnvTokenAuthMode,
|
|
1002
|
+
hasEnvTokenCredential,
|
|
979
1003
|
isAccessTokenUsable,
|
|
980
1004
|
maskToken,
|
|
981
1005
|
resolveEnvName,
|
|
@@ -105,38 +105,6 @@ function compactSkillsDiagnostics(skillsDiagnostics) {
|
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
function isTruthyEnv(value) {
|
|
109
|
-
return ['1', 'true', 'yes', 'on'].includes(String(value || '').trim().toLowerCase());
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function hasEnvTokenCredential(env = process.env) {
|
|
113
|
-
return !!(
|
|
114
|
-
String(env.OPENYIDA_ACCESS_TOKEN || '').trim() ||
|
|
115
|
-
String(env.OPENYIDA_REFRESH_TOKEN || '').trim()
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function hasRuntimeProvisionedAccessToken(env = process.env) {
|
|
120
|
-
return isTruthyEnv(env.YIDA_AUTH_ENABLED) &&
|
|
121
|
-
!!String(env.OPENYIDA_ACCESS_TOKEN || '').trim();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function buildRuntimeProvisionedLoginStatus(env = process.env) {
|
|
125
|
-
return {
|
|
126
|
-
ok: true,
|
|
127
|
-
auth_mode: 'token',
|
|
128
|
-
auth_source: 'env',
|
|
129
|
-
auth_store: 'host_injected',
|
|
130
|
-
corp_id: env.OPENYIDA_TOKEN_CORP_ID,
|
|
131
|
-
corp_name: env.OPENYIDA_TOKEN_CORP_NAME,
|
|
132
|
-
user_id: env.OPENYIDA_TOKEN_USER_ID,
|
|
133
|
-
user_auth_store_writable: null,
|
|
134
|
-
persistence_scope: 'host',
|
|
135
|
-
status: 'ok',
|
|
136
|
-
can_auto_use: true,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
108
|
function buildRuntimeSnapshot(projectRoot) {
|
|
141
109
|
const detected = typeof coreUtils.detectRuntimeCapabilities === 'function'
|
|
142
110
|
? coreUtils.detectRuntimeCapabilities()
|
|
@@ -204,18 +172,12 @@ function forbiddenAliasBriefs(manifest) {
|
|
|
204
172
|
}
|
|
205
173
|
|
|
206
174
|
function buildAuthPath(login, env = process.env) {
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
const authSource = login.auth_source || (hostInjectedTokenMode || envTokenPresent ? 'env' : 'token_session');
|
|
210
|
-
const hostTokenEnvDetected = hostInjectedTokenMode || envTokenPresent || authSource === 'env';
|
|
211
|
-
const authStore = login.auth_store || (hostTokenEnvDetected ? 'host_injected' : undefined);
|
|
212
|
-
const runtimeAuthProvisioned = hasRuntimeProvisionedAccessToken(env) &&
|
|
213
|
-
authSource === 'env' &&
|
|
214
|
-
login.status === 'ok';
|
|
175
|
+
const authSource = login.auth_source || 'token_session';
|
|
176
|
+
const envTokenSession = authSource === 'env' || login.failure_reason === 'env_token_missing';
|
|
215
177
|
const authPath = {
|
|
216
178
|
mode: login.auth_mode || 'token',
|
|
217
179
|
source: authSource,
|
|
218
|
-
store:
|
|
180
|
+
store: login.auth_store,
|
|
219
181
|
auth_profile: login.auth_profile,
|
|
220
182
|
corp_id: login.corp_id,
|
|
221
183
|
corp_name: login.corp_name,
|
|
@@ -227,12 +189,9 @@ function buildAuthPath(login, env = process.env) {
|
|
|
227
189
|
next_step: login.next_step,
|
|
228
190
|
next_step_commands: login.next_step_commands,
|
|
229
191
|
can_auto_use: login.can_auto_use === true,
|
|
230
|
-
|
|
231
|
-
host_token_env_detected: hostTokenEnvDetected,
|
|
232
|
-
env_token_present: envTokenPresent,
|
|
233
|
-
interactive_login_allowed: !hostTokenEnvDetected,
|
|
192
|
+
interactive_login_allowed: !envTokenSession,
|
|
234
193
|
browser_session_auth_allowed: false,
|
|
235
|
-
auth_runtime: 'token_oauth_session',
|
|
194
|
+
auth_runtime: envTokenSession ? 'env_token_bootstrap' : 'token_oauth_session',
|
|
236
195
|
cookie_auth_supported: false,
|
|
237
196
|
cookie_check_required: false,
|
|
238
197
|
playwright_cookie_check_required: false,
|
|
@@ -243,13 +202,10 @@ function buildAuthPath(login, env = process.env) {
|
|
|
243
202
|
'qr_login',
|
|
244
203
|
'cookie_cache',
|
|
245
204
|
],
|
|
246
|
-
missing_token_action:
|
|
247
|
-
? '
|
|
205
|
+
missing_token_action: envTokenSession
|
|
206
|
+
? 'STOP_AND_REQUEST_ENV_TOKEN'
|
|
248
207
|
: 'RUN_OPENYIDA_LOGIN_IF_USER_APPROVES',
|
|
249
208
|
};
|
|
250
|
-
if (runtimeAuthProvisioned) {
|
|
251
|
-
authPath.runtime_auth_provisioned = true;
|
|
252
|
-
}
|
|
253
209
|
return authPath;
|
|
254
210
|
}
|
|
255
211
|
|
|
@@ -261,14 +217,14 @@ function buildInteractiveLogin(auth, runtime) {
|
|
|
261
217
|
playwright_required: false,
|
|
262
218
|
};
|
|
263
219
|
|
|
264
|
-
if (auth.
|
|
220
|
+
if (!auth.interactive_login_allowed) {
|
|
265
221
|
return {
|
|
266
222
|
mode: 'not_required',
|
|
267
223
|
browser_default: 'not_required',
|
|
268
224
|
browser_owner: 'none',
|
|
269
225
|
recommended_command: null,
|
|
270
226
|
agent_action: 'do_not_run_oauth_login',
|
|
271
|
-
reason: auth.
|
|
227
|
+
reason: auth.source === 'env' ? 'env_token_bootstrap' : 'login_not_required',
|
|
272
228
|
...base,
|
|
273
229
|
};
|
|
274
230
|
}
|
|
@@ -306,7 +262,7 @@ function buildInteractiveLogin(auth, runtime) {
|
|
|
306
262
|
browser_default: 'unsupported',
|
|
307
263
|
browser_owner: 'none',
|
|
308
264
|
recommended_command: null,
|
|
309
|
-
agent_action: '
|
|
265
|
+
agent_action: 'ask_user_for_browser_access',
|
|
310
266
|
reason: 'no_desktop_shell_or_agent_browser_detected',
|
|
311
267
|
...base,
|
|
312
268
|
};
|
|
@@ -314,7 +270,7 @@ function buildInteractiveLogin(auth, runtime) {
|
|
|
314
270
|
|
|
315
271
|
function buildBuilderPath(login, projectRoot, manifest, env = process.env, runtimeSnapshot = null) {
|
|
316
272
|
const auth = buildAuthPath(login, env);
|
|
317
|
-
const canTrustSummaryPreflight = auth.can_auto_use === true
|
|
273
|
+
const canTrustSummaryPreflight = auth.can_auto_use === true;
|
|
318
274
|
const runtime = runtimeSnapshot || buildRuntimeSnapshot(projectRoot);
|
|
319
275
|
|
|
320
276
|
return {
|
|
@@ -352,10 +308,10 @@ function buildBuilderPath(login, projectRoot, manifest, env = process.env, runti
|
|
|
352
308
|
skip_help_discovery_default: true,
|
|
353
309
|
skip_env_noise_default: true,
|
|
354
310
|
skip_login_check_only_default: canTrustSummaryPreflight,
|
|
355
|
-
skip_browser_login_default: auth.
|
|
311
|
+
skip_browser_login_default: !auth.interactive_login_allowed,
|
|
356
312
|
skip_cookie_or_playwright_checks_default: true,
|
|
357
313
|
default_app_list_policy: 'skip_when_bound_app_type_unique',
|
|
358
|
-
|
|
314
|
+
stop_when_env_token_missing: auth.missing_token_action === 'STOP_AND_REQUEST_ENV_TOKEN' && !auth.can_auto_use,
|
|
359
315
|
},
|
|
360
316
|
command_contract: {
|
|
361
317
|
command_prefix: manifest.command_prefix,
|
|
@@ -437,9 +393,6 @@ function compactBuilderPath(builderPath) {
|
|
|
437
393
|
next_step: builderPath.auth.next_step,
|
|
438
394
|
next_step_commands: builderPath.auth.next_step_commands,
|
|
439
395
|
can_auto_use: builderPath.auth.can_auto_use,
|
|
440
|
-
host_injected_token_mode: builderPath.auth.host_injected_token_mode,
|
|
441
|
-
host_token_env_detected: builderPath.auth.host_token_env_detected,
|
|
442
|
-
env_token_present: builderPath.auth.env_token_present,
|
|
443
396
|
interactive_login_allowed: builderPath.auth.interactive_login_allowed,
|
|
444
397
|
browser_session_auth_allowed: builderPath.auth.browser_session_auth_allowed,
|
|
445
398
|
auth_runtime: builderPath.auth.auth_runtime,
|
|
@@ -449,10 +402,6 @@ function compactBuilderPath(builderPath) {
|
|
|
449
402
|
qr_login_required: builderPath.auth.qr_login_required,
|
|
450
403
|
missing_token_action: builderPath.auth.missing_token_action,
|
|
451
404
|
};
|
|
452
|
-
if (builderPath.auth.runtime_auth_provisioned === true) {
|
|
453
|
-
auth.runtime_auth_provisioned = true;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
405
|
return {
|
|
457
406
|
schema_version: builderPath.schema_version,
|
|
458
407
|
preflight: builderPath.preflight,
|
|
@@ -465,7 +414,7 @@ function compactBuilderPath(builderPath) {
|
|
|
465
414
|
skip_login_check_only_default: environment.skip_login_check_only_default,
|
|
466
415
|
skip_browser_login_default: environment.skip_browser_login_default,
|
|
467
416
|
skip_cookie_or_playwright_checks_default: environment.skip_cookie_or_playwright_checks_default,
|
|
468
|
-
|
|
417
|
+
stop_when_env_token_missing: environment.stop_when_env_token_missing,
|
|
469
418
|
default_app_list_policy: environment.default_app_list_policy,
|
|
470
419
|
},
|
|
471
420
|
command_contract: {
|
|
@@ -541,43 +490,6 @@ function buildCommandManifestDigest(manifest) {
|
|
|
541
490
|
|
|
542
491
|
function buildAgentCapabilitiesSummary() {
|
|
543
492
|
const manifest = buildCommandManifest({ t, version });
|
|
544
|
-
|
|
545
|
-
if (hasRuntimeProvisionedAccessToken(process.env)) {
|
|
546
|
-
const projectResolution = resolveProjectRootCompat();
|
|
547
|
-
const projectRoot = projectResolution.projectRoot;
|
|
548
|
-
const skillsDiagnostics = compactSkillsDiagnostics(buildSkillsDiagnosticsCompat(projectResolution));
|
|
549
|
-
const loginStatus = buildRuntimeProvisionedLoginStatus();
|
|
550
|
-
const runtime = buildRuntimeSnapshot(projectRoot);
|
|
551
|
-
const builderPath = compactBuilderPath(
|
|
552
|
-
buildBuilderPath(loginStatus, projectRoot, manifest, process.env, runtime)
|
|
553
|
-
);
|
|
554
|
-
|
|
555
|
-
return {
|
|
556
|
-
schema_version: 1,
|
|
557
|
-
name: 'openyida-agent-capabilities-summary',
|
|
558
|
-
version,
|
|
559
|
-
login: compactLogin(loginStatus),
|
|
560
|
-
precheck: {
|
|
561
|
-
skipped: true,
|
|
562
|
-
reason: 'runtime_auth_provisioned',
|
|
563
|
-
},
|
|
564
|
-
workdir: projectRoot,
|
|
565
|
-
workdir_exists: fs.existsSync(projectRoot),
|
|
566
|
-
workdir_source: projectResolution.source,
|
|
567
|
-
workdir_reason: projectResolution.reason,
|
|
568
|
-
project_root: compactProjectRootResolution(projectResolution),
|
|
569
|
-
cache_dir: path.join(projectRoot, '.cache'),
|
|
570
|
-
openyida_task_cache_dir: path.join(projectRoot, '.cache', 'openyida'),
|
|
571
|
-
skills: skillsDiagnostics,
|
|
572
|
-
command_manifest_digest: buildCommandManifestDigest(manifest),
|
|
573
|
-
command_manifest_digest_algorithm: 'sha256',
|
|
574
|
-
command_count: manifest.summary.command_count,
|
|
575
|
-
full_capabilities_command: 'openyida agent-capabilities --json',
|
|
576
|
-
runtime,
|
|
577
|
-
builder_path: builderPath,
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
|
|
581
493
|
const envSnapshot = buildEnvironmentSnapshot();
|
|
582
494
|
const projectResolution = resolveProjectRootCompat({
|
|
583
495
|
projectRoot: envSnapshot.active.projectRoot,
|