@moda-ai/cli 1.17.0 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/profile-commands.js +13 -1
- package/dist/profiles.d.ts +14 -0
- package/dist/profiles.js +39 -1
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
package/dist/profile-commands.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { authFetch, clearAuthSession, isAuthSessionValid, loadAuthSession, login, revokeCliSessionToken, } from './auth.js';
|
|
2
2
|
import { EXIT_AUTH_REQUIRED, EXIT_OK } from './output.js';
|
|
3
3
|
import { KEY_LIFECYCLE_ENDPOINT_REQUIREMENTS, createLocalKeyDescriptor, loadLocalKeyDescriptors, upsertLocalKeyDescriptor, writeLocalApiKeySecret, } from './keys.js';
|
|
4
|
-
import { DEFAULT_INGEST_URL, PROD_BASE_URL, ensureSecretFilePermissions, getActiveProfile, getModaPaths, loadProfileConfig, resolveApiKeyFromActiveProfile, resolveSecretReference, secretFilePathFromRef, setActiveProfile, upsertProfile, } from './profiles.js';
|
|
4
|
+
import { DEFAULT_INGEST_URL, PROD_BASE_URL, clearStoredApiKeyCredentials, ensureSecretFilePermissions, getActiveProfile, getModaPaths, loadProfileConfig, resolveApiKeyFromActiveProfile, resolveSecretReference, secretFilePathFromRef, setActiveProfile, upsertProfile, } from './profiles.js';
|
|
5
5
|
import { CliInputError } from './errors.js';
|
|
6
6
|
// Bound the `auth status --online` probe: without a signal, undici's defaults
|
|
7
7
|
// can stall a status check for minutes on a black-holed connection.
|
|
@@ -77,9 +77,21 @@ export async function runAuthCommand(context) {
|
|
|
77
77
|
// auth0-kind sessions have nothing to revoke.
|
|
78
78
|
await revokeCliSessionToken({ profile: context.profile, env: context.env });
|
|
79
79
|
clearAuthSession({ profile: context.profile, env: context.env });
|
|
80
|
+
// The session token is only the control-plane credential. Data commands
|
|
81
|
+
// authenticate with the moda_sk_ API key written by `moda init`
|
|
82
|
+
// (~/.moda/config.json + profile api_key_ref), so logout must clear it
|
|
83
|
+
// too or the next login keeps acting as the old tenant.
|
|
84
|
+
const apiKeyCleared = clearStoredApiKeyCredentials({
|
|
85
|
+
profile: context.profile,
|
|
86
|
+
env: context.env,
|
|
87
|
+
});
|
|
88
|
+
if (context.env.MODA_API_KEY) {
|
|
89
|
+
console.error('Note: MODA_API_KEY is set in the environment and still takes precedence. Unset it to fully sign out.');
|
|
90
|
+
}
|
|
80
91
|
context.output.writeData({
|
|
81
92
|
status: 'logged_out',
|
|
82
93
|
profile: context.profile ?? process.env.MODA_PROFILE ?? null,
|
|
94
|
+
api_key_cleared: apiKeyCleared,
|
|
83
95
|
});
|
|
84
96
|
return { exitCode: 0 };
|
|
85
97
|
}
|
package/dist/profiles.d.ts
CHANGED
|
@@ -80,6 +80,20 @@ export declare function getActiveProfile(options?: ProfileIOOptions): ModaProfil
|
|
|
80
80
|
export declare function setActiveProfile(name: string, options?: ProfileIOOptions): ProfileConfig;
|
|
81
81
|
export declare function upsertProfile(profile: ModaProfile, options?: ProfileIOOptions): ProfileConfig;
|
|
82
82
|
export declare function syncLegacyConfigToProfile(legacy: LegacyCliConfig, options?: ProfileIOOptions): ProfileConfig;
|
|
83
|
+
/**
|
|
84
|
+
* Forget the stored data-plane credentials (`moda_sk_` API key + tenant
|
|
85
|
+
* binding written by `moda init`): the legacy config's api_key/tenant_id and
|
|
86
|
+
* the target profile's api_key_ref/tenant_id, deleting `file:` key secrets
|
|
87
|
+
* under ~/.moda. Called by `moda auth logout` — without this, analytics
|
|
88
|
+
* commands keep authenticating as the old tenant after a re-login, because
|
|
89
|
+
* they use the x-api-key plane, not the session token. MODA_API_KEY in the
|
|
90
|
+
* environment still wins at resolve time.
|
|
91
|
+
*
|
|
92
|
+
* The legacy config must be cleared BEFORE reading the profile config:
|
|
93
|
+
* applyLegacyAwareness re-derives api_key_ref onto the prod profile on every
|
|
94
|
+
* load while config.json still holds an api_key.
|
|
95
|
+
*/
|
|
96
|
+
export declare function clearStoredApiKeyCredentials(options?: ProfileIOOptions): boolean;
|
|
83
97
|
export declare function secretFilePathFromRef(reference: SecretReference, options?: ProfileIOOptions): string | undefined;
|
|
84
98
|
export declare function resolveSecretReference(reference: SecretReference | undefined, options?: ProfileIOOptions): string | undefined;
|
|
85
99
|
export declare function resolveApiKeyFromActiveProfile(options?: ProfileIOOptions): string | undefined;
|
package/dist/profiles.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync, } from 'node:fs';
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { dirname, isAbsolute, join, normalize, relative } from 'node:path';
|
|
4
4
|
export const PROFILE_CONFIG_VERSION = 1;
|
|
@@ -347,6 +347,44 @@ export function syncLegacyConfigToProfile(legacy, options = {}) {
|
|
|
347
347
|
},
|
|
348
348
|
}, options);
|
|
349
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Forget the stored data-plane credentials (`moda_sk_` API key + tenant
|
|
352
|
+
* binding written by `moda init`): the legacy config's api_key/tenant_id and
|
|
353
|
+
* the target profile's api_key_ref/tenant_id, deleting `file:` key secrets
|
|
354
|
+
* under ~/.moda. Called by `moda auth logout` — without this, analytics
|
|
355
|
+
* commands keep authenticating as the old tenant after a re-login, because
|
|
356
|
+
* they use the x-api-key plane, not the session token. MODA_API_KEY in the
|
|
357
|
+
* environment still wins at resolve time.
|
|
358
|
+
*
|
|
359
|
+
* The legacy config must be cleared BEFORE reading the profile config:
|
|
360
|
+
* applyLegacyAwareness re-derives api_key_ref onto the prod profile on every
|
|
361
|
+
* load while config.json still holds an api_key.
|
|
362
|
+
*/
|
|
363
|
+
export function clearStoredApiKeyCredentials(options = {}) {
|
|
364
|
+
let cleared = false;
|
|
365
|
+
const paths = getModaPaths(options);
|
|
366
|
+
const legacy = loadLegacyCliConfig(options);
|
|
367
|
+
if (legacy.api_key || legacy.tenant_id) {
|
|
368
|
+
writeSecretJsonFile(paths.legacyConfigPath, legacy.ingest_url ? { ingest_url: legacy.ingest_url } : {});
|
|
369
|
+
cleared = true;
|
|
370
|
+
}
|
|
371
|
+
const config = loadProfileConfig(options);
|
|
372
|
+
const profileName = options.profile ||
|
|
373
|
+
optionalString(getEnv(options).MODA_PROFILE) ||
|
|
374
|
+
config.active_profile;
|
|
375
|
+
const profile = config.profiles[profileName];
|
|
376
|
+
if (profile && (profile.api_key_ref || profile.tenant_id)) {
|
|
377
|
+
if (profile.api_key_ref?.startsWith('file:')) {
|
|
378
|
+
const secretPath = resolveFileSecretPath(profile.api_key_ref, options);
|
|
379
|
+
if (secretPath)
|
|
380
|
+
rmSync(secretPath, { force: true });
|
|
381
|
+
}
|
|
382
|
+
const { api_key_ref: _key, tenant_id: _tenant, ...rest } = profile;
|
|
383
|
+
saveProfileConfig({ ...config, profiles: { ...config.profiles, [profileName]: rest } }, options);
|
|
384
|
+
cleared = true;
|
|
385
|
+
}
|
|
386
|
+
return cleared;
|
|
387
|
+
}
|
|
350
388
|
function resolveFileSecretPath(reference, options) {
|
|
351
389
|
if (!reference.startsWith('file:'))
|
|
352
390
|
return undefined;
|
package/package.json
CHANGED