/
login.ts
100 lines (88 loc) · 3.09 KB
/
login.ts
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
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import opener from 'opener';
import { AuthorizationCode } from 'simple-oauth2';
import AuthClient from '../app-config/auth';
import BaseCommand from '../base-command';
import { RequiresDocker } from '../common/docker/helper';
import PortUtil from '../common/utils/port';
import PromptUtils from '../common/utils/prompt-utils';
import inquirer = require('inquirer');
import { ArchitectError } from '../dependency-manager/utils/errors';
export default class Login extends BaseCommand {
async auth_required(): Promise<boolean> {
return false;
}
static description = 'Login to the Architect Cloud platform';
static examples = [
'architect login',
'architect login -e my-email-address@my-email-domain.com',
];
static flags = {
...BaseCommand.flags,
email: Flags.string({
char: 'e',
description: 'Email',
env: 'ARCHITECT_EMAIL',
}),
password: Flags.string({
char: 'p',
description: 'Password',
env: 'ARCHITECT_PASSWORD',
}),
};
@RequiresDocker() // docker is required for login because we run `docker login`
async run(): Promise<void> {
const { flags } = await this.parse(Login);
if (flags.email || flags.password) {
await this.runCliFlow(flags);
} else {
await this.runBrowserFlow();
}
this.log(chalk.green('Login successful'));
}
private async runBrowserFlow() {
if (!PromptUtils.promptsAvailable()) {
throw new ArchitectError('We detected that this environment does not have a prompt available. To login in a non-tty environment, please use both the user and password options: `architect login -e <email> -p <password>`');
}
const port = await PortUtil.getAvailablePort(60000);
const auth_client: AuthorizationCode<'client_id'> = this.app.auth.getAuthClient();
const authorization_uri: string = auth_client.authorizeURL({
redirect_uri: `http://localhost:${port}`,
scope: AuthClient.SCOPE,
state: Buffer.from(Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)).toString('base64'),
});
try {
this.log('To login, please navigate to the following URL in your browser:');
this.log('\n');
this.log(`\t${authorization_uri}`);
opener(authorization_uri);
} catch (err) {
// do nothing if opener fails
}
await this.app.auth.loginFromBrowser(port, auth_client);
}
private async runCliFlow(flags: any) {
let answers = await inquirer.prompt([
{
type: 'input',
name: 'email',
default: flags.email,
when: !flags.email,
ciMessage: '--email flag is required in CI pipelines or by setting ARCHITECT_EMAIL env',
},
{
type: 'password',
name: 'password',
default: flags.password,
when: !flags.password,
ciMessage: '--password flag is required in CI pipelines or by setting ARCHITECT_PASSWORD env',
},
]);
answers = {
...flags,
...answers,
};
await this.app.auth.loginFromCli(answers.email, answers.password);
}
}