From 09c3de40ccb286c35ea1b2184806e32bdd88673d Mon Sep 17 00:00:00 2001 From: Leo Lamprecht Date: Tue, 2 May 2017 11:50:21 +0200 Subject: [PATCH] Added `now logout` --- bin/now-logout.js | 126 ++++++++++++++++++++++++++++++++++++++++++++++ bin/now.js | 3 +- lib/cfg.js | 6 ++- 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 bin/now-logout.js diff --git a/bin/now-logout.js b/bin/now-logout.js new file mode 100644 index 0000000..238c9ce --- /dev/null +++ b/bin/now-logout.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node + +// Packages +const minimist = require('minimist'); +const chalk = require('chalk'); +const fetch = require('node-fetch'); +const ora = require('ora'); + +// Utilities +const cfg = require('../lib/cfg'); +const logo = require('../lib/utils/output/logo'); + +const argv = minimist(process.argv.slice(2), { + string: ['config'], + boolean: ['help'], + alias: { + help: 'h', + config: 'c' + } +}); + +const help = () => { + console.log( + ` + ${chalk.bold(`${logo} now logout`)} + + ${chalk.dim('Options:')} + + -h, --help output usage information + -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline('FILE')} config file + + ${chalk.dim('Examples:')} + + ${chalk.gray('–')} Logout from the CLI: + + ${chalk.cyan('$ now logout')} +` + ); +}; + +if (argv.help) { + help(); + process.exit(0); +} + +const apiUrl = argv.url || 'https://api.zeit.co'; +const endpoint = apiUrl + '/www/user/tokens/'; + +if (argv.config) { + cfg.setConfigFile(argv.config); +} + +const requestHeaders = token => ({ + headers: { + Authorization: `bearer ${token}` + } +}); + +const getTokenId = async token => { + const result = await fetch(endpoint, requestHeaders(token)); + const tokenList = await result.json(); + + if (!tokenList.tokens) { + return; + } + + const tokenInfo = tokenList.tokens.find(t => token === t.token); + + if (!tokenInfo) { + return; + } + + return tokenInfo.id; +}; + +const revokeToken = async (token, tokenId) => { + const details = { + method: 'DELETE' + }; + + Object.assign(details, requestHeaders(token)); + const result = await fetch(endpoint + encodeURIComponent(tokenId), details); + + if (!result.ok) { + console.error('Not able to log out'); + } +}; + +const logout = async () => { + const spinner = ora({ + text: 'Logging out...' + }).start(); + + const config = await cfg.read(); + + try { + await cfg.removeFile(); + } catch (err) { + spinner.fail(`Couldn't remove config while logging out`); + process.exit(1); + } + + let tokenId; + + try { + tokenId = await getTokenId(argv.token || config.token); + } catch (err) { + spinner.fail('Not able to get token id on logout'); + process.exit(1); + } + + if (!tokenId) { + return; + } + + try { + await revokeToken(argv.token || config.token, tokenId); + } catch (err) { + spinner.fail('Could not revoke token on logout'); + process.exit(1); + } + + spinner.succeed('Logged out!'); +}; + +logout(); diff --git a/bin/now.js b/bin/now.js index 241613b..cedf720 100755 --- a/bin/now.js +++ b/bin/now.js @@ -53,7 +53,8 @@ const commands = new Set([ 'switch', 'log', 'logs', - 'scale' + 'scale', + 'logout' ]); const aliases = new Map([ diff --git a/lib/cfg.js b/lib/cfg.js index 79cf0b5..691c0a2 100644 --- a/lib/cfg.js +++ b/lib/cfg.js @@ -97,9 +97,13 @@ async function remove(key) { fs.writeFileSync(file, JSON.stringify(cfg, null, 2)); } +// We need to remove the config file when running `now logout` +const removeFile = async () => fs.remove(file); + module.exports = { setConfigFile, read, merge, - remove + remove, + removeFile };