mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
- Extended `CliAuthAttempt` with `anonRefreshToken` and a migration. - CLI `POST /auth/cli` accepts optional `anon_refresh_token` (must be an anonymous user's refresh token for the current project). - `POST /auth/cli/complete` supports `mode` `check` (anonymous vs none), `claim-anon-session` (issue tokens for the linked anonymous session), and `complete` (bind the browser session's refresh token to the attempt). Completing clears `anonRefreshToken` on the row. We do **not** merge anonymous account data into the signed-in user (that behavior was removed as a security risk; the anonymous user remains unchanged). - Template CLI confirmation page, stack-cli optional `STACK_CLI_ANON_REFRESH_TOKEN`, SDK/spec updates, and e2e coverage. <!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * CLI login supports attaching anonymous sessions and a multi-mode confirm/claim/check flow; CLI tools now surface login codes and remove anon token after use. * Added interactive CLI auth demo page and a CLI simulator script. * Client libraries: prompt flow accepts an optional anon token and a promptLink(url, loginCode) callback. * **Tests** * Expanded end-to-end coverage for anonymous CLI sessions, claim/complete/poll flows, upgrades, and error cases. * **Documentation** * Updated prompt CLI docs/spec to describe new options and callback signature. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import * as fs from "fs";
|
|
import * as path from "path";
|
|
import * as os from "os";
|
|
|
|
const CONFIG_PATH = process.env.STACK_CLI_CONFIG_PATH ?? path.join(os.homedir(), ".config", "stack-auth", "credentials.json");
|
|
|
|
type ConfigKey = "STACK_CLI_REFRESH_TOKEN" | "STACK_CLI_ANON_REFRESH_TOKEN" | "STACK_API_URL" | "STACK_DASHBOARD_URL";
|
|
|
|
function readConfigJson(): Record<string, string> {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function writeConfigJson(data: Record<string, string>): void {
|
|
fs.mkdirSync(path.dirname(CONFIG_PATH), { recursive: true });
|
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify(data, null, 2) + "\n", { mode: 0o600 });
|
|
}
|
|
|
|
export function readConfigValue(key: ConfigKey): string | undefined {
|
|
const config = readConfigJson();
|
|
return config[key];
|
|
}
|
|
|
|
export function writeConfigValue(key: ConfigKey, value: string): void {
|
|
const config = readConfigJson();
|
|
config[key] = value;
|
|
writeConfigJson(config);
|
|
}
|
|
|
|
export function removeConfigValue(key: ConfigKey): void {
|
|
const config = readConfigJson();
|
|
delete config[key];
|
|
writeConfigJson(config);
|
|
}
|