You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.2 KiB
87 lines
2.2 KiB
import chalk from 'chalk';
|
|
import fetch from 'node-fetch';
|
|
import * as cfg from './cfg';
|
|
import { stringify as stringifyQuery } from 'querystring';
|
|
import { validate } from 'email-validator';
|
|
|
|
function readEmail ({ invalid = false } = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const decorate = invalid ? chalk.red : (v) => v;
|
|
const prompt = decorate('> Enter your email address: ');
|
|
process.stdout.write(prompt);
|
|
const data = [];
|
|
process.stdin.on('data', (d) => {
|
|
data.push(d);
|
|
if (d.indexOf('\n') > -1) {
|
|
process.stdin.pause();
|
|
resolve(Buffer.concat(data).toString().trim());
|
|
}
|
|
});
|
|
process.stdin.resume();
|
|
});
|
|
}
|
|
|
|
async function getVerificationToken (url, email) {
|
|
const data = JSON.stringify({ email });
|
|
const res = await fetch(`${url}/now/registration`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(data)
|
|
},
|
|
body: data
|
|
});
|
|
|
|
if (200 !== res.status) {
|
|
throw new Error('Verification error');
|
|
}
|
|
|
|
const body = await res.json();
|
|
return body.token;
|
|
}
|
|
|
|
async function verify (url, email, verificationToken) {
|
|
const query = {
|
|
email,
|
|
token: verificationToken
|
|
};
|
|
|
|
const res = await fetch(`${url}/now/registration/verify?${stringifyQuery(query)}`);
|
|
const body = await res.json();
|
|
return body.token;
|
|
}
|
|
|
|
function sleep (ms) {
|
|
return new Promise((resolve, reject) => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|
|
|
|
async function register (url, { retryEmail = false } = {}) {
|
|
const email = await readEmail({ invalid: retryEmail });
|
|
if (!validate(email)) return register(url, { retryEmail: true });
|
|
|
|
const verificationToken = await getVerificationToken(url, email);
|
|
|
|
console.log(`> Please follow the link sent to ${chalk.bold(email)} to log in.`);
|
|
process.stdout.write('> Waiting for confirmation..');
|
|
|
|
let final;
|
|
do {
|
|
await sleep(2500);
|
|
try {
|
|
final = await verify(url, email, verificationToken);
|
|
} catch (e) {}
|
|
process.stdout.write('.');
|
|
} while (!final);
|
|
|
|
process.stdout.write('\n');
|
|
|
|
return { email, token: final };
|
|
}
|
|
|
|
export default async function (url) {
|
|
const loginData = await register(url);
|
|
cfg.merge(loginData);
|
|
return loginData.token;
|
|
}
|
|
|