-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlogin.ts
More file actions
133 lines (114 loc) · 3.7 KB
/
login.ts
File metadata and controls
133 lines (114 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { Args, Command, Flags } from '@oclif/core';
import { printHeader, printSuccess, printError, printKV } from '../../utils/format.js';
import { writeAuthConfig } from '../../utils/auth-config.js';
import { ObjectStackClient } from '@objectstack/client';
import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';
export default class AuthLogin extends Command {
static override description = 'Authenticate and store session credentials';
static override examples = [
'$ os auth login',
'$ os auth login --url https://api.example.com',
'$ os auth login --email user@example.com --password mypassword',
];
static override flags = {
url: Flags.string({
char: 'u',
description: 'Server URL',
default: 'http://localhost:3000',
env: 'OBJECTSTACK_URL',
}),
email: Flags.string({
char: 'e',
description: 'Email address',
}),
password: Flags.string({
char: 'p',
description: 'Password',
}),
json: Flags.boolean({
description: 'Output as JSON',
}),
};
async run(): Promise<void> {
const { flags } = await this.parse(AuthLogin);
try {
if (!flags.json) {
printHeader('ObjectStack Login');
printKV('Server', flags.url);
console.log('');
}
// Prompt for credentials if not provided
let email = flags.email;
let password = flags.password;
if (!email || !password) {
const rl = readline.createInterface({ input, output });
if (!email) {
email = await rl.question('Email: ');
}
if (!password) {
// Note: This doesn't hide the password input in the terminal
// For production use, consider using a library like 'inquirer' or 'prompts'
password = await rl.question('Password: ');
}
rl.close();
}
if (!email || !password) {
throw new Error('Email and password are required');
}
// Create client and authenticate
const client = new ObjectStackClient({
baseUrl: flags.url,
});
const response = await client.auth.login({
email,
password,
});
// Check if login was successful
if (!response.data?.token && !response.data?.user) {
throw new Error('Login failed: Invalid response from server');
}
// Extract token - it might be in different locations depending on the auth system
const token = response.data?.token || (response as any).token;
const user = response.data?.user;
if (!token) {
throw new Error('Login failed: No token received from server');
}
// Store credentials
await writeAuthConfig({
url: flags.url,
token,
email: user?.email || email,
userId: user?.id,
createdAt: new Date().toISOString(),
});
if (flags.json) {
console.log(JSON.stringify({
success: true,
email: user?.email || email,
userId: user?.id,
}, null, 2));
} else {
printSuccess('Authentication successful');
printKV('Email', user?.email || email);
if (user?.id) {
printKV('User ID', user.id);
}
console.log('');
console.log(' Credentials stored in ~/.objectstack/credentials.json');
console.log('');
}
} catch (error: any) {
if (flags.json) {
console.log(JSON.stringify({
success: false,
error: error.message,
}, null, 2));
this.exit(1);
}
printError(error.message || String(error));
this.exit(1);
}
}
}