Browse Source

Made logs and logout work

master
Leo Lamprecht 8 years ago
parent
commit
fbf58ef698
  1. 32
      package-lock.json
  2. 1
      package.json
  3. 10
      src/now.js
  4. 6
      src/providers/sh/commands/bin/domains.js
  5. 121
      src/providers/sh/commands/bin/domains/buy.js
  6. 142
      src/providers/sh/commands/bin/logout.js

32
package-lock.json

@ -5089,6 +5089,12 @@
"integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=",
"dev": true
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
"dev": true
},
"lodash.merge": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz",
@ -7274,6 +7280,32 @@
"escape-string-regexp": "1.0.5"
}
},
"stripe": {
"version": "4.24.1",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-4.24.1.tgz",
"integrity": "sha512-qpNphrz1LiZHFC4twMhHlsT9MllgVKjOdvhoc0MJ3yWXWHcK1FnkgNxbACJZ9FEInx6gXs1yySm7psOZGkGCpQ==",
"dev": true,
"requires": {
"bluebird": "2.11.0",
"lodash.isplainobject": "4.0.6",
"object-assign": "4.1.1",
"qs": "6.0.4"
},
"dependencies": {
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
"dev": true
},
"qs": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.0.4.tgz",
"integrity": "sha1-UQGdhHIMk5uCc36EVWp4Izjs6ns=",
"dev": true
}
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",

1
package.json

@ -138,6 +138,7 @@
"socket.io-client": "1.7.4",
"split-array": "1.0.1",
"strip-ansi": "4.0.0",
"stripe": "4.24.1",
"tar-fs": "1.15.3",
"then-sleep": "1.0.1",
"tmp-promise": "1.0.3",

10
src/now.js

@ -1,6 +1,5 @@
#!/usr/bin/env node
//@flow
const start = Date.now()
// Native
const { join } = require('path')
@ -31,11 +30,6 @@ const NOW_AUTH_CONFIG_PATH = configFiles.getAuthConfigFilePath()
const GLOBAL_COMMANDS = new Set(['help'])
const exit = code => {
debug('finished in', Date.now() - start)
process.exit(code)
}
const main = async (argv_): Promise<number> => {
await checkForUpdates()
@ -419,4 +413,6 @@ const handleUnexpected = err => {
process.on('unhandledRejection', handleRejection)
process.on('uncaughtException', handleUnexpected)
main(process.argv).then((code: number) => exit(code)).catch(handleUnexpected)
// Don't use `.then` here. We need to shutdown gracefully, otherwise
// sub commands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv).catch(handleUnexpected)

6
src/providers/sh/commands/bin/domains.js

@ -1,8 +1,5 @@
#!/usr/bin/env node
// Native
const { resolve } = require('path')
// Packages
const chalk = require('chalk')
const minimist = require('minimist')
@ -20,6 +17,7 @@ const promptBool = require('../lib/utils/input/prompt-bool')
const strlen = require('../lib/strlen')
const toHost = require('../lib/to-host')
const { handleError, error } = require('../lib/error')
const buy = require('./domains/buy')
const help = () => {
console.log(`
@ -343,7 +341,7 @@ async function run({ token, config: { currentTeam, user } }) {
break
}
case 'buy': {
await require(resolve(__dirname, 'domains', 'buy.js'))({
await buy({
domains: domain,
args,
currentTeam,

121
src/providers/sh/commands/bin/domains/buy.js

@ -0,0 +1,121 @@
// Packages
const { italic, bold } = require('chalk')
// Utilities
const error = require('../../lib/utils/output/error')
const wait = require('../../lib/utils/output/wait')
const cmd = require('../../lib/utils/output/cmd')
const param = require('../../lib/utils/output/param')
const info = require('../../lib/utils/output/info')
const success = require('../../lib/utils/output/success')
const stamp = require('../../lib/utils/output/stamp')
const promptBool = require('../../lib/utils/input/prompt-bool')
const eraseLines = require('../../lib/utils/output/erase-lines')
const treatBuyError = require('../../lib/utils/domains/treat-buy-error')
const NowCreditCards = require('../../lib/credit-cards')
module.exports = async function({ domains, args, currentTeam, user, coupon }) {
const name = args[0]
let elapsed
if (!name) {
return error(`Missing domain name. Run ${cmd('now domains help')}`)
}
const nameParam = param(name)
let stopSpinner
let price
let period
let validCoupon
try {
if (coupon) {
stopSpinner = wait(`Validating coupon ${param(coupon)}`)
const creditCards = new NowCreditCards({
apiUrl: domains._agent._url,
token: domains._token,
debug: domains._debug,
currentTeam
})
const [couponInfo, { cards }] = await Promise.all([
domains.coupon(coupon),
creditCards.ls()
])
stopSpinner()
if (!couponInfo.isValid) {
return error(`The coupon ${param(coupon)} is invalid`)
}
if (!couponInfo.canBeUsed) {
return error(`The coupon ${param(coupon)} has already been used`)
}
validCoupon = true
if (cards.length === 0) {
info(
'You have no credit cards on file. Please add one in order to claim your free domain'
)
info(`Your card will ${bold('not')} be charged`)
await require('../now-billing-add')({
creditCards,
currentTeam,
user,
clear: true
})
}
}
elapsed = stamp()
stopSpinner = wait(`Checking availability for ${nameParam}`)
const json = await domains.price(name)
price = validCoupon ? 0 : json.price
period = json.period
} catch (err) {
stopSpinner()
return error(err.message)
}
const available = await domains.status(name)
stopSpinner()
if (!available) {
return error(
`The domain ${nameParam} is ${italic('unavailable')}! ${elapsed()}`
)
}
const periodMsg = `${period}yr${period > 1 ? 's' : ''}`
info(
`The domain ${nameParam} is ${italic('available')} to buy under ${bold(
(currentTeam && currentTeam.slug) || user.username || user.email
)}! ${elapsed()}`
)
const confirmation = await promptBool(
`Buy now for ${bold(`$${price}`)} (${periodMsg})?`
)
eraseLines(1)
if (!confirmation) {
return info('Aborted')
}
stopSpinner = wait('Purchasing')
elapsed = stamp()
try {
await domains.buy({ name, coupon })
} catch (err) {
stopSpinner()
return treatBuyError(err)
}
stopSpinner()
success(`Domain ${nameParam} purchased ${elapsed()}`)
info(
`You may now use your domain as an alias to your deployments. Run ${cmd(
'now alias --help'
)}`
)
}

142
src/providers/sh/commands/bin/logout.js

@ -0,0 +1,142 @@
#!/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 { handleError } = require('../lib/error')
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')}
`)
}
let argv
let apiUrl
let endpoint
const main = async ctx => {
argv = minimist(ctx.argv.slice(2), {
string: ['config'],
boolean: ['help'],
alias: {
help: 'h',
config: 'c'
}
})
apiUrl = argv.url || 'https://api.zeit.co'
endpoint = apiUrl + '/www/user/tokens/'
if (argv.config) {
cfg.setConfigFile(argv.config)
}
if (argv.help) {
help()
process.exit(0)
}
logout()
}
module.exports = async ctx => {
try {
await main(ctx)
} catch (err) {
handleError(err)
process.exit(1)
}
}
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!')
}
Loading…
Cancel
Save