UNPKG

5.96 kBJavaScriptView Raw
1const ini = require('ini')
2const chalk = require('chalk')
3const fs = require('fs-extra')
4const fsOpts = { encoding: 'utf8' }
5const verifyAccess = require('../login/verify-aws-access')
6const { indent, bulletize } = require('./indent-bullet')
7const indent2 = indent.bind(null, 2)
8
9const lsCred = 'ls -l ~/.aws/credentials'
10const catCred = 'cat ~/.aws/credentials'
11const chmodCred = 'chmod 644 ~/.aws/credentials'
12const chownCred = 'sudo chown `whoami` ~/.aws/credentials'
13
14const credFormat = `[default]
15aws_access_key_id = ALPHANUMERIC20CHARS1
16aws_secret_access_key = ALPHANUMERICand+and/and40charactersEXACT`
17const logCred = `Log the contents of your credentials file with the following command:
18 ${chalk.italic.gray(catCred)}`
19const awsFail = 'Connection to AWS S3 failed'
20const badCreds = `Check the internet connection and then confirm the
21AWS access ID and secret in ~/.aws/credentials are correct.`
22const newCreds = chalk`To enter new credentials, run {italic.gray blink login}`
23const noCredFile = `The credentials file was not found
24The AWS Access Key Id and AWS Secret Access Key should be
25included in a file named "credentials" located at ~/.aws/`
26const writePermissions = 'No write permissions for the AWS credentials file located at ~/.aws/'
27const readPermissions = 'No read permissions for the AWS credentials file located at ~/.aws/'
28const logCredPerm = `Check permission with the following command:
29 ${chalk.italic.gray(lsCred)}`
30const fixPermissions = `If the user shows as 'root' and/or not your username, try the following:
31 ${chalk.italic.gray(chownCred)}
32If the file permissions do not match "-rw-r--r--", try the following:
33 ${chalk.italic.gray(chmodCred)}`
34const credAccess = 'There is a problem accessing the AWS credentials file located at ~/.aws/'
35const credParse = `Could not parse the AWS credentials file located at ~/.aws/
36Check the formatting of the file contents`
37const credDefault = `The AWS credentials file is missing the default profile
38Add the default profile to the credentials file located at ~/.aws/
39or run "blink login" and provide a valid AWS access ID and secret`
40const noAwsId = `There is no key "aws_access_key_id" for the default profile or it is
41not assigned a value in the credentials file located at ~/.aws/`
42const awsIdLength = 'The aws_access_key_id must be exactly 20 characters long, yours is'
43const awsIdChars = 'The aws_access_key_id must only contain alphanumeric characters'
44const noAwsSecret = `There is no key "aws_secret_access_key" for the default profile or it is
45not assigned a value in the credentials file located at ~/.aws/`
46const awsSecretLength = 'The aws_secret_access_key must be exactly 40 characters long, yours is'
47const awsSecretChars = 'The aws_secret_access_key must only contain numbers, letters, +, and /'
48const loginFix = chalk`Run {italic.gray blink login} and provide a valid AWS access ID and secret`
49const permFormat = `Output should resemble the following:
50[permissions] [links] [user] ...`
51
52module.exports = async ({ env }) => {
53 const warnings = []
54 const credPath = `${env.home}/.aws/credentials`
55 // check write permissions of AWS credentials file
56 try {
57 await fs.access(credPath, fs.constants.W_OK)
58 } catch (err) {
59 if (err.code === 'EACCES') warnings.push(`${writePermissions}\n${indent2(`${logCredPerm}\n${permFormat}\n${fixPermissions}`)}`)
60 }
61 // check S3 access
62 try {
63 await verifyAccess()
64 } catch (err) {
65 let bullets = []
66 // check read permissions of AWS credentials file
67 try {
68 const data = await fs.readFile(credPath, fsOpts)
69 // parse credentials file
70 try {
71 const config = ini.parse(data)
72 // check for default profile
73 if (!config.default || typeof config.default !== 'object') {
74 bullets.push(`${credDefault}\nExample file contents:\n${indent2(credFormat)}\n${logCred}`)
75 } else {
76 const contentErrors = []
77 const creds = config.default
78 // check aws_access_key_id
79 if (!creds.aws_access_key_id || typeof creds.aws_access_key_id !== 'string') {
80 contentErrors.push(`${noAwsId}\n${loginFix}\n${logCred}`)
81 } else {
82 if (creds.aws_access_key_id.length !== 20) {
83 contentErrors.push(`${awsIdLength} ${creds.aws_access_key_id.length}\n${loginFix}\n${logCred}`)
84 }
85 if (/[^\w]/.test(creds.aws_access_key_id)) {
86 contentErrors.push(`${awsIdChars}\n${loginFix}\n${logCred}`)
87 }
88 }
89 // check aws_secret_access_key
90 if (!creds.aws_secret_access_key || typeof creds.aws_secret_access_key !== 'string') {
91 contentErrors.push(`${noAwsSecret}\n${loginFix}\n${logCred}`)
92 } else {
93 if (creds.aws_secret_access_key.length !== 40) {
94 contentErrors.push(`${awsSecretLength} ${creds.aws_secret_access_key.length}\n${loginFix}\n${logCred}`)
95 }
96 if (/[^\w/+]/.test(creds.aws_secret_access_key)) {
97 contentErrors.push(`${awsSecretChars}\n${loginFix}\n${logCred}`)
98 }
99 }
100 if (contentErrors.length) {
101 bullets = bullets.concat(contentErrors)
102 } else {
103 // no other problems detected, credentials must not be valid
104 bullets.push(`${badCreds}\n${logCred}\n${newCreds}`)
105 }
106 }
107 } catch (err) {
108 bullets.push(`${credParse}\nExample file contents:\n${indent2(credFormat)}`)
109 }
110 } catch (err) {
111 if (err.code === 'ENOENT') bullets.push(`${noCredFile}\nExample file contents:\n${indent2(credFormat)}\n${loginFix}`)
112 else if (err.code === 'EACCES') bullets.push(`${readPermissions}\n${logCredPerm}\n${permFormat}\n${fixPermissions}`)
113 else bullets.push(`${credAccess}\n${logCredPerm}\n${permFormat}\n${fixPermissions}`)
114 }
115 warnings.push(`${awsFail}\n${indent2(bullets.map(bulletize).join('\n'))}`)
116 }
117 return { warnings, details: [] }
118}