opensteer 0.6.1 → 0.6.2
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/README.md +4 -5
- package/bin/opensteer.mjs +0 -1
- package/dist/{chunk-3FNI7JUU.js → chunk-7RMY26CM.js} +82 -187
- package/dist/cli/auth.cjs +82 -187
- package/dist/cli/auth.d.cts +0 -6
- package/dist/cli/auth.d.ts +0 -6
- package/dist/cli/auth.js +1 -1
- package/dist/cli/profile.cjs +59 -155
- package/dist/cli/profile.d.cts +0 -2
- package/dist/cli/profile.d.ts +0 -2
- package/dist/cli/profile.js +1 -25
- package/package.json +1 -1
package/dist/cli/auth.cjs
CHANGED
|
@@ -804,13 +804,10 @@ function createKeychainStore() {
|
|
|
804
804
|
}
|
|
805
805
|
|
|
806
806
|
// src/auth/machine-credential-store.ts
|
|
807
|
-
var METADATA_VERSION =
|
|
808
|
-
var ACTIVE_TARGET_VERSION =
|
|
807
|
+
var METADATA_VERSION = 2;
|
|
808
|
+
var ACTIVE_TARGET_VERSION = 2;
|
|
809
809
|
var KEYCHAIN_SERVICE = "com.opensteer.cli.cloud";
|
|
810
810
|
var KEYCHAIN_ACCOUNT_PREFIX = "machine:";
|
|
811
|
-
var LEGACY_KEYCHAIN_ACCOUNT = "machine";
|
|
812
|
-
var LEGACY_METADATA_FILE_NAME = "cli-login.json";
|
|
813
|
-
var LEGACY_FALLBACK_SECRET_FILE_NAME = "cli-login.secret.json";
|
|
814
811
|
var ACTIVE_TARGET_FILE_NAME = "cli-target.json";
|
|
815
812
|
var MachineCredentialStore = class {
|
|
816
813
|
authDir;
|
|
@@ -825,8 +822,11 @@ var MachineCredentialStore = class {
|
|
|
825
822
|
this.warn = options.warn ?? (() => void 0);
|
|
826
823
|
}
|
|
827
824
|
readCloudCredential(target) {
|
|
828
|
-
const
|
|
829
|
-
return this.readCredentialSlot(
|
|
825
|
+
const normalizedTarget = normalizeCloudCredentialTarget(target);
|
|
826
|
+
return this.readCredentialSlot(
|
|
827
|
+
resolveCredentialSlot(this.authDir, normalizedTarget),
|
|
828
|
+
normalizedTarget
|
|
829
|
+
);
|
|
830
830
|
}
|
|
831
831
|
writeCloudCredential(args) {
|
|
832
832
|
const accessToken = args.accessToken.trim();
|
|
@@ -834,12 +834,8 @@ var MachineCredentialStore = class {
|
|
|
834
834
|
if (!accessToken || !refreshToken2) {
|
|
835
835
|
throw new Error("Cannot persist empty machine credential secrets.");
|
|
836
836
|
}
|
|
837
|
-
const baseUrl = normalizeCredentialUrl(args.baseUrl
|
|
838
|
-
const
|
|
839
|
-
const slot = resolveCredentialSlot(this.authDir, {
|
|
840
|
-
baseUrl,
|
|
841
|
-
siteUrl
|
|
842
|
-
});
|
|
837
|
+
const baseUrl = normalizeCredentialUrl(args.baseUrl);
|
|
838
|
+
const slot = resolveCredentialSlot(this.authDir, { baseUrl });
|
|
843
839
|
ensureDirectory(this.authDir);
|
|
844
840
|
const secretPayload = {
|
|
845
841
|
accessToken,
|
|
@@ -866,7 +862,6 @@ var MachineCredentialStore = class {
|
|
|
866
862
|
version: METADATA_VERSION,
|
|
867
863
|
secretBackend,
|
|
868
864
|
baseUrl,
|
|
869
|
-
siteUrl,
|
|
870
865
|
scope: args.scope,
|
|
871
866
|
obtainedAt: args.obtainedAt,
|
|
872
867
|
expiresAt: args.expiresAt,
|
|
@@ -878,23 +873,18 @@ var MachineCredentialStore = class {
|
|
|
878
873
|
return readActiveCloudTargetMetadata(resolveActiveTargetPath(this.authDir));
|
|
879
874
|
}
|
|
880
875
|
writeActiveCloudTarget(target) {
|
|
881
|
-
const baseUrl = normalizeCredentialUrl(target.baseUrl
|
|
882
|
-
const siteUrl = normalizeCredentialUrl(target.siteUrl, "siteUrl");
|
|
876
|
+
const baseUrl = normalizeCredentialUrl(target.baseUrl);
|
|
883
877
|
ensureDirectory(this.authDir);
|
|
884
878
|
writeJsonFile(resolveActiveTargetPath(this.authDir), {
|
|
885
879
|
version: ACTIVE_TARGET_VERSION,
|
|
886
880
|
baseUrl,
|
|
887
|
-
siteUrl,
|
|
888
881
|
updatedAt: Date.now()
|
|
889
882
|
});
|
|
890
883
|
}
|
|
891
884
|
clearCloudCredential(target) {
|
|
892
|
-
this.clearCredentialSlot(
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
if (legacyMetadata && matchesCredentialTarget(legacyMetadata, target)) {
|
|
896
|
-
this.clearCredentialSlot(legacySlot);
|
|
897
|
-
}
|
|
885
|
+
this.clearCredentialSlot(
|
|
886
|
+
resolveCredentialSlot(this.authDir, normalizeCloudCredentialTarget(target))
|
|
887
|
+
);
|
|
898
888
|
}
|
|
899
889
|
readCredentialSlot(slot, target) {
|
|
900
890
|
const metadata = readMetadata(slot.metadataPath);
|
|
@@ -910,7 +900,6 @@ var MachineCredentialStore = class {
|
|
|
910
900
|
}
|
|
911
901
|
return {
|
|
912
902
|
baseUrl: metadata.baseUrl,
|
|
913
|
-
siteUrl: metadata.siteUrl,
|
|
914
903
|
scope: metadata.scope,
|
|
915
904
|
accessToken: secret.accessToken,
|
|
916
905
|
refreshToken: secret.refreshToken,
|
|
@@ -918,16 +907,6 @@ var MachineCredentialStore = class {
|
|
|
918
907
|
expiresAt: metadata.expiresAt
|
|
919
908
|
};
|
|
920
909
|
}
|
|
921
|
-
readAndMigrateLegacyCredential(target) {
|
|
922
|
-
const legacySlot = resolveLegacyCredentialSlot(this.authDir);
|
|
923
|
-
const legacyCredential = this.readCredentialSlot(legacySlot, target);
|
|
924
|
-
if (!legacyCredential) {
|
|
925
|
-
return null;
|
|
926
|
-
}
|
|
927
|
-
this.writeCloudCredential(legacyCredential);
|
|
928
|
-
this.clearCredentialSlot(legacySlot);
|
|
929
|
-
return legacyCredential;
|
|
930
|
-
}
|
|
931
910
|
readSecret(slot, backend) {
|
|
932
911
|
if (backend === "keychain" && this.keychain) {
|
|
933
912
|
try {
|
|
@@ -968,9 +947,8 @@ function createMachineCredentialStore(options = {}) {
|
|
|
968
947
|
return new MachineCredentialStore(options);
|
|
969
948
|
}
|
|
970
949
|
function resolveCredentialSlot(authDir, target) {
|
|
971
|
-
const normalizedBaseUrl = normalizeCredentialUrl(target.baseUrl
|
|
972
|
-
const
|
|
973
|
-
const storageKey = (0, import_node_crypto.createHash)("sha256").update(`${normalizedBaseUrl}\0${normalizedSiteUrl}`).digest("hex").slice(0, 24);
|
|
950
|
+
const normalizedBaseUrl = normalizeCredentialUrl(target.baseUrl);
|
|
951
|
+
const storageKey = (0, import_node_crypto.createHash)("sha256").update(normalizedBaseUrl).digest("hex").slice(0, 24);
|
|
974
952
|
return {
|
|
975
953
|
keychainAccount: `${KEYCHAIN_ACCOUNT_PREFIX}${storageKey}`,
|
|
976
954
|
metadataPath: import_node_path.default.join(authDir, `cli-login.${storageKey}.json`),
|
|
@@ -980,26 +958,24 @@ function resolveCredentialSlot(authDir, target) {
|
|
|
980
958
|
)
|
|
981
959
|
};
|
|
982
960
|
}
|
|
983
|
-
function resolveLegacyCredentialSlot(authDir) {
|
|
984
|
-
return {
|
|
985
|
-
keychainAccount: LEGACY_KEYCHAIN_ACCOUNT,
|
|
986
|
-
metadataPath: import_node_path.default.join(authDir, LEGACY_METADATA_FILE_NAME),
|
|
987
|
-
fallbackSecretPath: import_node_path.default.join(authDir, LEGACY_FALLBACK_SECRET_FILE_NAME)
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
961
|
function resolveActiveTargetPath(authDir) {
|
|
991
962
|
return import_node_path.default.join(authDir, ACTIVE_TARGET_FILE_NAME);
|
|
992
963
|
}
|
|
993
964
|
function matchesCredentialTarget(value, target) {
|
|
994
|
-
return normalizeCredentialUrl(value.baseUrl
|
|
965
|
+
return normalizeCredentialUrl(value.baseUrl) === normalizeCredentialUrl(target.baseUrl);
|
|
995
966
|
}
|
|
996
|
-
function normalizeCredentialUrl(value
|
|
967
|
+
function normalizeCredentialUrl(value) {
|
|
997
968
|
const normalized = stripTrailingSlashes(value.trim());
|
|
998
969
|
if (!normalized) {
|
|
999
|
-
throw new Error(
|
|
970
|
+
throw new Error("Cannot persist machine credential without baseUrl.");
|
|
1000
971
|
}
|
|
1001
972
|
return normalized;
|
|
1002
973
|
}
|
|
974
|
+
function normalizeCloudCredentialTarget(target) {
|
|
975
|
+
return {
|
|
976
|
+
baseUrl: normalizeCredentialUrl(target.baseUrl)
|
|
977
|
+
};
|
|
978
|
+
}
|
|
1003
979
|
function resolveConfigDir(appName, env) {
|
|
1004
980
|
if (process.platform === "win32") {
|
|
1005
981
|
const appData = env.APPDATA?.trim() || import_node_path.default.join(import_node_os.default.homedir(), "AppData", "Roaming");
|
|
@@ -1038,7 +1014,6 @@ function readMetadata(filePath) {
|
|
|
1038
1014
|
return null;
|
|
1039
1015
|
}
|
|
1040
1016
|
if (typeof parsed.baseUrl !== "string" || !parsed.baseUrl.trim()) return null;
|
|
1041
|
-
if (typeof parsed.siteUrl !== "string" || !parsed.siteUrl.trim()) return null;
|
|
1042
1017
|
if (!Array.isArray(parsed.scope)) return null;
|
|
1043
1018
|
if (typeof parsed.obtainedAt !== "number") return null;
|
|
1044
1019
|
if (typeof parsed.expiresAt !== "number") return null;
|
|
@@ -1047,7 +1022,6 @@ function readMetadata(filePath) {
|
|
|
1047
1022
|
version: parsed.version,
|
|
1048
1023
|
secretBackend: parsed.secretBackend,
|
|
1049
1024
|
baseUrl: parsed.baseUrl,
|
|
1050
|
-
siteUrl: parsed.siteUrl,
|
|
1051
1025
|
scope: parsed.scope.filter(
|
|
1052
1026
|
(value) => typeof value === "string"
|
|
1053
1027
|
),
|
|
@@ -1072,12 +1046,8 @@ function readActiveCloudTargetMetadata(filePath) {
|
|
|
1072
1046
|
if (typeof parsed.baseUrl !== "string" || !parsed.baseUrl.trim()) {
|
|
1073
1047
|
return null;
|
|
1074
1048
|
}
|
|
1075
|
-
if (typeof parsed.siteUrl !== "string" || !parsed.siteUrl.trim()) {
|
|
1076
|
-
return null;
|
|
1077
|
-
}
|
|
1078
1049
|
return {
|
|
1079
|
-
baseUrl: parsed.baseUrl
|
|
1080
|
-
siteUrl: parsed.siteUrl
|
|
1050
|
+
baseUrl: parsed.baseUrl
|
|
1081
1051
|
};
|
|
1082
1052
|
} catch {
|
|
1083
1053
|
return null;
|
|
@@ -1102,14 +1072,13 @@ function readSecretFile(filePath) {
|
|
|
1102
1072
|
return null;
|
|
1103
1073
|
}
|
|
1104
1074
|
try {
|
|
1105
|
-
|
|
1106
|
-
return parseSecretPayload(raw);
|
|
1075
|
+
return parseSecretPayload(import_node_fs.default.readFileSync(filePath, "utf8"));
|
|
1107
1076
|
} catch {
|
|
1108
1077
|
return null;
|
|
1109
1078
|
}
|
|
1110
1079
|
}
|
|
1111
|
-
function writeJsonFile(filePath,
|
|
1112
|
-
import_node_fs.default.writeFileSync(filePath, JSON.stringify(
|
|
1080
|
+
function writeJsonFile(filePath, value, options = {}) {
|
|
1081
|
+
import_node_fs.default.writeFileSync(filePath, JSON.stringify(value, null, 2), {
|
|
1113
1082
|
encoding: "utf8",
|
|
1114
1083
|
mode: options.mode ?? 384
|
|
1115
1084
|
});
|
|
@@ -1140,11 +1109,12 @@ Commands:
|
|
|
1140
1109
|
|
|
1141
1110
|
Options:
|
|
1142
1111
|
--base-url <url> Cloud API base URL (defaults to env or the last selected host)
|
|
1143
|
-
--site-url <url> Cloud site URL for browser/device auth (defaults to env or the last selected host)
|
|
1144
1112
|
--json JSON output (login prompts go to stderr)
|
|
1145
1113
|
--no-browser Do not auto-open your default browser during login
|
|
1146
1114
|
-h, --help Show this help
|
|
1147
1115
|
`;
|
|
1116
|
+
var DEFAULT_AUTH_SITE_URL = "https://opensteer.com";
|
|
1117
|
+
var INTERNAL_AUTH_SITE_URL_ENV = "OPENSTEER_INTERNAL_AUTH_SITE_URL";
|
|
1148
1118
|
function createDefaultDeps() {
|
|
1149
1119
|
const env = process.env;
|
|
1150
1120
|
return {
|
|
@@ -1196,13 +1166,6 @@ function parseAuthCommonArgs(rawArgs) {
|
|
|
1196
1166
|
i = value.nextIndex;
|
|
1197
1167
|
continue;
|
|
1198
1168
|
}
|
|
1199
|
-
if (arg === "--site-url") {
|
|
1200
|
-
const value = readFlagValue(rawArgs, i, "--site-url");
|
|
1201
|
-
if (!value.ok) return { args, error: value.error };
|
|
1202
|
-
args.siteUrl = value.value;
|
|
1203
|
-
i = value.nextIndex;
|
|
1204
|
-
continue;
|
|
1205
|
-
}
|
|
1206
1169
|
return {
|
|
1207
1170
|
args,
|
|
1208
1171
|
error: `Unsupported option "${arg}".`
|
|
@@ -1272,16 +1235,19 @@ function resolveBaseUrl(provided, env) {
|
|
|
1272
1235
|
assertSecureUrl(baseUrl, "--base-url");
|
|
1273
1236
|
return baseUrl;
|
|
1274
1237
|
}
|
|
1275
|
-
function
|
|
1276
|
-
const
|
|
1277
|
-
(
|
|
1238
|
+
function resolveAuthSiteUrl(env) {
|
|
1239
|
+
const authSiteUrl = normalizeCloudBaseUrl(
|
|
1240
|
+
(env[INTERNAL_AUTH_SITE_URL_ENV] || DEFAULT_AUTH_SITE_URL).trim()
|
|
1241
|
+
);
|
|
1242
|
+
assertSecureUrl(
|
|
1243
|
+
authSiteUrl,
|
|
1244
|
+
`environment variable ${INTERNAL_AUTH_SITE_URL_ENV}`
|
|
1278
1245
|
);
|
|
1279
|
-
|
|
1280
|
-
return siteUrl;
|
|
1246
|
+
return authSiteUrl;
|
|
1281
1247
|
}
|
|
1282
|
-
function hasExplicitCloudTargetSelection(providedBaseUrl,
|
|
1248
|
+
function hasExplicitCloudTargetSelection(providedBaseUrl, env) {
|
|
1283
1249
|
return Boolean(
|
|
1284
|
-
providedBaseUrl?.trim() ||
|
|
1250
|
+
providedBaseUrl?.trim() || env.OPENSTEER_BASE_URL?.trim()
|
|
1285
1251
|
);
|
|
1286
1252
|
}
|
|
1287
1253
|
function readRememberedCloudTarget(store) {
|
|
@@ -1291,57 +1257,21 @@ function readRememberedCloudTarget(store) {
|
|
|
1291
1257
|
}
|
|
1292
1258
|
try {
|
|
1293
1259
|
const baseUrl = normalizeCloudBaseUrl(activeTarget.baseUrl);
|
|
1294
|
-
const siteUrl = normalizeCloudBaseUrl(activeTarget.siteUrl);
|
|
1295
1260
|
assertSecureUrl(baseUrl, "--base-url");
|
|
1296
|
-
|
|
1297
|
-
return {
|
|
1298
|
-
baseUrl,
|
|
1299
|
-
siteUrl
|
|
1300
|
-
};
|
|
1261
|
+
return { baseUrl };
|
|
1301
1262
|
} catch {
|
|
1302
1263
|
return null;
|
|
1303
1264
|
}
|
|
1304
1265
|
}
|
|
1305
|
-
function resolveCloudTarget(args, env, store) {
|
|
1306
|
-
if (!hasExplicitCloudTargetSelection(args.baseUrl,
|
|
1266
|
+
function resolveCloudTarget(args, env, store, options = {}) {
|
|
1267
|
+
if (options.allowRememberedTarget !== false && !hasExplicitCloudTargetSelection(args.baseUrl, env)) {
|
|
1307
1268
|
const rememberedTarget = readRememberedCloudTarget(store);
|
|
1308
1269
|
if (rememberedTarget) {
|
|
1309
1270
|
return rememberedTarget;
|
|
1310
1271
|
}
|
|
1311
1272
|
}
|
|
1312
1273
|
const baseUrl = resolveBaseUrl(args.baseUrl, env);
|
|
1313
|
-
|
|
1314
|
-
return {
|
|
1315
|
-
baseUrl,
|
|
1316
|
-
siteUrl
|
|
1317
|
-
};
|
|
1318
|
-
}
|
|
1319
|
-
function deriveSiteUrlFromBaseUrl(baseUrl) {
|
|
1320
|
-
let parsed;
|
|
1321
|
-
try {
|
|
1322
|
-
parsed = new URL(baseUrl);
|
|
1323
|
-
} catch {
|
|
1324
|
-
return "https://opensteer.com";
|
|
1325
|
-
}
|
|
1326
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
1327
|
-
if (hostname.startsWith("api.")) {
|
|
1328
|
-
parsed.hostname = hostname.slice("api.".length);
|
|
1329
|
-
parsed.pathname = "";
|
|
1330
|
-
parsed.search = "";
|
|
1331
|
-
parsed.hash = "";
|
|
1332
|
-
return normalizeCloudBaseUrl(parsed.toString());
|
|
1333
|
-
}
|
|
1334
|
-
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1") {
|
|
1335
|
-
parsed.port = "3001";
|
|
1336
|
-
parsed.pathname = "";
|
|
1337
|
-
parsed.search = "";
|
|
1338
|
-
parsed.hash = "";
|
|
1339
|
-
return normalizeCloudBaseUrl(parsed.toString());
|
|
1340
|
-
}
|
|
1341
|
-
parsed.pathname = "";
|
|
1342
|
-
parsed.search = "";
|
|
1343
|
-
parsed.hash = "";
|
|
1344
|
-
return normalizeCloudBaseUrl(parsed.toString());
|
|
1274
|
+
return { baseUrl };
|
|
1345
1275
|
}
|
|
1346
1276
|
function assertSecureUrl(value, flag) {
|
|
1347
1277
|
let parsed;
|
|
@@ -1416,10 +1346,10 @@ function parseCliOauthError(error) {
|
|
|
1416
1346
|
interval: typeof root.interval === "number" ? root.interval : void 0
|
|
1417
1347
|
};
|
|
1418
1348
|
}
|
|
1419
|
-
async function startDeviceAuthorization(
|
|
1349
|
+
async function startDeviceAuthorization(authSiteUrl, fetchFn) {
|
|
1420
1350
|
const response = await postJson(
|
|
1421
1351
|
fetchFn,
|
|
1422
|
-
`${
|
|
1352
|
+
`${authSiteUrl}/api/cli-auth/device/start`,
|
|
1423
1353
|
{
|
|
1424
1354
|
scope: ["cloud:browser"]
|
|
1425
1355
|
}
|
|
@@ -1429,24 +1359,24 @@ async function startDeviceAuthorization(siteUrl, fetchFn) {
|
|
|
1429
1359
|
}
|
|
1430
1360
|
return response;
|
|
1431
1361
|
}
|
|
1432
|
-
async function pollDeviceToken(
|
|
1362
|
+
async function pollDeviceToken(authSiteUrl, deviceCode, fetchFn) {
|
|
1433
1363
|
return await postJson(
|
|
1434
1364
|
fetchFn,
|
|
1435
|
-
`${
|
|
1365
|
+
`${authSiteUrl}/api/cli-auth/device/token`,
|
|
1436
1366
|
{
|
|
1437
1367
|
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
1438
1368
|
device_code: deviceCode
|
|
1439
1369
|
}
|
|
1440
1370
|
);
|
|
1441
1371
|
}
|
|
1442
|
-
async function refreshToken(
|
|
1443
|
-
return await postJson(fetchFn, `${
|
|
1372
|
+
async function refreshToken(authSiteUrl, refreshTokenValue, fetchFn) {
|
|
1373
|
+
return await postJson(fetchFn, `${authSiteUrl}/api/cli-auth/token`, {
|
|
1444
1374
|
grant_type: "refresh_token",
|
|
1445
1375
|
refresh_token: refreshTokenValue
|
|
1446
1376
|
});
|
|
1447
1377
|
}
|
|
1448
|
-
async function revokeToken(
|
|
1449
|
-
await postJson(fetchFn, `${
|
|
1378
|
+
async function revokeToken(authSiteUrl, refreshTokenValue, fetchFn) {
|
|
1379
|
+
await postJson(fetchFn, `${authSiteUrl}/api/cli-auth/revoke`, {
|
|
1450
1380
|
token: refreshTokenValue
|
|
1451
1381
|
});
|
|
1452
1382
|
}
|
|
@@ -1463,7 +1393,7 @@ async function openDefaultBrowser(url) {
|
|
|
1463
1393
|
}
|
|
1464
1394
|
}
|
|
1465
1395
|
async function runDeviceLoginFlow(args) {
|
|
1466
|
-
const start = await startDeviceAuthorization(args.
|
|
1396
|
+
const start = await startDeviceAuthorization(args.authSiteUrl, args.fetchFn);
|
|
1467
1397
|
if (args.openBrowser) {
|
|
1468
1398
|
args.writeProgress(
|
|
1469
1399
|
"Opening your default browser for Opensteer CLI authentication.\n"
|
|
@@ -1508,7 +1438,7 @@ ${start.verification_uri_complete}
|
|
|
1508
1438
|
await args.sleep(pollIntervalMs);
|
|
1509
1439
|
try {
|
|
1510
1440
|
const tokenPayload = await pollDeviceToken(
|
|
1511
|
-
args.
|
|
1441
|
+
args.authSiteUrl,
|
|
1512
1442
|
start.device_code,
|
|
1513
1443
|
args.fetchFn
|
|
1514
1444
|
);
|
|
@@ -1556,7 +1486,7 @@ ${start.verification_uri_complete}
|
|
|
1556
1486
|
}
|
|
1557
1487
|
async function refreshSavedCredential(saved, deps) {
|
|
1558
1488
|
const tokenPayload = await refreshToken(
|
|
1559
|
-
|
|
1489
|
+
resolveAuthSiteUrl(deps.env),
|
|
1560
1490
|
saved.refreshToken,
|
|
1561
1491
|
deps.fetchFn
|
|
1562
1492
|
);
|
|
@@ -1569,7 +1499,6 @@ async function refreshSavedCredential(saved, deps) {
|
|
|
1569
1499
|
};
|
|
1570
1500
|
deps.store.writeCloudCredential({
|
|
1571
1501
|
baseUrl: saved.baseUrl,
|
|
1572
|
-
siteUrl: saved.siteUrl,
|
|
1573
1502
|
scope: updated.scope,
|
|
1574
1503
|
accessToken: updated.accessToken,
|
|
1575
1504
|
refreshToken: updated.refreshToken,
|
|
@@ -1598,8 +1527,7 @@ async function ensureSavedCredentialIsFresh(saved, deps) {
|
|
|
1598
1527
|
const oauth = parseCliOauthError(error.body);
|
|
1599
1528
|
if (oauth?.error === "invalid_grant" || oauth?.error === "expired_token") {
|
|
1600
1529
|
deps.store.clearCloudCredential({
|
|
1601
|
-
baseUrl: saved.baseUrl
|
|
1602
|
-
siteUrl: saved.siteUrl
|
|
1530
|
+
baseUrl: saved.baseUrl
|
|
1603
1531
|
});
|
|
1604
1532
|
return null;
|
|
1605
1533
|
}
|
|
@@ -1699,7 +1627,7 @@ async function ensureCloudCredentialsForCommand(options) {
|
|
|
1699
1627
|
`);
|
|
1700
1628
|
}
|
|
1701
1629
|
});
|
|
1702
|
-
const { baseUrl
|
|
1630
|
+
const { baseUrl } = resolveCloudTarget(options, env, store);
|
|
1703
1631
|
const initialCredential = resolveCloudCredential({
|
|
1704
1632
|
env,
|
|
1705
1633
|
apiKeyFlag: options.apiKeyFlag,
|
|
@@ -1707,11 +1635,9 @@ async function ensureCloudCredentialsForCommand(options) {
|
|
|
1707
1635
|
});
|
|
1708
1636
|
let credential = initialCredential;
|
|
1709
1637
|
if (!credential) {
|
|
1710
|
-
const saved = store.readCloudCredential({
|
|
1711
|
-
baseUrl,
|
|
1712
|
-
siteUrl
|
|
1713
|
-
});
|
|
1638
|
+
const saved = store.readCloudCredential({ baseUrl });
|
|
1714
1639
|
const freshSaved = saved ? await ensureSavedCredentialIsFresh(saved, {
|
|
1640
|
+
env,
|
|
1715
1641
|
fetchFn,
|
|
1716
1642
|
store,
|
|
1717
1643
|
now,
|
|
@@ -1729,7 +1655,7 @@ async function ensureCloudCredentialsForCommand(options) {
|
|
|
1729
1655
|
if (!credential) {
|
|
1730
1656
|
if (options.autoLoginIfNeeded && (options.interactive ?? false)) {
|
|
1731
1657
|
const loggedIn = await runDeviceLoginFlow({
|
|
1732
|
-
|
|
1658
|
+
authSiteUrl: resolveAuthSiteUrl(env),
|
|
1733
1659
|
fetchFn,
|
|
1734
1660
|
writeProgress,
|
|
1735
1661
|
openExternalUrl,
|
|
@@ -1739,7 +1665,6 @@ async function ensureCloudCredentialsForCommand(options) {
|
|
|
1739
1665
|
});
|
|
1740
1666
|
store.writeCloudCredential({
|
|
1741
1667
|
baseUrl,
|
|
1742
|
-
siteUrl,
|
|
1743
1668
|
scope: loggedIn.scope,
|
|
1744
1669
|
accessToken: loggedIn.accessToken,
|
|
1745
1670
|
refreshToken: loggedIn.refreshToken,
|
|
@@ -1757,28 +1682,25 @@ async function ensureCloudCredentialsForCommand(options) {
|
|
|
1757
1682
|
throw new Error(toAuthMissingMessage(options.commandName));
|
|
1758
1683
|
}
|
|
1759
1684
|
}
|
|
1760
|
-
store.writeActiveCloudTarget({
|
|
1761
|
-
baseUrl,
|
|
1762
|
-
siteUrl
|
|
1763
|
-
});
|
|
1685
|
+
store.writeActiveCloudTarget({ baseUrl });
|
|
1764
1686
|
applyCloudCredentialToEnv(env, credential);
|
|
1765
1687
|
env.OPENSTEER_BASE_URL = baseUrl;
|
|
1766
|
-
env.OPENSTEER_CLOUD_SITE_URL = siteUrl;
|
|
1767
1688
|
return {
|
|
1768
1689
|
token: credential.token,
|
|
1769
1690
|
authScheme: credential.authScheme,
|
|
1770
1691
|
source: credential.source,
|
|
1771
1692
|
kind: credential.kind,
|
|
1772
|
-
baseUrl
|
|
1773
|
-
siteUrl
|
|
1693
|
+
baseUrl
|
|
1774
1694
|
};
|
|
1775
1695
|
}
|
|
1776
1696
|
async function runLogin(args, deps) {
|
|
1777
|
-
const { baseUrl
|
|
1697
|
+
const { baseUrl } = resolveCloudTarget(args, deps.env, deps.store, {
|
|
1698
|
+
allowRememberedTarget: false
|
|
1699
|
+
});
|
|
1778
1700
|
const writeProgress = args.json ? deps.writeStderr : deps.writeStdout;
|
|
1779
1701
|
const browserOpenMode = describeBrowserOpenMode(args, deps);
|
|
1780
1702
|
const login = await runDeviceLoginFlow({
|
|
1781
|
-
|
|
1703
|
+
authSiteUrl: resolveAuthSiteUrl(deps.env),
|
|
1782
1704
|
fetchFn: deps.fetchFn,
|
|
1783
1705
|
writeProgress,
|
|
1784
1706
|
openExternalUrl: deps.openExternalUrl,
|
|
@@ -1789,22 +1711,17 @@ async function runLogin(args, deps) {
|
|
|
1789
1711
|
});
|
|
1790
1712
|
deps.store.writeCloudCredential({
|
|
1791
1713
|
baseUrl,
|
|
1792
|
-
siteUrl,
|
|
1793
1714
|
scope: login.scope,
|
|
1794
1715
|
accessToken: login.accessToken,
|
|
1795
1716
|
refreshToken: login.refreshToken,
|
|
1796
1717
|
obtainedAt: deps.now(),
|
|
1797
1718
|
expiresAt: login.expiresAt
|
|
1798
1719
|
});
|
|
1799
|
-
deps.store.writeActiveCloudTarget({
|
|
1800
|
-
baseUrl,
|
|
1801
|
-
siteUrl
|
|
1802
|
-
});
|
|
1720
|
+
deps.store.writeActiveCloudTarget({ baseUrl });
|
|
1803
1721
|
if (args.json) {
|
|
1804
1722
|
writeJsonLine(deps, {
|
|
1805
1723
|
loggedIn: true,
|
|
1806
1724
|
baseUrl,
|
|
1807
|
-
siteUrl,
|
|
1808
1725
|
expiresAt: login.expiresAt,
|
|
1809
1726
|
scope: login.scope,
|
|
1810
1727
|
authSource: "device"
|
|
@@ -1812,33 +1729,22 @@ async function runLogin(args, deps) {
|
|
|
1812
1729
|
return 0;
|
|
1813
1730
|
}
|
|
1814
1731
|
writeHumanLine(deps, "Opensteer CLI login successful.");
|
|
1815
|
-
writeHumanLine(deps, ` Site URL: ${siteUrl}`);
|
|
1816
1732
|
writeHumanLine(deps, ` API Base URL: ${baseUrl}`);
|
|
1817
1733
|
writeHumanLine(deps, ` Expires At: ${new Date(login.expiresAt).toISOString()}`);
|
|
1818
1734
|
return 0;
|
|
1819
1735
|
}
|
|
1820
1736
|
async function runStatus(args, deps) {
|
|
1821
|
-
const { baseUrl
|
|
1822
|
-
deps.store.writeActiveCloudTarget({
|
|
1823
|
-
|
|
1824
|
-
siteUrl
|
|
1825
|
-
});
|
|
1826
|
-
const saved = deps.store.readCloudCredential({
|
|
1827
|
-
baseUrl,
|
|
1828
|
-
siteUrl
|
|
1829
|
-
});
|
|
1737
|
+
const { baseUrl } = resolveCloudTarget(args, deps.env, deps.store);
|
|
1738
|
+
deps.store.writeActiveCloudTarget({ baseUrl });
|
|
1739
|
+
const saved = deps.store.readCloudCredential({ baseUrl });
|
|
1830
1740
|
if (!saved) {
|
|
1831
1741
|
if (args.json) {
|
|
1832
1742
|
writeJsonLine(deps, {
|
|
1833
1743
|
loggedIn: false,
|
|
1834
|
-
baseUrl
|
|
1835
|
-
siteUrl
|
|
1744
|
+
baseUrl
|
|
1836
1745
|
});
|
|
1837
1746
|
} else {
|
|
1838
|
-
writeHumanLine(
|
|
1839
|
-
deps,
|
|
1840
|
-
`Opensteer CLI is not logged in for ${siteUrl}.`
|
|
1841
|
-
);
|
|
1747
|
+
writeHumanLine(deps, `Opensteer CLI is not logged in for ${baseUrl}.`);
|
|
1842
1748
|
}
|
|
1843
1749
|
return 0;
|
|
1844
1750
|
}
|
|
@@ -1849,7 +1755,6 @@ async function runStatus(args, deps) {
|
|
|
1849
1755
|
loggedIn: true,
|
|
1850
1756
|
expired,
|
|
1851
1757
|
baseUrl: saved.baseUrl,
|
|
1852
|
-
siteUrl: saved.siteUrl,
|
|
1853
1758
|
expiresAt: saved.expiresAt,
|
|
1854
1759
|
scope: saved.scope
|
|
1855
1760
|
});
|
|
@@ -1859,43 +1764,33 @@ async function runStatus(args, deps) {
|
|
|
1859
1764
|
deps,
|
|
1860
1765
|
expired ? "Opensteer CLI has a saved login, but the access token is expired." : "Opensteer CLI is logged in."
|
|
1861
1766
|
);
|
|
1862
|
-
writeHumanLine(deps, ` Site URL: ${saved.siteUrl}`);
|
|
1863
1767
|
writeHumanLine(deps, ` API Base URL: ${saved.baseUrl}`);
|
|
1864
1768
|
writeHumanLine(deps, ` Expires At: ${new Date(saved.expiresAt).toISOString()}`);
|
|
1865
1769
|
return 0;
|
|
1866
1770
|
}
|
|
1867
1771
|
async function runLogout(args, deps) {
|
|
1868
|
-
const { baseUrl
|
|
1869
|
-
deps.store.writeActiveCloudTarget({
|
|
1870
|
-
|
|
1871
|
-
siteUrl
|
|
1872
|
-
});
|
|
1873
|
-
const saved = deps.store.readCloudCredential({
|
|
1874
|
-
baseUrl,
|
|
1875
|
-
siteUrl
|
|
1876
|
-
});
|
|
1772
|
+
const { baseUrl } = resolveCloudTarget(args, deps.env, deps.store);
|
|
1773
|
+
deps.store.writeActiveCloudTarget({ baseUrl });
|
|
1774
|
+
const saved = deps.store.readCloudCredential({ baseUrl });
|
|
1877
1775
|
if (saved) {
|
|
1878
1776
|
try {
|
|
1879
|
-
await revokeToken(
|
|
1777
|
+
await revokeToken(
|
|
1778
|
+
resolveAuthSiteUrl(deps.env),
|
|
1779
|
+
saved.refreshToken,
|
|
1780
|
+
deps.fetchFn
|
|
1781
|
+
);
|
|
1880
1782
|
} catch {
|
|
1881
1783
|
}
|
|
1882
1784
|
}
|
|
1883
|
-
deps.store.clearCloudCredential({
|
|
1884
|
-
baseUrl,
|
|
1885
|
-
siteUrl
|
|
1886
|
-
});
|
|
1785
|
+
deps.store.clearCloudCredential({ baseUrl });
|
|
1887
1786
|
if (args.json) {
|
|
1888
1787
|
writeJsonLine(deps, {
|
|
1889
1788
|
loggedOut: true,
|
|
1890
|
-
baseUrl
|
|
1891
|
-
siteUrl
|
|
1789
|
+
baseUrl
|
|
1892
1790
|
});
|
|
1893
1791
|
return 0;
|
|
1894
1792
|
}
|
|
1895
|
-
writeHumanLine(
|
|
1896
|
-
deps,
|
|
1897
|
-
`Opensteer CLI login removed for ${siteUrl}.`
|
|
1898
|
-
);
|
|
1793
|
+
writeHumanLine(deps, `Opensteer CLI login removed for ${baseUrl}.`);
|
|
1899
1794
|
return 0;
|
|
1900
1795
|
}
|
|
1901
1796
|
async function runOpensteerAuthCli(rawArgs, overrideDeps = {}) {
|
package/dist/cli/auth.d.cts
CHANGED
|
@@ -3,7 +3,6 @@ import 'playwright';
|
|
|
3
3
|
|
|
4
4
|
interface StoredMachineCloudCredential {
|
|
5
5
|
baseUrl: string;
|
|
6
|
-
siteUrl: string;
|
|
7
6
|
scope: string[];
|
|
8
7
|
accessToken: string;
|
|
9
8
|
refreshToken: string;
|
|
@@ -12,7 +11,6 @@ interface StoredMachineCloudCredential {
|
|
|
12
11
|
}
|
|
13
12
|
interface WriteMachineCloudCredentialArgs {
|
|
14
13
|
baseUrl: string;
|
|
15
|
-
siteUrl: string;
|
|
16
14
|
scope: string[];
|
|
17
15
|
accessToken: string;
|
|
18
16
|
refreshToken: string;
|
|
@@ -21,7 +19,6 @@ interface WriteMachineCloudCredentialArgs {
|
|
|
21
19
|
}
|
|
22
20
|
interface CloudCredentialStoreTarget {
|
|
23
21
|
baseUrl: string;
|
|
24
|
-
siteUrl: string;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
type AuthFetchFn = (input: string, init?: RequestInit) => Promise<Response>;
|
|
@@ -39,7 +36,6 @@ interface EnsuredCloudAuthContext {
|
|
|
39
36
|
source: 'flag' | 'env' | 'saved';
|
|
40
37
|
kind: 'api-key' | 'access-token';
|
|
41
38
|
baseUrl: string;
|
|
42
|
-
siteUrl: string;
|
|
43
39
|
}
|
|
44
40
|
interface EnsureCloudCredentialsOptions {
|
|
45
41
|
commandName: string;
|
|
@@ -48,7 +44,6 @@ interface EnsureCloudCredentialsOptions {
|
|
|
48
44
|
apiKeyFlag?: string;
|
|
49
45
|
accessTokenFlag?: string;
|
|
50
46
|
baseUrl?: string;
|
|
51
|
-
siteUrl?: string;
|
|
52
47
|
interactive?: boolean;
|
|
53
48
|
autoLoginIfNeeded?: boolean;
|
|
54
49
|
writeProgress?: (message: string) => void;
|
|
@@ -86,7 +81,6 @@ interface AuthCliDeps {
|
|
|
86
81
|
}
|
|
87
82
|
interface AuthCommonArgs {
|
|
88
83
|
baseUrl?: string;
|
|
89
|
-
siteUrl?: string;
|
|
90
84
|
json?: boolean;
|
|
91
85
|
}
|
|
92
86
|
interface AuthLoginArgs extends AuthCommonArgs {
|
package/dist/cli/auth.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import 'playwright';
|
|
|
3
3
|
|
|
4
4
|
interface StoredMachineCloudCredential {
|
|
5
5
|
baseUrl: string;
|
|
6
|
-
siteUrl: string;
|
|
7
6
|
scope: string[];
|
|
8
7
|
accessToken: string;
|
|
9
8
|
refreshToken: string;
|
|
@@ -12,7 +11,6 @@ interface StoredMachineCloudCredential {
|
|
|
12
11
|
}
|
|
13
12
|
interface WriteMachineCloudCredentialArgs {
|
|
14
13
|
baseUrl: string;
|
|
15
|
-
siteUrl: string;
|
|
16
14
|
scope: string[];
|
|
17
15
|
accessToken: string;
|
|
18
16
|
refreshToken: string;
|
|
@@ -21,7 +19,6 @@ interface WriteMachineCloudCredentialArgs {
|
|
|
21
19
|
}
|
|
22
20
|
interface CloudCredentialStoreTarget {
|
|
23
21
|
baseUrl: string;
|
|
24
|
-
siteUrl: string;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
type AuthFetchFn = (input: string, init?: RequestInit) => Promise<Response>;
|
|
@@ -39,7 +36,6 @@ interface EnsuredCloudAuthContext {
|
|
|
39
36
|
source: 'flag' | 'env' | 'saved';
|
|
40
37
|
kind: 'api-key' | 'access-token';
|
|
41
38
|
baseUrl: string;
|
|
42
|
-
siteUrl: string;
|
|
43
39
|
}
|
|
44
40
|
interface EnsureCloudCredentialsOptions {
|
|
45
41
|
commandName: string;
|
|
@@ -48,7 +44,6 @@ interface EnsureCloudCredentialsOptions {
|
|
|
48
44
|
apiKeyFlag?: string;
|
|
49
45
|
accessTokenFlag?: string;
|
|
50
46
|
baseUrl?: string;
|
|
51
|
-
siteUrl?: string;
|
|
52
47
|
interactive?: boolean;
|
|
53
48
|
autoLoginIfNeeded?: boolean;
|
|
54
49
|
writeProgress?: (message: string) => void;
|
|
@@ -86,7 +81,6 @@ interface AuthCliDeps {
|
|
|
86
81
|
}
|
|
87
82
|
interface AuthCommonArgs {
|
|
88
83
|
baseUrl?: string;
|
|
89
|
-
siteUrl?: string;
|
|
90
84
|
json?: boolean;
|
|
91
85
|
}
|
|
92
86
|
interface AuthLoginArgs extends AuthCommonArgs {
|