-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
actions.ts
96 lines (85 loc) · 2.53 KB
/
actions.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
import assert from 'assert';
import chalk from 'chalk';
import * as Log from '../../log';
import { ApiV2Error } from '../api';
import { CommandError } from '../errors';
import { learnMore } from '../link';
import promptAsync, { Question } from '../prompts';
import { retryUsernamePasswordAuthWithOTPAsync } from './otp';
import { Actor, getUserAsync, loginAsync } from './user';
/** Show login prompt while prompting for missing credentials. */
export async function showLoginPromptAsync({
printNewLine = false,
otp,
...options
}: {
printNewLine?: boolean;
username?: string;
password?: string;
otp?: string;
} = {}): Promise<void> {
const hasCredentials = options.username && options.password;
if (printNewLine) {
Log.log();
}
Log.log(hasCredentials ? 'Logging in to EAS' : 'Log in to EAS');
let username = options.username;
let password = options.password;
if (!hasCredentials) {
const resolved = await promptAsync(
[
!options.username && {
type: 'text',
name: 'username',
message: 'Email or username',
},
!options.password && {
type: 'password',
name: 'password',
message: 'Password',
},
].filter(Boolean) as Question<string>[],
{
nonInteractiveHelp: `Use the EXPO_TOKEN environment variable to authenticate in CI (${learnMore(
'https://docs.expo.dev/accounts/programmatic-access/'
)})`,
}
);
username = resolved.username ?? options.username;
password = resolved.password ?? options.password;
}
try {
await loginAsync({
username,
password,
otp,
});
} catch (e) {
if (e instanceof ApiV2Error && e.expoApiV2ErrorCode === 'ONE_TIME_PASSWORD_REQUIRED') {
await retryUsernamePasswordAuthWithOTPAsync(
username,
password,
e.expoApiV2ErrorMetadata as any
);
} else {
throw e;
}
}
}
/** Ensure the user is logged in, if not, prompt to login. */
export async function ensureLoggedInAsync(): Promise<Actor> {
let user = await getUserAsync().catch(() => null);
if (!user) {
Log.warn(chalk.yellow`An Expo user account is required to proceed.`);
await showLoginPromptAsync({ printNewLine: true });
user = await getUserAsync();
}
assert(user, 'User should be logged in');
return user;
}
export function ensureActorHasUsername(user: Actor): string {
if (user.__typename === 'User') {
return user.username;
}
throw new CommandError('This action is not supported for robot users.');
}