UNPKG

serverless

Version:

Serverless Framework - Build web, mobile and IoT applications with serverless architectures using AWS Lambda, Azure Functions, Google CloudFunctions & more

125 lines (117 loc) 3.84 kB
'use strict'; const { join } = require('path'); const { constants, readFile, writeFile, mkdir } = require('fs'); const os = require('os'); const BbPromise = require('bluebird'); const homedir = os.homedir(); const awsConfigDirPath = join(homedir, '.aws'); const credentialsFilePath = homedir ? join(awsConfigDirPath, 'credentials') : null; const isWindows = process.platform === 'win32'; const profileNameRe = /^\[([^\]]+)]\s*$/; const settingRe = /^([a-zA-Z0-9_]+)\s*=\s*([^\s]+)\s*$/; const settingMap = new Map([ ['aws_access_key_id', 'accessKeyId'], ['aws_secret_access_key', 'secretAccessKey'], ['aws_session_token', 'sessionToken'], ]); const parseFileProfiles = (content) => { const profiles = new Map(); let currentProfile; for (const line of content.split(/[\n\r]+/)) { const profileNameMatches = line.match(profileNameRe); if (profileNameMatches) { currentProfile = {}; profiles.set(profileNameMatches[1], currentProfile); continue; } if (!currentProfile) continue; const settingMatches = line.match(settingRe); if (!settingMatches) continue; let [, settingAwsName] = settingMatches; settingAwsName = settingAwsName.toLowerCase(); const settingName = settingMap.get(settingAwsName); if (settingName) currentProfile[settingName] = settingMatches[2]; } for (const [profileName, profileData] of profiles) { if (!profileData.sessionToken && (!profileData.accessKeyId || !profileData.secretAccessKey)) { profiles.delete(profileName); } } return profiles; }; const writeCredentialsContent = (content) => new BbPromise((resolve, reject) => writeFile( credentialsFilePath, content, !isWindows ? { mode: constants.S_IRUSR | constants.S_IWUSR } : null, (writeFileError) => { if (writeFileError) { if (writeFileError.code === 'ENOENT') { mkdir( awsConfigDirPath, !isWindows ? { mode: constants.S_IRWXU } : null, (mkdirError) => { if (mkdirError) reject(mkdirError); else resolve(writeCredentialsContent(content)); } ); } else { reject(writeFileError); } } else { resolve(); } } ) ); module.exports = { resolveFileProfiles() { return new BbPromise((resolve, reject) => { if (!credentialsFilePath) { resolve(new Map()); return; } readFile(credentialsFilePath, { encoding: 'utf8' }, (error, content) => { if (error) { if (error.code === 'ENOENT') { resolve(new Map()); return; } reject(error); return; } resolve(parseFileProfiles(content)); }); }); }, resolveEnvCredentials() { if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) return null; return { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }; }, saveFileProfiles(profiles) { return new BbPromise((resolve) => { if (!credentialsFilePath) throw new Error('Could not resolve path to user credentials file'); resolve( writeCredentialsContent( `${Array.from(profiles) .map(([name, data]) => { const lineTokens = [`[${name}]`]; if (data.sessionToken) lineTokens.push(`aws_session_token=${data.sessionToken}`); else { lineTokens.push( `aws_access_key_id=${data.accessKeyId}`, `aws_secret_access_key=${data.secretAccessKey}` ); } return `${lineTokens.join('\n')}\n`; }) .join('\n')}` ) ); }); }, };