From efb5243d0d0ee5a8ba99eadf263621c3f04d94bd Mon Sep 17 00:00:00 2001 From: "lisheng.lisheng" Date: Thu, 9 Jul 2026 23:40:47 +0800 Subject: [PATCH] feat(auth): call GenerateCLIAccessToken on open-api login When logging in with --open-api, call the GenerateCLIAccessToken API using the provided AK/SK to obtain an access token and persist it alongside the credentials in config.json. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../commands/auth/generate-access-token.ts | 57 +++++++++++++++++++ packages/commands/src/commands/auth/login.ts | 17 +++++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 packages/commands/src/commands/auth/generate-access-token.ts diff --git a/packages/commands/src/commands/auth/generate-access-token.ts b/packages/commands/src/commands/auth/generate-access-token.ts new file mode 100644 index 0000000..0470ef1 --- /dev/null +++ b/packages/commands/src/commands/auth/generate-access-token.ts @@ -0,0 +1,57 @@ +import { Client, REGIONS, type Identity, type Region, type Settings } from "bailian-cli-core"; + +const API_VERSION = "2026-02-10"; +const API_ACTION = "GenerateCLIAccessToken"; +const API_PATH = "/modelstudio/cli/generateAccessToken"; + +const MODEL_STUDIO_HOSTS: Partial> = { + cn: "modelstudio.cn-beijing.aliyuncs.com", + intl: "modelstudio.ap-southeast-1.aliyuncs.com", +}; + +function resolveRegion(baseUrl: string): Region { + for (const [region, url] of Object.entries(REGIONS) as Array<[Region, string]>) { + if (baseUrl === url || baseUrl.startsWith(`${url}/`)) return region; + } + return "cn"; +} + +function modelStudioHost(baseUrl: string): string { + const region = resolveRegion(baseUrl); + return MODEL_STUDIO_HOSTS[region] ?? MODEL_STUDIO_HOSTS.cn!; +} + +interface GenerateCLIAccessTokenResponse { + Success?: boolean; + Code?: string; + Message?: string; + Data?: Record; +} + +export async function generateCLIAccessToken(opts: { + identity: Identity; + settings: Settings; + baseUrl: string; + accessKeyId: string; + accessKeySecret: string; +}): Promise { + const { identity, settings, baseUrl, accessKeyId, accessKeySecret } = opts; + + const client = new Client({ + identity, + settings, + baseUrl, + openApiCred: { accessKeyId, accessKeySecret, source: "flag" }, + }); + + const host = modelStudioHost(baseUrl); + + return client.openApiQueryJson({ + host, + path: API_PATH, + action: API_ACTION, + version: API_VERSION, + method: "POST", + queryParams: {}, + }); +} diff --git a/packages/commands/src/commands/auth/login.ts b/packages/commands/src/commands/auth/login.ts index d3e8561..754db6b 100644 --- a/packages/commands/src/commands/auth/login.ts +++ b/packages/commands/src/commands/auth/login.ts @@ -5,6 +5,7 @@ import { runConsoleLogin, validateAndPersistApiKey, } from "./login-console.ts"; +import { generateCLIAccessToken } from "./generate-access-token.ts"; const LOGIN_MODE_HINT = "Choose exactly one login mode: --api-key, --console, or --open-api"; @@ -110,12 +111,26 @@ export default defineCommand({ if (flags.openApi) { if (settings.dryRun) { - emitBare("Would save OpenAPI AK/SK credentials."); + emitBare("Would save OpenAPI AK/SK credentials and generate CLI access token."); return; } + const resolvedBaseUrl = store.resolveBaseUrl(); + process.stderr.write("Generating CLI access token... "); + const resp = await generateCLIAccessToken({ + identity, + settings, + baseUrl: resolvedBaseUrl, + accessKeyId: flags.accessKeyId!, + accessKeySecret: flags.accessKeySecret!, + }); + console.log(resp); + process.stderr.write("Done\n"); + const accessToken = + typeof resp.Data?.AccessToken === "string" ? resp.Data.AccessToken : undefined; await store.login({ access_key_id: flags.accessKeyId, access_key_secret: flags.accessKeySecret, + access_token: accessToken, }); process.stderr.write(`OpenAPI credentials saved to ${getConfigPath()}\n`); return;