@backstage/cli-module-auth 0.1.1-next.1 → 0.1.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @backstage/cli-module-auth
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2e5c5f8: Bumped `glob` dependency from v7/v8/v11 to v13 to address security vulnerabilities in older versions. Bumped `rollup` from v4.27 to v4.59+ to fix a high severity path traversal vulnerability (GHSA-mw96-cpmx-2vgc).
|
|
8
|
+
- c705d44: Fixed `auth login` clearing previously configured action sources and other instance metadata when re-authenticating.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/errors@1.3.0
|
|
11
|
+
- @backstage/cli-node@0.3.1
|
|
12
|
+
|
|
13
|
+
## 0.1.1-next.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @backstage/errors@1.3.0-next.0
|
|
19
|
+
- @backstage/cli-node@0.3.1-next.1
|
|
20
|
+
|
|
3
21
|
## 0.1.1-next.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -276,7 +276,8 @@ async function persistInstance(options) {
|
|
|
276
276
|
clientId,
|
|
277
277
|
issuedAt: Date.now(),
|
|
278
278
|
accessTokenExpiresAt: Date.now() + token.expires_in * 1e3,
|
|
279
|
-
selected: existing?.selected
|
|
279
|
+
selected: existing?.selected,
|
|
280
|
+
metadata: existing?.metadata
|
|
280
281
|
});
|
|
281
282
|
});
|
|
282
283
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.cjs.js","sources":["../../src/commands/login.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { startCallbackServer } from '../lib/localServer';\nimport { spawn } from 'node:child_process';\nimport { challengeFromVerifier, generateVerifier } from '../lib/pkce';\nimport { httpJson } from '../lib/http';\nimport {\n upsertInstance,\n withMetadataLock,\n getAllInstances,\n getInstanceByName,\n StoredInstance,\n} from '../lib/storage';\nimport { getSecretStore, getAuthInstanceService } from '@internal/cli';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { globSync } from 'glob';\nimport YAML from 'yaml';\nimport inquirer from 'inquirer';\n\nconst TOKEN_EXCHANGE_TIMEOUT_MS = 30_000;\n\nexport default async ({ args, info }: CliCommandContext) => {\n const {\n flags: { backendUrl, noBrowser, instance: instanceFlag },\n } = cli(\n {\n help: info,\n flags: {\n backendUrl: { type: String, description: 'Backend base URL' },\n noBrowser: {\n type: Boolean,\n description: 'Do not open browser automatically',\n },\n instance: {\n type: String,\n description: 'Name for this instance (used by other auth commands)',\n },\n },\n },\n undefined,\n args,\n );\n\n const { instances, selected } = await getAllInstances();\n\n let backendBaseUrl: string;\n let instanceName: string;\n\n if (instanceFlag) {\n instanceName = instanceFlag;\n const targetInstance = instances.find(i => i.name === instanceFlag);\n if (targetInstance) {\n backendBaseUrl = normalizeUrl(backendUrl) ?? targetInstance.baseUrl;\n } else {\n backendBaseUrl = normalizeUrl(backendUrl) ?? (await pickBaseUrl());\n }\n } else if (backendUrl) {\n backendBaseUrl = normalizeUrl(backendUrl);\n instanceName = deriveInstanceName(backendBaseUrl);\n } else if (instances.length > 0) {\n const choice = await promptForInstance(instances, selected);\n if (choice === '__new__') {\n backendBaseUrl = await pickBaseUrl();\n instanceName = deriveInstanceName(backendBaseUrl);\n } else {\n const targetInstance = instances.find(i => i.name === choice);\n if (!targetInstance) {\n throw new Error('Instance not found');\n }\n backendBaseUrl = targetInstance.baseUrl;\n instanceName = targetInstance.name;\n }\n } else {\n backendBaseUrl = await pickBaseUrl();\n instanceName = deriveInstanceName(backendBaseUrl);\n }\n\n const authBaseUrl = `${backendBaseUrl}/api/auth`;\n const clientId = `${authBaseUrl}/.well-known/oauth-client/cli.json`;\n\n const metadataResponse = await fetch(clientId, {\n signal: AbortSignal.timeout(30_000),\n });\n if (!metadataResponse.ok) {\n throw new Error(\n `Server does not support CLI authentication. Ensure CIMD is enabled on the backend.`,\n );\n }\n\n const { verifier, challenge, state } = createPkceState();\n const callback = await startCallbackServer({ state });\n\n try {\n const authorizeUrl = buildAuthorizeUrl({\n authBaseUrl,\n clientId,\n redirectUri: callback.url,\n state,\n challenge,\n });\n\n await openBrowserOrPrint(authorizeUrl, noBrowser);\n\n const code = await waitForAuthorizationCode(callback, state);\n\n const token = await exchangeAuthorizationCode({\n authBaseUrl,\n code,\n redirectUri: callback.url,\n verifier,\n });\n\n await persistInstance({\n instanceName,\n backendBaseUrl,\n clientId,\n token,\n });\n\n process.stdout.write('Login successful\\n');\n } finally {\n await callback.close();\n }\n};\n\nasync function promptForInstance(\n instances: StoredInstance[],\n selected: StoredInstance | undefined,\n): Promise<string> {\n const choices = instances.map(i => ({\n name: `${i.name === selected?.name ? '* ' : ' '}${i.name} (${i.baseUrl})`,\n value: i.name,\n }));\n\n choices.push({\n name: 'Add new instance...',\n value: '__new__',\n });\n\n const { choice } = await inquirer.prompt<{ choice: string }>([\n {\n type: 'list',\n name: 'choice',\n message: 'Select instance to authenticate:',\n choices,\n default: selected?.name ?? '__new__',\n },\n ]);\n\n return choice;\n}\n\nasync function pickBaseUrl() {\n const cwd = process.cwd();\n const candidates: Array<{ url: string; file: string }> = [];\n\n const patterns = [\n 'app-config.yaml',\n 'app-config.*.yaml',\n 'packages/*/app-config.yaml',\n 'packages/*/app-config.*.yaml',\n ];\n const files = patterns.flatMap(p => globSync(p, { cwd, nodir: true }));\n for (const file of files) {\n try {\n const content = await fs.readFile(path.resolve(cwd, file), 'utf8');\n const doc = YAML.parse(content);\n const url = doc?.backend?.baseUrl as string | undefined;\n if (url) {\n candidates.push({ url: normalizeUrl(url), file });\n }\n } catch {\n // ignore parse errors\n }\n }\n\n const list = [...new Map(candidates.map(c => [c.url, c])).values()];\n if (list.length === 0) {\n const { manual } = await inquirer.prompt<{ manual: string }>([\n { type: 'input', name: 'manual', message: 'Enter backend base URL' },\n ]);\n return normalizeUrl(manual);\n }\n if (list.length === 1) {\n return list[0].url;\n }\n\n const { picked } = await inquirer.prompt<{ picked: string }>([\n {\n type: 'list',\n name: 'picked',\n message: 'Select backend base URL',\n choices: [\n ...list.map(e => ({ name: `${e.url} (${e.file})`, value: e.url })),\n { name: 'Enter manually', value: '__manual__' },\n ],\n },\n ]);\n if (picked === '__manual__') {\n const { manual } = await inquirer.prompt<{ manual: string }>([\n { type: 'input', name: 'manual', message: 'Enter backend base URL' },\n ]);\n return normalizeUrl(manual);\n }\n return picked;\n}\n\nfunction normalizeUrl(u: string): string;\nfunction normalizeUrl(u: string | undefined): string | undefined;\nfunction normalizeUrl(u: string | undefined): string | undefined {\n if (u === undefined) {\n return undefined;\n }\n try {\n const url = new URL(u);\n return url.toString().replace(/\\/$/, '');\n } catch {\n throw new Error(`'${u}' is not a valid URL`);\n }\n}\n\nfunction deriveInstanceName(url: string): string {\n return new URL(url).host;\n}\n\nfunction createPkceState() {\n const verifier = generateVerifier();\n const challenge = challengeFromVerifier(verifier);\n const state = cryptoRandom();\n return { verifier, challenge, state };\n}\n\nfunction buildAuthorizeUrl(options: {\n authBaseUrl: string;\n clientId: string;\n redirectUri: string;\n state: string;\n challenge: string;\n}): string {\n const { authBaseUrl, clientId, redirectUri, state, challenge } = options;\n const authorize = new URL(`${authBaseUrl}/v1/authorize`);\n authorize.searchParams.set('client_id', clientId);\n authorize.searchParams.set('redirect_uri', redirectUri);\n authorize.searchParams.set('response_type', 'code');\n authorize.searchParams.set('scope', 'openid offline_access');\n authorize.searchParams.set('state', state);\n authorize.searchParams.set('code_challenge', challenge);\n authorize.searchParams.set('code_challenge_method', 'S256');\n return authorize.toString();\n}\n\nasync function openBrowserOrPrint(url: string, noBrowser?: boolean) {\n if (noBrowser) {\n process.stdout.write(`Open this URL to continue: ${url}\\n`);\n } else {\n process.stdout.write(`Opening the following URL: ${url}\\n`);\n openInBrowser(url);\n }\n}\n\nasync function waitForAuthorizationCode(\n callback: Awaited<ReturnType<typeof startCallbackServer>>,\n expectedState: string,\n) {\n const { code, state } = await callback.waitForCode();\n if (state !== expectedState) {\n throw new Error('State mismatch');\n }\n return code;\n}\n\nasync function exchangeAuthorizationCode(options: {\n authBaseUrl: string;\n code: string;\n redirectUri: string;\n verifier: string;\n}) {\n const { authBaseUrl, code, redirectUri, verifier } = options;\n return await httpJson<{\n access_token: string;\n token_type: string;\n expires_in: number;\n id_token?: string;\n refresh_token?: string;\n }>(`${authBaseUrl}/v1/token`, {\n method: 'POST',\n body: {\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n code_verifier: verifier,\n },\n signal: AbortSignal.timeout(TOKEN_EXCHANGE_TIMEOUT_MS),\n });\n}\n\nasync function persistInstance(options: {\n instanceName: string;\n backendBaseUrl: string;\n clientId: string;\n token: { access_token: string; refresh_token?: string; expires_in: number };\n}) {\n const { instanceName, backendBaseUrl, clientId, token } = options;\n const secretStore = await getSecretStore();\n await withMetadataLock(async () => {\n const service = getAuthInstanceService(instanceName);\n await secretStore.set(service, 'accessToken', token.access_token);\n if (token.refresh_token) {\n await secretStore.set(service, 'refreshToken', token.refresh_token);\n } else {\n process.stderr.write(\n 'Warning: No refresh token received. You will need to re-authenticate when the access token expires.\\n',\n );\n }\n let existing: StoredInstance | undefined;\n try {\n existing = await getInstanceByName(instanceName);\n } catch {\n // new instance\n }\n await upsertInstance({\n name: instanceName,\n baseUrl: backendBaseUrl,\n clientId,\n issuedAt: Date.now(),\n accessTokenExpiresAt: Date.now() + token.expires_in * 1000,\n selected: existing?.selected,\n });\n });\n}\n\nfunction cryptoRandom(): string {\n return crypto.randomBytes(32).toString('hex');\n}\n\n// The react-dev-utils/openBrowser breaks the login URL by encoding the URL parameters again\nexport function openInBrowser(url: string): void {\n const handleError = (error: unknown) => {\n const message = error instanceof Error ? error.message : 'Unknown error';\n process.stderr.write(\n `Warning: Failed to open browser automatically: ${message}\\n`,\n );\n process.stderr.write(`Please open this URL manually: ${url}\\n`);\n };\n\n const spawnOpts = { detached: true, stdio: 'ignore' } as const;\n let child;\n try {\n if (process.platform === 'darwin') {\n child = spawn('open', [url], spawnOpts);\n } else if (process.platform === 'win32') {\n child = spawn(\n 'powershell',\n ['-Command', `Start-Process '${url.replace(/'/g, \"''\")}'`],\n spawnOpts,\n );\n } else {\n child = spawn('xdg-open', [url], spawnOpts);\n }\n child.unref();\n child.on('error', handleError);\n } catch (error) {\n handleError(error);\n }\n}\n"],"names":["cli","getAllInstances","startCallbackServer","inquirer","globSync","fs","path","YAML","generateVerifier","challengeFromVerifier","httpJson","secretStore","getSecretStore","withMetadataLock","getAuthInstanceService","getInstanceByName","upsertInstance","crypto","spawn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"login.cjs.js","sources":["../../src/commands/login.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { startCallbackServer } from '../lib/localServer';\nimport { spawn } from 'node:child_process';\nimport { challengeFromVerifier, generateVerifier } from '../lib/pkce';\nimport { httpJson } from '../lib/http';\nimport {\n upsertInstance,\n withMetadataLock,\n getAllInstances,\n getInstanceByName,\n StoredInstance,\n} from '../lib/storage';\nimport { getSecretStore, getAuthInstanceService } from '@internal/cli';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { globSync } from 'glob';\nimport YAML from 'yaml';\nimport inquirer from 'inquirer';\n\nconst TOKEN_EXCHANGE_TIMEOUT_MS = 30_000;\n\nexport default async ({ args, info }: CliCommandContext) => {\n const {\n flags: { backendUrl, noBrowser, instance: instanceFlag },\n } = cli(\n {\n help: info,\n flags: {\n backendUrl: { type: String, description: 'Backend base URL' },\n noBrowser: {\n type: Boolean,\n description: 'Do not open browser automatically',\n },\n instance: {\n type: String,\n description: 'Name for this instance (used by other auth commands)',\n },\n },\n },\n undefined,\n args,\n );\n\n const { instances, selected } = await getAllInstances();\n\n let backendBaseUrl: string;\n let instanceName: string;\n\n if (instanceFlag) {\n instanceName = instanceFlag;\n const targetInstance = instances.find(i => i.name === instanceFlag);\n if (targetInstance) {\n backendBaseUrl = normalizeUrl(backendUrl) ?? targetInstance.baseUrl;\n } else {\n backendBaseUrl = normalizeUrl(backendUrl) ?? (await pickBaseUrl());\n }\n } else if (backendUrl) {\n backendBaseUrl = normalizeUrl(backendUrl);\n instanceName = deriveInstanceName(backendBaseUrl);\n } else if (instances.length > 0) {\n const choice = await promptForInstance(instances, selected);\n if (choice === '__new__') {\n backendBaseUrl = await pickBaseUrl();\n instanceName = deriveInstanceName(backendBaseUrl);\n } else {\n const targetInstance = instances.find(i => i.name === choice);\n if (!targetInstance) {\n throw new Error('Instance not found');\n }\n backendBaseUrl = targetInstance.baseUrl;\n instanceName = targetInstance.name;\n }\n } else {\n backendBaseUrl = await pickBaseUrl();\n instanceName = deriveInstanceName(backendBaseUrl);\n }\n\n const authBaseUrl = `${backendBaseUrl}/api/auth`;\n const clientId = `${authBaseUrl}/.well-known/oauth-client/cli.json`;\n\n const metadataResponse = await fetch(clientId, {\n signal: AbortSignal.timeout(30_000),\n });\n if (!metadataResponse.ok) {\n throw new Error(\n `Server does not support CLI authentication. Ensure CIMD is enabled on the backend.`,\n );\n }\n\n const { verifier, challenge, state } = createPkceState();\n const callback = await startCallbackServer({ state });\n\n try {\n const authorizeUrl = buildAuthorizeUrl({\n authBaseUrl,\n clientId,\n redirectUri: callback.url,\n state,\n challenge,\n });\n\n await openBrowserOrPrint(authorizeUrl, noBrowser);\n\n const code = await waitForAuthorizationCode(callback, state);\n\n const token = await exchangeAuthorizationCode({\n authBaseUrl,\n code,\n redirectUri: callback.url,\n verifier,\n });\n\n await persistInstance({\n instanceName,\n backendBaseUrl,\n clientId,\n token,\n });\n\n process.stdout.write('Login successful\\n');\n } finally {\n await callback.close();\n }\n};\n\nasync function promptForInstance(\n instances: StoredInstance[],\n selected: StoredInstance | undefined,\n): Promise<string> {\n const choices = instances.map(i => ({\n name: `${i.name === selected?.name ? '* ' : ' '}${i.name} (${i.baseUrl})`,\n value: i.name,\n }));\n\n choices.push({\n name: 'Add new instance...',\n value: '__new__',\n });\n\n const { choice } = await inquirer.prompt<{ choice: string }>([\n {\n type: 'list',\n name: 'choice',\n message: 'Select instance to authenticate:',\n choices,\n default: selected?.name ?? '__new__',\n },\n ]);\n\n return choice;\n}\n\nasync function pickBaseUrl() {\n const cwd = process.cwd();\n const candidates: Array<{ url: string; file: string }> = [];\n\n const patterns = [\n 'app-config.yaml',\n 'app-config.*.yaml',\n 'packages/*/app-config.yaml',\n 'packages/*/app-config.*.yaml',\n ];\n const files = patterns.flatMap(p => globSync(p, { cwd, nodir: true }));\n for (const file of files) {\n try {\n const content = await fs.readFile(path.resolve(cwd, file), 'utf8');\n const doc = YAML.parse(content);\n const url = doc?.backend?.baseUrl as string | undefined;\n if (url) {\n candidates.push({ url: normalizeUrl(url), file });\n }\n } catch {\n // ignore parse errors\n }\n }\n\n const list = [...new Map(candidates.map(c => [c.url, c])).values()];\n if (list.length === 0) {\n const { manual } = await inquirer.prompt<{ manual: string }>([\n { type: 'input', name: 'manual', message: 'Enter backend base URL' },\n ]);\n return normalizeUrl(manual);\n }\n if (list.length === 1) {\n return list[0].url;\n }\n\n const { picked } = await inquirer.prompt<{ picked: string }>([\n {\n type: 'list',\n name: 'picked',\n message: 'Select backend base URL',\n choices: [\n ...list.map(e => ({ name: `${e.url} (${e.file})`, value: e.url })),\n { name: 'Enter manually', value: '__manual__' },\n ],\n },\n ]);\n if (picked === '__manual__') {\n const { manual } = await inquirer.prompt<{ manual: string }>([\n { type: 'input', name: 'manual', message: 'Enter backend base URL' },\n ]);\n return normalizeUrl(manual);\n }\n return picked;\n}\n\nfunction normalizeUrl(u: string): string;\nfunction normalizeUrl(u: string | undefined): string | undefined;\nfunction normalizeUrl(u: string | undefined): string | undefined {\n if (u === undefined) {\n return undefined;\n }\n try {\n const url = new URL(u);\n return url.toString().replace(/\\/$/, '');\n } catch {\n throw new Error(`'${u}' is not a valid URL`);\n }\n}\n\nfunction deriveInstanceName(url: string): string {\n return new URL(url).host;\n}\n\nfunction createPkceState() {\n const verifier = generateVerifier();\n const challenge = challengeFromVerifier(verifier);\n const state = cryptoRandom();\n return { verifier, challenge, state };\n}\n\nfunction buildAuthorizeUrl(options: {\n authBaseUrl: string;\n clientId: string;\n redirectUri: string;\n state: string;\n challenge: string;\n}): string {\n const { authBaseUrl, clientId, redirectUri, state, challenge } = options;\n const authorize = new URL(`${authBaseUrl}/v1/authorize`);\n authorize.searchParams.set('client_id', clientId);\n authorize.searchParams.set('redirect_uri', redirectUri);\n authorize.searchParams.set('response_type', 'code');\n authorize.searchParams.set('scope', 'openid offline_access');\n authorize.searchParams.set('state', state);\n authorize.searchParams.set('code_challenge', challenge);\n authorize.searchParams.set('code_challenge_method', 'S256');\n return authorize.toString();\n}\n\nasync function openBrowserOrPrint(url: string, noBrowser?: boolean) {\n if (noBrowser) {\n process.stdout.write(`Open this URL to continue: ${url}\\n`);\n } else {\n process.stdout.write(`Opening the following URL: ${url}\\n`);\n openInBrowser(url);\n }\n}\n\nasync function waitForAuthorizationCode(\n callback: Awaited<ReturnType<typeof startCallbackServer>>,\n expectedState: string,\n) {\n const { code, state } = await callback.waitForCode();\n if (state !== expectedState) {\n throw new Error('State mismatch');\n }\n return code;\n}\n\nasync function exchangeAuthorizationCode(options: {\n authBaseUrl: string;\n code: string;\n redirectUri: string;\n verifier: string;\n}) {\n const { authBaseUrl, code, redirectUri, verifier } = options;\n return await httpJson<{\n access_token: string;\n token_type: string;\n expires_in: number;\n id_token?: string;\n refresh_token?: string;\n }>(`${authBaseUrl}/v1/token`, {\n method: 'POST',\n body: {\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n code_verifier: verifier,\n },\n signal: AbortSignal.timeout(TOKEN_EXCHANGE_TIMEOUT_MS),\n });\n}\n\nasync function persistInstance(options: {\n instanceName: string;\n backendBaseUrl: string;\n clientId: string;\n token: { access_token: string; refresh_token?: string; expires_in: number };\n}) {\n const { instanceName, backendBaseUrl, clientId, token } = options;\n const secretStore = await getSecretStore();\n await withMetadataLock(async () => {\n const service = getAuthInstanceService(instanceName);\n await secretStore.set(service, 'accessToken', token.access_token);\n if (token.refresh_token) {\n await secretStore.set(service, 'refreshToken', token.refresh_token);\n } else {\n process.stderr.write(\n 'Warning: No refresh token received. You will need to re-authenticate when the access token expires.\\n',\n );\n }\n let existing: StoredInstance | undefined;\n try {\n existing = await getInstanceByName(instanceName);\n } catch {\n // new instance\n }\n await upsertInstance({\n name: instanceName,\n baseUrl: backendBaseUrl,\n clientId,\n issuedAt: Date.now(),\n accessTokenExpiresAt: Date.now() + token.expires_in * 1000,\n selected: existing?.selected,\n metadata: existing?.metadata,\n });\n });\n}\n\nfunction cryptoRandom(): string {\n return crypto.randomBytes(32).toString('hex');\n}\n\n// The react-dev-utils/openBrowser breaks the login URL by encoding the URL parameters again\nexport function openInBrowser(url: string): void {\n const handleError = (error: unknown) => {\n const message = error instanceof Error ? error.message : 'Unknown error';\n process.stderr.write(\n `Warning: Failed to open browser automatically: ${message}\\n`,\n );\n process.stderr.write(`Please open this URL manually: ${url}\\n`);\n };\n\n const spawnOpts = { detached: true, stdio: 'ignore' } as const;\n let child;\n try {\n if (process.platform === 'darwin') {\n child = spawn('open', [url], spawnOpts);\n } else if (process.platform === 'win32') {\n child = spawn(\n 'powershell',\n ['-Command', `Start-Process '${url.replace(/'/g, \"''\")}'`],\n spawnOpts,\n );\n } else {\n child = spawn('xdg-open', [url], spawnOpts);\n }\n child.unref();\n child.on('error', handleError);\n } catch (error) {\n handleError(error);\n }\n}\n"],"names":["cli","getAllInstances","startCallbackServer","inquirer","globSync","fs","path","YAML","generateVerifier","challengeFromVerifier","httpJson","secretStore","getSecretStore","withMetadataLock","getAuthInstanceService","getInstanceByName","upsertInstance","crypto","spawn"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/cli-module-auth",
|
|
3
|
-
"version": "0.1.1
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "CLI module for Backstage CLI",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli-module"
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"test": "backstage-cli package test"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@backstage/cli-node": "0.3.1
|
|
37
|
-
"@backstage/errors": "1.
|
|
36
|
+
"@backstage/cli-node": "^0.3.1",
|
|
37
|
+
"@backstage/errors": "^1.3.0",
|
|
38
38
|
"cleye": "^2.3.0",
|
|
39
39
|
"fs-extra": "^11.2.0",
|
|
40
40
|
"glob": "^13.0.0",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"zod": "^3.25.76"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@backstage/backend-test-utils": "1.11.2
|
|
48
|
-
"@backstage/cli": "0.36.1
|
|
47
|
+
"@backstage/backend-test-utils": "^1.11.2",
|
|
48
|
+
"@backstage/cli": "^0.36.1",
|
|
49
49
|
"@types/fs-extra": "^11.0.0",
|
|
50
50
|
"@types/proper-lockfile": "^4"
|
|
51
51
|
},
|