switch-profile 0.1.1 → 0.2.1
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/CHANGELOG.md +17 -0
- package/README.md +140 -26
- package/docs/architecture.md +185 -0
- package/docs/aws-profile-management.md +308 -0
- package/docs/cli-interface.md +267 -0
- package/docs/configuration-files.md +240 -0
- package/docs/development-guide.md +168 -0
- package/index.js +36 -2
- package/package.json +2 -2
- package/src/aws/index.js +12 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.2.1](https://github.com/nicolasdao/switch-profile/compare/v0.2.0...v0.2.1) (2026-02-08)
|
|
6
|
+
|
|
7
|
+
## [0.2.0](https://github.com/nicolasdao/switch-profile/compare/v0.1.2...v0.2.0) (2026-02-08)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* handle SSO profile creation failure and improve SSO setup UX ([b0ee837](https://github.com/nicolasdao/switch-profile/commit/b0ee83791bfbc1208cc5fb6b6f2850d4cbd160c9))
|
|
13
|
+
* vulnerabilities ([3fa2575](https://github.com/nicolasdao/switch-profile/commit/3fa2575156f3e07a6de9cd077f3f8f75f9bceafa))
|
|
14
|
+
|
|
15
|
+
### [0.1.2](https://github.com/nicolasdao/switch-profile/compare/v0.1.1...v0.1.2) (2022-05-14)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* Multiple SSO profiles are not supported. It only uses one. ([b9d9d03](https://github.com/nicolasdao/switch-profile/commit/b9d9d03b4edfa048cc157376222378513138e257))
|
|
21
|
+
|
|
5
22
|
### [0.1.1](https://github.com/nicolasdao/switch-profile/compare/v0.1.0...v0.1.1) (2021-08-03)
|
|
6
23
|
|
|
7
24
|
|
package/README.md
CHANGED
|
@@ -1,43 +1,157 @@
|
|
|
1
1
|
# switch-profile
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An interactive CLI tool for switching between AWS profiles directly from your terminal. No more manually editing `~/.aws/credentials` or juggling environment variables.
|
|
4
4
|
|
|
5
|
+
```shell
|
|
6
|
+
npx switch-profile
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Why?
|
|
10
|
+
|
|
11
|
+
AWS SSO credentials expire every hour. Without `switch-profile`, refreshing them means either:
|
|
12
|
+
|
|
13
|
+
1. **Manual copy-paste** - Browse to the SSO portal, log in, reveal credentials, paste them into your terminal or `~/.aws/credentials` file. Repeat every hour.
|
|
14
|
+
2. **Per-command `--profile` flag** - Use `aws sso login --profile <name>`, but then every command (and every tool like Terraform) needs `--profile`. Not always possible or practical.
|
|
15
|
+
|
|
16
|
+
`switch-profile` makes setting any AWS profile as `default` trivial - one command, pick from a list, done. It handles SSO session refresh automatically, including opening the browser for re-authentication when sessions expire.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- **[AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)** - Version 2 or later is required.
|
|
21
|
+
- **Node.js** - Any recent version that supports `npx`.
|
|
22
|
+
|
|
23
|
+
> **Important:** Remove these environment variables from your shell if they are set, as they override the default profile and will conflict with `switch-profile`:
|
|
24
|
+
> - `AWS_ACCESS_KEY_ID`
|
|
25
|
+
> - `AWS_SECRET_ACCESS_KEY`
|
|
26
|
+
> - `AWS_SESSION_TOKEN`
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
No installation needed. Run directly with npx:
|
|
31
|
+
|
|
32
|
+
```shell
|
|
33
|
+
npx switch-profile
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or install globally:
|
|
37
|
+
|
|
38
|
+
```shell
|
|
39
|
+
npm install -g switch-profile
|
|
40
|
+
switch-profile
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
### Switch between existing profiles
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
npx switch-profile
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This will:
|
|
52
|
+
1. Show your current default profile with its expiry status.
|
|
53
|
+
2. List all available profiles.
|
|
54
|
+
3. Let you pick one to set as the new `default`.
|
|
55
|
+
|
|
56
|
+
For SSO profiles, if the session has expired, it automatically opens your browser for re-authentication.
|
|
57
|
+
|
|
58
|
+
### Create a new profile
|
|
59
|
+
|
|
60
|
+
```shell
|
|
61
|
+
npx switch-profile
|
|
62
|
+
# Select "More options" > "Create profile"
|
|
5
63
|
```
|
|
64
|
+
|
|
65
|
+
You can create:
|
|
66
|
+
- **Standard profiles** - Access key + secret key pair.
|
|
67
|
+
- **SSO profiles** - Launches the interactive `aws configure sso` flow.
|
|
68
|
+
|
|
69
|
+
### Delete profiles
|
|
70
|
+
|
|
71
|
+
```shell
|
|
6
72
|
npx switch-profile
|
|
73
|
+
# Select "More options" > "Delete profiles"
|
|
7
74
|
```
|
|
8
75
|
|
|
9
|
-
|
|
76
|
+
Select one or more profiles to remove. The current default profile cannot be deleted (switch to another one first).
|
|
77
|
+
|
|
78
|
+
### Refresh an expired profile
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
npx switch-profile
|
|
82
|
+
# Select "More options" > "Refresh default profile"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This option only appears when the current default profile has expired. It forces a new SSO login and refreshes the credentials.
|
|
86
|
+
|
|
87
|
+
## How It Works
|
|
88
|
+
|
|
89
|
+
`switch-profile` manages two AWS configuration files:
|
|
90
|
+
|
|
91
|
+
| File | Purpose |
|
|
92
|
+
|------|---------|
|
|
93
|
+
| `~/.aws/config` | Stores profile settings (region, output format, SSO metadata) |
|
|
94
|
+
| `~/.aws/credentials` | Stores access keys, secret keys, and session tokens |
|
|
10
95
|
|
|
11
|
-
|
|
96
|
+
When you select a profile, `switch-profile`:
|
|
97
|
+
1. Retrieves the credentials for that profile (from cache or via SSO login).
|
|
98
|
+
2. Writes them into the `[default]` section of both files.
|
|
99
|
+
3. Records the profile name and expiry date for status display.
|
|
12
100
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
> - `AWS_SESSION_TOKEN`
|
|
101
|
+
For SSO profiles specifically, it leverages two additional AWS CLI cache directories:
|
|
102
|
+
- `~/.aws/sso/cache/` - SSO session tokens (long-lived, ~24 hours)
|
|
103
|
+
- `~/.aws/cli/cache/` - Temporary AWS credentials (short-lived, ~1 hour)
|
|
17
104
|
|
|
18
|
-
|
|
105
|
+
## Detailed Documentation
|
|
19
106
|
|
|
20
|
-
|
|
21
|
-
- Manually paste the short-lived credentials in the terminal:
|
|
22
|
-
- Browse to the AWS SSO login page and login.
|
|
23
|
-
- Select an account.
|
|
24
|
-
- Reveal the short-lived credentials (i.e., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN).
|
|
25
|
-
- Copy paste them in the terminal or manually edit the `.aws/credentials` file.
|
|
26
|
-
- Create an SSO profile in the terminal and update its credentials via the CLI:
|
|
27
|
-
- Creating an SSO profile: `aws configure sso`
|
|
28
|
-
- Renew a SSO credentials for a specific profile: `aws sso login --profile YOUR_PROFILE`
|
|
107
|
+
For deeper technical details, see the docs below:
|
|
29
108
|
|
|
30
|
-
|
|
109
|
+
| Document | Description |
|
|
110
|
+
|----------|-------------|
|
|
111
|
+
| [Architecture](docs/architecture.md) | Project structure, source files, and how the components fit together |
|
|
112
|
+
| [AWS Profile Management](docs/aws-profile-management.md) | How AWS profiles, SSO sessions, and credentials are managed internally |
|
|
113
|
+
| [CLI Interface](docs/cli-interface.md) | Detailed walkthrough of every menu, prompt, and user flow |
|
|
114
|
+
| [Configuration Files](docs/configuration-files.md) | Exact formats of all AWS and internal configuration files |
|
|
115
|
+
| [Development Guide](docs/development-guide.md) | How to set up, develop, test, lint, and release |
|
|
31
116
|
|
|
32
|
-
|
|
117
|
+
## Troubleshooting
|
|
33
118
|
|
|
34
|
-
|
|
119
|
+
### `invalid_grant: Invalid grant provided`
|
|
120
|
+
|
|
121
|
+
This error occurs during SSO profile creation when the **wrong SSO region** is specified. AWS SSO is region-specific - you must use the region where your SSO instance is configured, not the region you want to deploy resources to.
|
|
122
|
+
|
|
123
|
+
**Fix:** Delete the profile and recreate it with the correct SSO region.
|
|
124
|
+
|
|
125
|
+
### `Error: Fail to get credentials for profile ... Error loading SSO Token...`
|
|
126
|
+
|
|
127
|
+
This typically happens after the `~/.aws/sso/cache` folder has been deleted or corrupted. This folder tracks SSO sessions and cannot be reconstructed automatically.
|
|
128
|
+
|
|
129
|
+
**Fix:** Delete the affected SSO profiles and recreate them:
|
|
130
|
+
|
|
131
|
+
1. Run `npx switch-profile`
|
|
132
|
+
2. Select **More options** > **Delete profiles**
|
|
133
|
+
3. Remove the broken SSO profiles
|
|
134
|
+
4. Recreate them via **More options** > **Create profile**
|
|
135
|
+
|
|
136
|
+
### AWS CLI not found
|
|
137
|
+
|
|
138
|
+
`switch-profile` requires AWS CLI v2. Install it for your platform:
|
|
139
|
+
|
|
140
|
+
**macOS:**
|
|
141
|
+
```shell
|
|
142
|
+
brew install awscli
|
|
143
|
+
brew link --overwrite awscli
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Linux:**
|
|
147
|
+
```shell
|
|
148
|
+
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
|
149
|
+
unzip awscliv2.zip
|
|
150
|
+
sudo ./aws/install
|
|
151
|
+
```
|
|
35
152
|
|
|
36
|
-
|
|
37
|
-
- `Create profile`: Helps create both a standard or AWS SSO profile.
|
|
38
|
-
- `Delete profiles`: Helps cleaning one or many profiles.
|
|
39
|
-
- `Refresh default profile`: Helps refreshing the current default profile if it has expired (e.g., SSO profile). This option only appears when the default profile has expired.
|
|
153
|
+
**Windows:** Download and run the [AWS CLI MSI installer](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
|
|
40
154
|
|
|
41
|
-
|
|
155
|
+
## License
|
|
42
156
|
|
|
43
|
-
BSD 3-Clause
|
|
157
|
+
[BSD 3-Clause](LICENSE)
|
|
@@ -0,0 +1,185 @@
|
|
|
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. |
|
|
41
|
+
| `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. |
|
|
42
|
+
| `chooseProfileName(denyList)` | Validates profile name input (lowercase alphanumeric, dashes, underscores, min 2 chars, no duplicates). |
|
|
43
|
+
| `chooseRegions()` | Autocomplete region picker from the 24 supported AWS regions. |
|
|
44
|
+
| `chooseNonEmpty(prop, message)` | Generic required-field input validator. |
|
|
45
|
+
|
|
46
|
+
**Default command behavior:** If no command is passed (`process.argv.length == 2`), it automatically injects the `switch` command.
|
|
47
|
+
|
|
48
|
+
### `src/aws/index.js` - AWS Profile Management
|
|
49
|
+
|
|
50
|
+
The core module. Handles all interactions with AWS configuration files and the AWS CLI.
|
|
51
|
+
|
|
52
|
+
**Responsibilities:**
|
|
53
|
+
- Reading and writing `~/.aws/config` and `~/.aws/credentials`.
|
|
54
|
+
- Parsing INI-style profile sections.
|
|
55
|
+
- Managing SSO sessions and credential caching.
|
|
56
|
+
- Creating, deleting, and listing profiles.
|
|
57
|
+
- Refreshing expired SSO sessions (including browser redirect).
|
|
58
|
+
|
|
59
|
+
See [AWS Profile Management](aws-profile-management.md) for a detailed breakdown of every function.
|
|
60
|
+
|
|
61
|
+
### `src/aws/regions.js` - Region Definitions
|
|
62
|
+
|
|
63
|
+
A static array of 24 AWS region objects, each with `name` and `code` properties:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
{ name: 'US East (N. Virginia)', code: 'us-east-1' }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Regions covered: 4 US, 8 Asia Pacific, 6 EU, 2 China, 2 GovCloud, 1 Africa, 1 Canada, 1 Middle East, 1 South America.
|
|
70
|
+
|
|
71
|
+
### `src/core.js` - Shell Execution and Error Formatting
|
|
72
|
+
|
|
73
|
+
Low-level utilities shared across the project.
|
|
74
|
+
|
|
75
|
+
| Function | Purpose |
|
|
76
|
+
|----------|---------|
|
|
77
|
+
| `exec(cmd)` | Wraps `child_process.exec()` in a Promise. Rejects on error or stderr. |
|
|
78
|
+
| `isCommandExist(cmd, errorMsg)` | Returns a function that checks if `cmd` exists in PATH (uses `which` on Unix, `where` on Windows). Results are cached. |
|
|
79
|
+
| `printErrors(errors, options)` | Prints an array of `Error` objects in red. |
|
|
80
|
+
| `printAWSerrors(errors, options)` | Like `printErrors` but detects missing AWS CLI and appends installation hints. |
|
|
81
|
+
| `formatErrorMsg(errors, options)` | Formats error arrays into a single message string. Supports `noStack` option. |
|
|
82
|
+
|
|
83
|
+
### `src/fileHelper.js` - File System Operations
|
|
84
|
+
|
|
85
|
+
A general-purpose file I/O library. Only a subset of its functions are used by `switch-profile`:
|
|
86
|
+
|
|
87
|
+
**Used by the project:**
|
|
88
|
+
|
|
89
|
+
| Function | Exported As | Purpose |
|
|
90
|
+
|----------|-------------|---------|
|
|
91
|
+
| `fileExists(path)` | `exists` | Check if a file or folder exists |
|
|
92
|
+
| `readFile(path)` | `read` | Read file contents into a Buffer |
|
|
93
|
+
| `writeToFile(path, content, opts)` | `write` | Create or overwrite a file |
|
|
94
|
+
| `listFiles(folder, opts)` | `list` | Glob-based file listing |
|
|
95
|
+
| `getJSON(path, default)` | `json.get` | Read and parse a JSON file |
|
|
96
|
+
|
|
97
|
+
**Available but unused:**
|
|
98
|
+
|
|
99
|
+
Functions for folder creation/deletion, MIME type detection, ZIP/TAR archiving, and more. These exist because `fileHelper.js` is a shared utility library.
|
|
100
|
+
|
|
101
|
+
## Dependency Graph
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
index.js
|
|
105
|
+
├── commander (CLI framework)
|
|
106
|
+
├── inquirer (interactive prompts)
|
|
107
|
+
├── inquirer-autocomplete-prompt
|
|
108
|
+
├── colors (terminal colors)
|
|
109
|
+
├── src/core.js
|
|
110
|
+
│ ├── colors
|
|
111
|
+
│ ├── puffy (error handling: catchErrors, wrapErrors)
|
|
112
|
+
│ └── child_process (Node built-in)
|
|
113
|
+
├── src/aws/index.js
|
|
114
|
+
│ ├── puffy (error handling + delay)
|
|
115
|
+
│ ├── src/core.js
|
|
116
|
+
│ ├── src/fileHelper.js
|
|
117
|
+
│ │ ├── core-async (co-routine support)
|
|
118
|
+
│ │ ├── fast-glob (file pattern matching)
|
|
119
|
+
│ │ ├── rimraf (recursive delete)
|
|
120
|
+
│ │ ├── mime-types (MIME detection)
|
|
121
|
+
│ │ ├── archiver (ZIP creation - unused)
|
|
122
|
+
│ │ ├── tar-stream (TAR creation - unused)
|
|
123
|
+
│ │ └── convert-stream (stream utils - unused)
|
|
124
|
+
│ ├── src/aws/regions.js
|
|
125
|
+
│ └── child_process (for spawn)
|
|
126
|
+
└── package.json (version number)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Error Handling Pattern
|
|
130
|
+
|
|
131
|
+
All async functions in the AWS module use the `catchErrors` wrapper from the `puffy` library. This converts thrown errors into a `[errors, result]` tuple:
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
const [errors, profiles] = await listProfiles()
|
|
135
|
+
if (errors) {
|
|
136
|
+
printAWSerrors([new Error('Fail to list profiles'), ...errors])
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
// Use profiles safely
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Errors are composed using `wrapErrors(message, errorArray)` to build layered error contexts:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Error: Fail to get credentials for profile sso-dev
|
|
146
|
+
→ Error: Fail to refresh the SSO session
|
|
147
|
+
→ Error: Timeout - Time to wait exceeded 300000ms
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This pattern allows errors to propagate up with context while keeping individual functions simple.
|
|
151
|
+
|
|
152
|
+
## Data Flow
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
User runs: npx switch-profile
|
|
156
|
+
│
|
|
157
|
+
▼
|
|
158
|
+
┌──────────────┐
|
|
159
|
+
│ index.js │ Checks AWS CLI v2 exists
|
|
160
|
+
│ switchCmd() │ Gets default profile + status
|
|
161
|
+
│ │ Lists all profiles
|
|
162
|
+
└──────┬───────┘
|
|
163
|
+
│
|
|
164
|
+
▼
|
|
165
|
+
User selects a profile
|
|
166
|
+
│
|
|
167
|
+
▼
|
|
168
|
+
┌──────────────────────┐
|
|
169
|
+
│ setProfileToDefault │
|
|
170
|
+
│ │
|
|
171
|
+
│ 1. Find profile │
|
|
172
|
+
│ 2. Get credentials │──────► For SSO: refresh session,
|
|
173
|
+
│ 3. Update default │ open browser if needed
|
|
174
|
+
└──────────────────────┘
|
|
175
|
+
│
|
|
176
|
+
▼
|
|
177
|
+
┌──────────────────────┐
|
|
178
|
+
│ updateDefaultProfile│
|
|
179
|
+
│ │
|
|
180
|
+
│ Writes [default] │
|
|
181
|
+
│ section to: │
|
|
182
|
+
│ - ~/.aws/credentials│
|
|
183
|
+
│ - ~/.aws/config │
|
|
184
|
+
└──────────────────────┘
|
|
185
|
+
```
|