login.ts79 lines · main
1import { apiCall, ApiCallError } from '../api-client.js';
2import { readCredentials, writeCredentials } from '../config.js';
3import { banner, blankLine, error as printError, step, success } from '../output.js';
4
5const DEFAULT_API_ORIGIN = 'https://api.briven.tech';
6
7interface ParsedArgs {
8 projectId?: string;
9 apiKey?: string;
10 apiOrigin: string;
11 setDefault: boolean;
12}
13
14function parse(argv: readonly string[]): ParsedArgs {
15 const out: ParsedArgs = { apiOrigin: DEFAULT_API_ORIGIN, setDefault: true };
16 for (let i = 0; i < argv.length; i++) {
17 const arg = argv[i];
18 if (arg === '--project' && argv[i + 1]) {
19 out.projectId = argv[++i];
20 } else if (arg === '--key' && argv[i + 1]) {
21 out.apiKey = argv[++i];
22 } else if (arg === '--api-origin' && argv[i + 1]) {
23 out.apiOrigin = argv[++i]!;
24 } else if (arg === '--no-default') {
25 out.setDefault = false;
26 }
27 }
28 if (process.env.BRIVEN_API_ORIGIN) out.apiOrigin = process.env.BRIVEN_API_ORIGIN;
29 return out;
30}
31
32export async function runLogin(argv: readonly string[]): Promise<number> {
33 const args = parse(argv);
34
35 if (!args.projectId || !args.apiKey) {
36 banner('login');
37 blankLine();
38 step('usage: briven login --project <p_...> --key <brk_...>');
39 step('create a key from the dashboard: /dashboard/projects/<id>/keys');
40 return 1;
41 }
42
43 if (!args.apiKey.startsWith('brk_')) {
44 printError('api key must start with brk_');
45 return 1;
46 }
47
48 banner('login');
49 step(`verifying key against ${args.apiOrigin}`);
50
51 try {
52 await apiCall(`/v1/projects/${args.projectId}/info`, {
53 apiOrigin: args.apiOrigin,
54 apiKey: args.apiKey,
55 });
56 } catch (err) {
57 if (err instanceof ApiCallError) {
58 printError(`server rejected the credentials: ${err.code}`);
59 return 1;
60 }
61 printError(err instanceof Error ? err.message : 'unknown error');
62 return 1;
63 }
64
65 const suffix = args.apiKey.slice(-4);
66 const file = await readCredentials();
67 file.projects[args.projectId] = {
68 projectId: args.projectId,
69 apiKey: args.apiKey,
70 apiOrigin: args.apiOrigin,
71 suffix,
72 createdAt: new Date().toISOString(),
73 };
74 if (args.setDefault) file.default = args.projectId;
75 await writeCredentials(file);
76
77 success(`credentials saved for ${args.projectId}`);
78 return 0;
79}