switch-profile 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -94
- package/dist/cli.js +7921 -0
- package/index.js +12 -409
- package/package.json +31 -25
- package/.eslintrc.json +0 -39
- package/CHANGELOG.md +0 -120
- package/docs/architecture.md +0 -199
- package/docs/aws-profile-management.md +0 -325
- package/docs/cli-interface.md +0 -304
- package/docs/configuration-files.md +0 -240
- package/docs/development-guide.md +0 -168
- package/docs/gotchas.md +0 -82
- package/skills-lock.json +0 -73
- package/src/aws/index.js +0 -574
- package/src/aws/regions.js +0 -103
- package/src/core.js +0 -64
- package/src/fileHelper.js +0 -433
package/docs/architecture.md
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
This document describes the project structure, source files, and how the components fit together.
|
|
4
|
-
|
|
5
|
-
## Project Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
switch-profile/
|
|
9
|
-
├── index.js # CLI entry point (executable)
|
|
10
|
-
├── package.json # Project manifest
|
|
11
|
-
├── CHANGELOG.md # Auto-generated release notes
|
|
12
|
-
├── LICENSE # BSD 3-Clause
|
|
13
|
-
├── src/
|
|
14
|
-
│ ├── core.js # Shell execution and error formatting
|
|
15
|
-
│ ├── fileHelper.js # File system operations
|
|
16
|
-
│ └── aws/
|
|
17
|
-
│ ├── index.js # AWS profile and credential management
|
|
18
|
-
│ └── regions.js # AWS region definitions
|
|
19
|
-
└── test/
|
|
20
|
-
└── index.js # Test suite
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Component Overview
|
|
24
|
-
|
|
25
|
-
### `index.js` - CLI Entry Point
|
|
26
|
-
|
|
27
|
-
The main executable file (with `#!/usr/bin/env node` shebang). Registered as the `bin` target in `package.json`, so it runs when you invoke `switch-profile` or `npx switch-profile`.
|
|
28
|
-
|
|
29
|
-
**Responsibilities:**
|
|
30
|
-
- Defines the CLI command structure using [Commander.js](https://www.npmjs.com/package/commander).
|
|
31
|
-
- Renders interactive prompts using [Inquirer.js](https://www.npmjs.com/package/inquirer).
|
|
32
|
-
- Orchestrates the user flow: profile listing, selection, creation, deletion, and refresh.
|
|
33
|
-
- Displays colored status output (expiry warnings, success messages).
|
|
34
|
-
|
|
35
|
-
**Key functions:**
|
|
36
|
-
|
|
37
|
-
| Function | Purpose |
|
|
38
|
-
|----------|---------|
|
|
39
|
-
| `switchCmd()` | Main command handler. Checks AWS CLI, shows current profile status, lists profiles, renders the selection menu. |
|
|
40
|
-
| `setProfileToDefault(name, list, msg)` | Gets credentials for a profile, writes them as the `[default]` profile. Shows a clear error if the profile is not found in the list. Displays the `export AWS_PROFILE` hint on success. |
|
|
41
|
-
| `printExportHint(profileName)` | Displays a cyan box with the profile isolation command. On Linux/macOS shows `export AWS_PROFILE=<name>`. On Windows shows both PowerShell (`$env:AWS_PROFILE`) and CMD (`set AWS_PROFILE`) variants. Box width adjusts dynamically. |
|
|
42
|
-
| `createNewProfile(profiles, makeItDefault)` | Walks the user through creating a standard or SSO profile. Displays an SSO Setup Guide before SSO creation and checks for errors before reporting success. |
|
|
43
|
-
| `chooseProfileName(denyList)` | Validates profile name input (lowercase alphanumeric, dashes, underscores, min 2 chars, no duplicates). |
|
|
44
|
-
| `chooseRegions()` | Autocomplete region picker from the 24 supported AWS regions. |
|
|
45
|
-
| `chooseNonEmpty(prop, message)` | Generic required-field input validator. |
|
|
46
|
-
|
|
47
|
-
**Default command behavior:** If no command is passed (`process.argv.length == 2`), it automatically injects the `switch` command.
|
|
48
|
-
|
|
49
|
-
### `src/aws/index.js` - AWS Profile Management
|
|
50
|
-
|
|
51
|
-
The core module. Handles all interactions with AWS configuration files and the AWS CLI.
|
|
52
|
-
|
|
53
|
-
**Responsibilities:**
|
|
54
|
-
- Reading and writing `~/.aws/config` and `~/.aws/credentials`.
|
|
55
|
-
- Parsing INI-style profile sections.
|
|
56
|
-
- Managing SSO sessions and credential caching.
|
|
57
|
-
- Creating, deleting, and listing profiles.
|
|
58
|
-
- Refreshing expired SSO sessions (including browser redirect).
|
|
59
|
-
|
|
60
|
-
**Windows compatibility:** Uses `IS_WINDOWS` (`process.platform === 'win32'`) to select platform-appropriate line separator for parsing (`LINE_SEP`: regex `/\r?\n/` on Windows, `os.EOL` otherwise), newline character for writing (`NL`: `'\n'` on Windows, `os.EOL` otherwise), and `shell: true` for `spawn` on Windows (required because `aws` is a `.cmd` batch file).
|
|
61
|
-
|
|
62
|
-
See [AWS Profile Management](aws-profile-management.md) for a detailed breakdown of every function.
|
|
63
|
-
|
|
64
|
-
### `src/aws/regions.js` - Region Definitions
|
|
65
|
-
|
|
66
|
-
A static array of 24 AWS region objects, each with `name` and `code` properties:
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
{ name: 'US East (N. Virginia)', code: 'us-east-1' }
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Regions covered: 4 US, 8 Asia Pacific, 6 EU, 2 China, 2 GovCloud, 1 Africa, 1 Canada, 1 Middle East, 1 South America.
|
|
73
|
-
|
|
74
|
-
### `src/core.js` - Shell Execution and Error Formatting
|
|
75
|
-
|
|
76
|
-
Low-level utilities shared across the project.
|
|
77
|
-
|
|
78
|
-
| Function | Purpose |
|
|
79
|
-
|----------|---------|
|
|
80
|
-
| `exec(cmd)` | Wraps `child_process.exec()` in a Promise. Rejects on error or stderr. |
|
|
81
|
-
| `isCommandExist(cmd, errorMsg)` | Returns a function that checks if `cmd` exists in PATH (uses `which` on Unix, `where` on Windows). Results are cached. |
|
|
82
|
-
| `printErrors(errors, options)` | Prints an array of `Error` objects in red. |
|
|
83
|
-
| `printAWSerrors(errors, options)` | Like `printErrors` but detects missing AWS CLI and appends installation hints. |
|
|
84
|
-
| `formatErrorMsg(errors, options)` | Formats error arrays into a single message string. Supports `noStack` option. |
|
|
85
|
-
|
|
86
|
-
### `src/fileHelper.js` - File System Operations
|
|
87
|
-
|
|
88
|
-
A general-purpose file I/O library. Only a subset of its functions are used by `switch-profile`:
|
|
89
|
-
|
|
90
|
-
**Used by the project:**
|
|
91
|
-
|
|
92
|
-
| Function | Exported As | Purpose |
|
|
93
|
-
|----------|-------------|---------|
|
|
94
|
-
| `fileExists(path)` | `exists` | Check if a file or folder exists |
|
|
95
|
-
| `readFile(path)` | `read` | Read file contents into a Buffer |
|
|
96
|
-
| `writeToFile(path, content, opts)` | `write` | Create or overwrite a file |
|
|
97
|
-
| `listFiles(folder, opts)` | `list` | Glob-based file listing |
|
|
98
|
-
| `getJSON(path, default)` | `json.get` | Read and parse a JSON file |
|
|
99
|
-
|
|
100
|
-
**Available but unused:**
|
|
101
|
-
|
|
102
|
-
Functions for folder creation/deletion, MIME type detection, ZIP/TAR archiving, and more. These exist because `fileHelper.js` is a shared utility library.
|
|
103
|
-
|
|
104
|
-
## Dependency Graph
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
index.js
|
|
108
|
-
├── commander (CLI framework)
|
|
109
|
-
├── inquirer (interactive prompts)
|
|
110
|
-
├── inquirer-autocomplete-prompt
|
|
111
|
-
├── colors (terminal colors)
|
|
112
|
-
├── src/core.js
|
|
113
|
-
│ ├── colors
|
|
114
|
-
│ ├── puffy (error handling: catchErrors, wrapErrors)
|
|
115
|
-
│ └── child_process (Node built-in)
|
|
116
|
-
├── src/aws/index.js
|
|
117
|
-
│ ├── puffy (error handling + delay)
|
|
118
|
-
│ ├── src/core.js
|
|
119
|
-
│ ├── src/fileHelper.js
|
|
120
|
-
│ │ ├── core-async (co-routine support)
|
|
121
|
-
│ │ ├── fast-glob (file pattern matching)
|
|
122
|
-
│ │ ├── rimraf (recursive delete)
|
|
123
|
-
│ │ ├── mime-types (MIME detection)
|
|
124
|
-
│ │ ├── archiver (ZIP creation - unused)
|
|
125
|
-
│ │ ├── tar-stream (TAR creation - unused)
|
|
126
|
-
│ │ └── convert-stream (stream utils - unused)
|
|
127
|
-
│ ├── src/aws/regions.js
|
|
128
|
-
│ └── child_process (for spawn)
|
|
129
|
-
└── package.json (version number)
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Error Handling Pattern
|
|
133
|
-
|
|
134
|
-
All async functions in the AWS module use the `catchErrors` wrapper from the `puffy` library. This converts thrown errors into a `[errors, result]` tuple:
|
|
135
|
-
|
|
136
|
-
```javascript
|
|
137
|
-
const [errors, profiles] = await listProfiles()
|
|
138
|
-
if (errors) {
|
|
139
|
-
printAWSerrors([new Error('Fail to list profiles'), ...errors])
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
// Use profiles safely
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Errors are composed using `wrapErrors(message, errorArray)` to build layered error contexts:
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
Error: Fail to get credentials for profile sso-dev
|
|
149
|
-
→ Error: Fail to refresh the SSO session
|
|
150
|
-
→ Error: Timeout - Time to wait exceeded 300000ms
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
This pattern allows errors to propagate up with context while keeping individual functions simple.
|
|
154
|
-
|
|
155
|
-
## Data Flow
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
User runs: npx switch-profile
|
|
159
|
-
│
|
|
160
|
-
▼
|
|
161
|
-
┌──────────────┐
|
|
162
|
-
│ index.js │ Checks AWS CLI v2 exists
|
|
163
|
-
│ switchCmd() │ Gets default profile + status
|
|
164
|
-
│ │ Lists all profiles
|
|
165
|
-
└──────┬───────┘
|
|
166
|
-
│
|
|
167
|
-
▼
|
|
168
|
-
User selects a profile
|
|
169
|
-
│
|
|
170
|
-
▼
|
|
171
|
-
┌──────────────────────┐
|
|
172
|
-
│ setProfileToDefault │
|
|
173
|
-
│ │
|
|
174
|
-
│ 1. Find profile │
|
|
175
|
-
│ 2. Get credentials │──────► For SSO: refresh session,
|
|
176
|
-
│ 3. Update default │ open browser if needed
|
|
177
|
-
└──────────────────────┘
|
|
178
|
-
│
|
|
179
|
-
▼
|
|
180
|
-
┌──────────────────────┐
|
|
181
|
-
│ updateDefaultProfile│
|
|
182
|
-
│ │
|
|
183
|
-
│ Writes [default] │
|
|
184
|
-
│ section to: │
|
|
185
|
-
│ - ~/.aws/credentials│
|
|
186
|
-
│ - ~/.aws/config │
|
|
187
|
-
└──────────────────────┘
|
|
188
|
-
│
|
|
189
|
-
▼
|
|
190
|
-
┌──────────────────────┐
|
|
191
|
-
│ printExportHint │
|
|
192
|
-
│ │
|
|
193
|
-
│ Shows: │
|
|
194
|
-
│ export AWS_PROFILE= │
|
|
195
|
-
│ <name> │
|
|
196
|
-
│ for per-terminal │
|
|
197
|
-
│ isolation │
|
|
198
|
-
└──────────────────────┘
|
|
199
|
-
```
|
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
# AWS Profile Management
|
|
2
|
-
|
|
3
|
-
This document explains how `switch-profile` manages AWS profiles, SSO sessions, and credentials internally.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
All profile and credential logic lives in `src/aws/index.js`. This module directly reads and writes AWS configuration files using regex-based INI parsing - it does not shell out to `aws configure` for most operations.
|
|
8
|
-
|
|
9
|
-
## File Locations
|
|
10
|
-
|
|
11
|
-
| Path | Purpose | Managed By |
|
|
12
|
-
|------|---------|------------|
|
|
13
|
-
| `~/.aws/config` | Profile settings (region, output, SSO metadata) | `switch-profile` + `aws configure sso` |
|
|
14
|
-
| `~/.aws/credentials` | Access keys, secrets, session tokens | `switch-profile` |
|
|
15
|
-
| `~/.aws/sso/cache/` | SSO session tokens (JSON files) | AWS CLI |
|
|
16
|
-
| `~/.aws/cli/cache/` | Temporary SSO credentials (JSON files) | AWS CLI |
|
|
17
|
-
|
|
18
|
-
## Constants
|
|
19
|
-
|
|
20
|
-
```javascript
|
|
21
|
-
SSO_GET_CREDS_TIMEOUT = 300000 // 5 minutes to complete SSO login
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Functions Reference
|
|
25
|
-
|
|
26
|
-
### Profile Listing
|
|
27
|
-
|
|
28
|
-
#### `listProfiles()`
|
|
29
|
-
|
|
30
|
-
Reads `~/.aws/config` and extracts all profile sections except `[default]`.
|
|
31
|
-
|
|
32
|
-
**Returns:** `[errors, profiles[]]`
|
|
33
|
-
|
|
34
|
-
Each profile object contains:
|
|
35
|
-
|
|
36
|
-
```javascript
|
|
37
|
-
{
|
|
38
|
-
name: 'sso-dev', // Profile name
|
|
39
|
-
friendlyName: 'sso-dev (SSO [role:Admin - account:123456])', // Display name
|
|
40
|
-
region: 'us-east-1', // AWS region
|
|
41
|
-
output: 'json', // Output format
|
|
42
|
-
sso_start_url: 'https://my.awsapps.com/start', // null if not SSO
|
|
43
|
-
sso_region: 'us-east-1', // null if not SSO
|
|
44
|
-
sso_account_id: '123456789012', // null if not SSO
|
|
45
|
-
sso_role_name: 'Admin', // null if not SSO
|
|
46
|
-
sso_session: 'my-session' // null if not using SSO sessions (legacy SSO format)
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Parsing logic:**
|
|
51
|
-
1. Matches all `[...]` sections in the config file.
|
|
52
|
-
2. For each section, extracts the content between it and the next `[` bracket.
|
|
53
|
-
3. Splits content by newline and extracts key-value pairs using `getParam()`.
|
|
54
|
-
4. Strips `[profile ...]` prefix to get the profile name.
|
|
55
|
-
5. For newer SSO profiles using `sso_session`, looks up the `[sso-session name]` section to retrieve `sso_start_url` and `sso_region`.
|
|
56
|
-
6. For SSO profiles, uses `sso_region` as the effective region.
|
|
57
|
-
7. Builds a `friendlyName` that includes role and account info for SSO profiles.
|
|
58
|
-
|
|
59
|
-
#### `getDefaultProfile()`
|
|
60
|
-
|
|
61
|
-
Reads the `[default]` section from `~/.aws/credentials`.
|
|
62
|
-
|
|
63
|
-
**Returns:** `[errors, profile]`
|
|
64
|
-
|
|
65
|
-
```javascript
|
|
66
|
-
{
|
|
67
|
-
aws_access_key_id: 'AKIA...',
|
|
68
|
-
aws_secret_access_key: '...',
|
|
69
|
-
aws_session_token: '...', // null for standard profiles
|
|
70
|
-
expiry_date: '2021-07-17...', // null for standard profiles
|
|
71
|
-
profile: 'sso-dev' // Which profile these creds belong to
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
The `profile` and `expiry_date` fields are custom additions by `switch-profile` - they are not standard AWS CLI fields. They are written into the credentials file so the tool can track which profile is currently active and when it expires.
|
|
76
|
-
|
|
77
|
-
### Credential Retrieval
|
|
78
|
-
|
|
79
|
-
#### `getCredentials(profile, ssoUrl)`
|
|
80
|
-
|
|
81
|
-
The main credential retrieval function. Behaves differently for SSO vs. standard profiles.
|
|
82
|
-
|
|
83
|
-
**For SSO profiles** (when `ssoUrl` is provided):
|
|
84
|
-
|
|
85
|
-
1. Calls `refreshSsoSession()` to ensure a valid SSO session exists.
|
|
86
|
-
2. Calls `getSsoCredentials()` to get temporary AWS credentials via the CLI cache.
|
|
87
|
-
3. If credentials fail with "session associated with this profile has expired", forces a session refresh and retries.
|
|
88
|
-
4. If `getSsoCredentials()` returns `null` (cache-based lookup failed), falls back to `aws configure export-credentials --profile <name> --format process` which directly outputs credentials as JSON.
|
|
89
|
-
5. If both approaches fail, throws an error.
|
|
90
|
-
|
|
91
|
-
**For standard profiles** (when `ssoUrl` is null):
|
|
92
|
-
|
|
93
|
-
1. Reads `~/.aws/credentials`.
|
|
94
|
-
2. Finds the `[profile-name]` section.
|
|
95
|
-
3. Extracts `aws_access_key_id`, `aws_secret_access_key`, and `aws_session_token`.
|
|
96
|
-
|
|
97
|
-
**Returns:** `[errors, { aws_access_key_id, aws_secret_access_key, aws_session_token, expiry_date }]`
|
|
98
|
-
|
|
99
|
-
#### `getSsoCredentials(profile)`
|
|
100
|
-
|
|
101
|
-
Gets SSO credentials by running `aws configure list --profile <profile>`, which triggers the AWS CLI to populate its credential cache.
|
|
102
|
-
|
|
103
|
-
**Process:**
|
|
104
|
-
1. Executes `aws configure list --profile <profile>`.
|
|
105
|
-
2. Parses the output to extract the last 4 characters of the access key and secret key (the CLI masks them as `****XXXX`).
|
|
106
|
-
3. Calls `getSsoCredsFromCacheFile()` to find the full credentials in the CLI cache.
|
|
107
|
-
|
|
108
|
-
**Returns:** `[errors, creds]` or `[errors, null]` if credentials not found.
|
|
109
|
-
|
|
110
|
-
#### `getSsoCredsFromCacheFile(access_key_end, secret_key_end)`
|
|
111
|
-
|
|
112
|
-
Searches `~/.aws/cli/cache/` for a JSON file containing credentials that match the given key suffixes.
|
|
113
|
-
|
|
114
|
-
**Matching criteria:**
|
|
115
|
-
- `ProviderType` must be `"sso"`.
|
|
116
|
-
- `Credentials.Expiration` must be at least 2 minutes in the future.
|
|
117
|
-
- Last 4 characters of `AccessKeyId` must match `access_key_end`.
|
|
118
|
-
- Last 4 characters of `SecretAccessKey` must match `secret_key_end`.
|
|
119
|
-
|
|
120
|
-
**Returns:** `[errors, creds]` or `[errors, null]` if no match found.
|
|
121
|
-
|
|
122
|
-
### SSO Session Management
|
|
123
|
-
|
|
124
|
-
#### `getSsoSession(ssoUrl)`
|
|
125
|
-
|
|
126
|
-
Finds a valid SSO session token in `~/.aws/sso/cache/`.
|
|
127
|
-
|
|
128
|
-
**Process:**
|
|
129
|
-
1. Extracts the host from `ssoUrl` (e.g., `my.awsapps.com`).
|
|
130
|
-
2. Lists all `*.json` files in `~/.aws/sso/cache/`.
|
|
131
|
-
3. For each file, checks if:
|
|
132
|
-
- `startUrl` host matches the SSO URL host.
|
|
133
|
-
- `expiresAt` is at least 2 minutes in the future.
|
|
134
|
-
- `accessToken` is present.
|
|
135
|
-
|
|
136
|
-
**Returns:** `[errors, session]` or `[errors, null]` if no valid session found.
|
|
137
|
-
|
|
138
|
-
#### `isSSOexpired(ssoSession)`
|
|
139
|
-
|
|
140
|
-
Checks if an SSO session will expire within the next 2 minutes.
|
|
141
|
-
|
|
142
|
-
**Returns:** `boolean`
|
|
143
|
-
|
|
144
|
-
#### `refreshSsoSession(profile, ssoUrl, options)`
|
|
145
|
-
|
|
146
|
-
Ensures a valid SSO session exists. If not, triggers a new SSO login.
|
|
147
|
-
|
|
148
|
-
**Process:**
|
|
149
|
-
1. Check for existing valid session via `getSsoSession()`.
|
|
150
|
-
2. If expired or `options.force` is true:
|
|
151
|
-
- Runs `aws sso login --profile <profile>` (opens browser).
|
|
152
|
-
- Polls `getSsoSession()` every 2 seconds.
|
|
153
|
-
- Waits up to 5 minutes (`SSO_GET_CREDS_TIMEOUT`) for the session to appear.
|
|
154
|
-
3. Returns the session object, or throws a timeout error.
|
|
155
|
-
|
|
156
|
-
### Profile Modification
|
|
157
|
-
|
|
158
|
-
#### `updateDefaultProfile({ profile, region, expiry_date, aws_access_key_id, aws_secret_access_key, aws_session_token })`
|
|
159
|
-
|
|
160
|
-
Updates the `[default]` section in both `~/.aws/credentials` and `~/.aws/config`.
|
|
161
|
-
|
|
162
|
-
**In `~/.aws/credentials`:**
|
|
163
|
-
```ini
|
|
164
|
-
[default]
|
|
165
|
-
aws_access_key_id = AKIA...
|
|
166
|
-
aws_secret_access_key = ...
|
|
167
|
-
aws_session_token = ... # Only for SSO profiles
|
|
168
|
-
expiry_date = 2021-07-17T... # Only for SSO profiles
|
|
169
|
-
profile = sso-dev # Custom field: tracks active profile
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**In `~/.aws/config`:**
|
|
173
|
-
```ini
|
|
174
|
-
[default]
|
|
175
|
-
region = us-east-1
|
|
176
|
-
output = json
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Approach:** Uses regex to find the existing `[default]` section and replaces it. If no `[default]` section exists, prepends it. All other profile sections are preserved unchanged.
|
|
180
|
-
|
|
181
|
-
#### `createProfile({ name, aws_access_key_id, aws_secret_access_key, region })`
|
|
182
|
-
|
|
183
|
-
Creates a standard (non-SSO) profile.
|
|
184
|
-
|
|
185
|
-
**Writes to `~/.aws/config`:**
|
|
186
|
-
```ini
|
|
187
|
-
[profile my-profile]
|
|
188
|
-
region = us-east-1
|
|
189
|
-
output = json
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
**Writes to `~/.aws/credentials`:**
|
|
193
|
-
```ini
|
|
194
|
-
[my-profile]
|
|
195
|
-
aws_access_key_id = AKIA...
|
|
196
|
-
aws_secret_access_key = ...
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
If the config or credentials files don't exist, they are created with a default `[default]` section first.
|
|
200
|
-
|
|
201
|
-
#### `createSsoProfile(name)`
|
|
202
|
-
|
|
203
|
-
Creates an SSO profile by spawning the interactive `aws configure sso --profile <name>` command. This hands control to the AWS CLI, which walks the user through the SSO setup (URL, region, account, role).
|
|
204
|
-
|
|
205
|
-
Uses `spawn` with `stdio: 'inherit'` so the user interacts directly with the AWS CLI process. On Windows, `shell: true` is also passed because `aws` is typically a `.cmd` batch file that requires shell resolution. Checks the exit code of the spawned process and throws an error if it is non-zero, indicating the SSO setup failed.
|
|
206
|
-
|
|
207
|
-
#### `deleteProfiles(profiles)`
|
|
208
|
-
|
|
209
|
-
Deletes one or more profiles from both `~/.aws/config` and `~/.aws/credentials`.
|
|
210
|
-
|
|
211
|
-
**Rules:**
|
|
212
|
-
- The `default` profile cannot be deleted.
|
|
213
|
-
- Uses regex matching to find and remove the profile section and everything up to the next `[` bracket.
|
|
214
|
-
|
|
215
|
-
#### `deleteProfileFromConfig(profile, fileContent)` / `deleteProfileFromCreds(profile, fileContent)`
|
|
216
|
-
|
|
217
|
-
Internal helpers that remove a single profile section from file content using regex. The config version handles both `[profile name]` and `[name]` syntax. The creds version handles `[name]` syntax only.
|
|
218
|
-
|
|
219
|
-
### AWS CLI Detection
|
|
220
|
-
|
|
221
|
-
#### `awsCliV2Exists(noFailIfMissing)`
|
|
222
|
-
|
|
223
|
-
Checks that AWS CLI v2+ is installed.
|
|
224
|
-
|
|
225
|
-
**Process:**
|
|
226
|
-
1. Runs `which aws` (or `where aws` on Windows) to check if the command exists.
|
|
227
|
-
2. Runs `aws --version` and parses the major version number.
|
|
228
|
-
3. Rejects if version is 1 or lower.
|
|
229
|
-
|
|
230
|
-
**Parameters:**
|
|
231
|
-
- `noFailIfMissing`: If `true`, returns `false` instead of throwing when AWS CLI is not found.
|
|
232
|
-
|
|
233
|
-
### Utility
|
|
234
|
-
|
|
235
|
-
#### `getParam(params, paramName)`
|
|
236
|
-
|
|
237
|
-
Extracts a parameter value from an array of lines in `key = value` format.
|
|
238
|
-
|
|
239
|
-
```javascript
|
|
240
|
-
getParam([' region = us-east-1', ' output = json'], 'region')
|
|
241
|
-
// Returns: 'us-east-1'
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
#### `getCredsFile()` / `getConfigFile()`
|
|
245
|
-
|
|
246
|
-
Reads the credentials or config file and returns its contents as a string. Returns an empty string if the file doesn't exist.
|
|
247
|
-
|
|
248
|
-
## SSO Credential Flow Diagram
|
|
249
|
-
|
|
250
|
-
```
|
|
251
|
-
User selects an SSO profile
|
|
252
|
-
│
|
|
253
|
-
▼
|
|
254
|
-
getCredentials(profile, ssoUrl)
|
|
255
|
-
│
|
|
256
|
-
▼
|
|
257
|
-
refreshSsoSession(profile, ssoUrl)
|
|
258
|
-
│
|
|
259
|
-
├── getSsoSession(ssoUrl)
|
|
260
|
-
│ │
|
|
261
|
-
│ ▼
|
|
262
|
-
│ Search ~/.aws/sso/cache/*.json
|
|
263
|
-
│ for matching, non-expired session
|
|
264
|
-
│ │
|
|
265
|
-
│ ├── Found valid session → continue
|
|
266
|
-
│ │
|
|
267
|
-
│ └── Not found or expired
|
|
268
|
-
│ │
|
|
269
|
-
│ ▼
|
|
270
|
-
│ aws sso login --profile <name>
|
|
271
|
-
│ (opens browser for SSO auth)
|
|
272
|
-
│ │
|
|
273
|
-
│ ▼
|
|
274
|
-
│ Poll ~/.aws/sso/cache/ every 2s
|
|
275
|
-
│ (up to 5 min timeout)
|
|
276
|
-
│
|
|
277
|
-
▼
|
|
278
|
-
getSsoCredentials(profile)
|
|
279
|
-
│
|
|
280
|
-
▼
|
|
281
|
-
aws configure list --profile <name>
|
|
282
|
-
(populates ~/.aws/cli/cache/)
|
|
283
|
-
│
|
|
284
|
-
▼
|
|
285
|
-
getSsoCredsFromCacheFile(keyEnd, secretEnd)
|
|
286
|
-
│
|
|
287
|
-
▼
|
|
288
|
-
Search ~/.aws/cli/cache/*.json
|
|
289
|
-
for matching credentials
|
|
290
|
-
│
|
|
291
|
-
├── Found → return credentials
|
|
292
|
-
│
|
|
293
|
-
└── Not found (null)
|
|
294
|
-
│
|
|
295
|
-
▼
|
|
296
|
-
Fallback: aws configure export-credentials
|
|
297
|
-
--profile <name> --format process
|
|
298
|
-
(directly outputs credentials as JSON)
|
|
299
|
-
│
|
|
300
|
-
├── Success → return credentials
|
|
301
|
-
│
|
|
302
|
-
└── Failure → throw error
|
|
303
|
-
│
|
|
304
|
-
▼
|
|
305
|
-
Return { aws_access_key_id,
|
|
306
|
-
aws_secret_access_key,
|
|
307
|
-
aws_session_token,
|
|
308
|
-
expiry_date }
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
## Expiry Handling
|
|
312
|
-
|
|
313
|
-
The tool uses a 2-minute buffer for expiry checks throughout. A session or credential is considered expired if it expires within the next 2 minutes:
|
|
314
|
-
|
|
315
|
-
```javascript
|
|
316
|
-
const credStillValid = (Date.now() - 2*60*1000) < new Date(expiresAt).getTime()
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
This prevents credentials from expiring between the time they're fetched and the time they're used.
|
|
320
|
-
|
|
321
|
-
## Profile Name Conventions
|
|
322
|
-
|
|
323
|
-
- In `~/.aws/config`: Non-default profiles use `[profile name]` syntax. The default uses `[default]`.
|
|
324
|
-
- In `~/.aws/credentials`: All profiles use `[name]` syntax (no `profile` prefix).
|
|
325
|
-
- Profile names must be: lowercase alphanumeric characters, dashes, and underscores. Minimum 2 characters.
|