1 | const ini = require('ini')
|
2 | const promptly = require('promptly')
|
3 | const chalk = require('chalk')
|
4 | const fs = require('fs-extra')
|
5 | const fsOpts = { encoding: 'utf8' }
|
6 | const verifyAccess = require('./verify-aws-access')
|
7 |
|
8 | const printError = (type, value, msg) => {
|
9 | console.log(`⚠️ Invalid input for ${type}`)
|
10 | console.log(`You entered: ${chalk.red(value)}`)
|
11 | throw new Error(msg)
|
12 | }
|
13 |
|
14 | const validateId = (value) => {
|
15 | const type = 'aws_access_key_id'
|
16 | if (value.length !== 20) printError(type, value, `Expecting id to be 20 characters long, yours is ${value.length}`)
|
17 | if (/[^\w]/.test(value)) printError(type, value, 'Input should only contain alphanumeric characters')
|
18 | return value
|
19 | }
|
20 |
|
21 | const validateSecret = (value) => {
|
22 | const type = 'aws_secret_access_key'
|
23 | if (value.length !== 40) printError(type, value, `Expecting secret to be 40 characters long, yours is ${value.length}`)
|
24 | if (/[^\w/+]/.test(value)) printError(type, value, 'Input should only contain numbers, letters, +, and /')
|
25 | return value
|
26 | }
|
27 |
|
28 | module.exports = async ({ program, env, pkg }) => {
|
29 | const credPath = env.filepath
|
30 | await fs.ensureFile(credPath)
|
31 | const data = await fs.readFile(credPath, fsOpts)
|
32 | const config = ini.parse(data)
|
33 | if (!config) return Promise.reject(new Error('Parsing the credentials file failed'))
|
34 | if (!config.default) config.default = {}
|
35 | const id = env.id ? validateId(env.id) : await promptly.prompt('aws_access_key_id:', { validator: validateId })
|
36 | const secret = env.secret ? validateSecret(env.secret) : await promptly.prompt('aws_secret_access_key:', { validator: validateSecret })
|
37 | config.default.aws_access_key_id = id
|
38 | config.default.aws_secret_access_key = secret
|
39 |
|
40 | await verifyAccess({
|
41 | credentials: {
|
42 | accessKeyId: id,
|
43 | secretAccessKey: secret
|
44 | }
|
45 | }).catch((err) => {
|
46 |
|
47 | return Promise.reject(new Error(`Could not access AWS S3\nCode: ${err.code}\nMessage: ${err.message}`))
|
48 | })
|
49 | await fs.writeFile(credPath, ini.stringify(config, { whitespace: true }))
|
50 | }
|