UNPKG

@liara/cli

Version:

The command line interface for Liara

180 lines (179 loc) 7.08 kB
import got from 'got'; import chalk from 'chalk'; import fs from 'fs-extra'; import retry from 'async-retry'; import inquirer from 'inquirer'; import { Flags } from '@oclif/core'; import promptEmail from 'email-prompt-ts'; import { validate as validateEmail } from 'email-validator'; import AccountUse from './use.js'; import hooks from '../../interceptors.js'; import Command from '../../base.js'; import eraseLines from '../../utils/erase-lines.js'; import { createDebugLogger } from '../../utils/output.js'; import { FALLBACK_REGION, REGIONS_API_URL, GLOBAL_CONF_PATH, GLOBAL_CONF_VERSION, } from '../../constants.js'; class AccountAdd extends Command { async run() { const { flags } = await this.parse(AccountAdd); const debug = createDebugLogger(flags.debug); const liara_json = await this.readGlobalConfig(); const currentAccounts = liara_json.accounts; const region = flags.region || FALLBACK_REGION; this.got = got.extend({ prefixUrl: REGIONS_API_URL[region], hooks }); let api_token; let fullname; let avatar; const user = flags['api-token'] ? await this.getMe(flags) : null; if (user) { flags.email = user.email; api_token = flags['api-token']; fullname = user.fullname; avatar = user.avatar; } if (!flags.email) { let emailIsValid = false; do { flags.email = await this.promptEmail(); emailIsValid = validateEmail(flags.email); if (!emailIsValid) { process.stdout.write(eraseLines(1)); } } while (!emailIsValid); this.log(); } const body = { email: await this.checkPasswordSet(flags.email), password: flags.password || (!flags['api-token'] && (await this.promptPassword())), }; if (flags['from-login']) { flags.account = `${flags.email.split('@')[0]}_${region}`; } const name = flags.account || (await this.promptName(flags.email, region)); const data = (await retry(async () => { try { if (!flags['api-token']) { const data = await this.got .post('v1/login', { json: body, headers: { Authorization: undefined }, }) .json(); return data; } } catch (error) { debug('retrying...'); throw error; } }, { retries: 3 })); const accounts = { ...currentAccounts, [name]: { email: body.email || data.email, api_token: api_token || data.api_token, region, fullname: fullname || data.fullname, avatar: avatar || data.avatar, current: false, }, }; fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify({ accounts, version: GLOBAL_CONF_VERSION })); flags['from-login'] && (await AccountUse.run(['--account', name])); const { accountName } = await this.getCurrentAccount(); this.log(`> Auth credentials saved in ${chalk.bold(GLOBAL_CONF_PATH)}`); accountName && this.log(`> Current account is: ${accountName}`); } async promptName(email, region) { const { name } = (await inquirer.prompt({ name: 'name', type: 'input', message: 'Enter an optional name for this account:', default: `${email.split('@')[0]}_${region}`, })); const liara_json = await this.readGlobalConfig(); const currentAccounts = liara_json.accounts; const currentAccountsName = currentAccounts && Object.keys(currentAccounts); return (currentAccountsName === null || currentAccountsName === void 0 ? void 0 : currentAccountsName.includes(name)) ? this.error('This name has already been used for another account. Please use a different name.') : name; } async promptEmail() { try { return await promptEmail({ start: `${chalk.green('?')} ${chalk.bold('Enter your email:')} `, }); } catch (error) { this.log(); // \n if (error.message === 'User abort') { process.stdout.write(eraseLines(2)); console.log(`${chalk.red('> Aborted!')} No changes made.`); process.exit(0); } if (error.message === 'stdin lacks setRawMode support') { this.error(`Interactive mode not supported – please run ${chalk.green('liara login --email you@domain.com --password your_password')}`); } throw error; } } async promptPassword() { const { password } = (await inquirer.prompt({ name: 'password', type: 'password', message: 'Enter your password:', validate(input) { if (input.length === 0) { return false; } return true; }, })); return password; } async getMe(flags) { const { user } = await this.got('v1/me', { headers: { Authorization: `Bearer ${flags['api-token']}` }, }).json(); return user; } async checkPasswordSet(email) { try { const { exists, socialCompleted } = await this.got .post('v1/login/check-if-exists', { json: { email } }) .json(); if (!exists) { this.error(`This email has not been registered before. Before proceeding, please sign up using the following link: https://console.liara.ir`); } if (!socialCompleted) { this.error(`This email has not yet set a password for the account. Before proceeding, please set a password using the following link: https://console.liara.ir/settings/security After setting your password, please run 'liara login' or 'liara account:add' again.`); } return email; } catch { this .error(`Checking email address failed. Please check your internet connection and try again. If the issue persists, please submit a ticket at https://console.liara.ir/tickets for further assistance.`); } } } AccountAdd.description = 'add an account'; AccountAdd.flags = { ...Command.flags, email: Flags.string({ char: 'e', description: 'your email' }), password: Flags.string({ char: 'p', description: 'your password' }), account: Flags.string({ char: 'a', description: 'account name', required: false, }), 'from-login': Flags.boolean({ required: false, hidden: true, default: false, }), }; export default AccountAdd;