az2aws 1.3.0 → 1.4.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/CHANGELOG.md +18 -0
- package/CONTRIBUTING.md +19 -18
- package/README.md +6 -2
- package/lib/awsConfig.js +5 -0
- package/lib/configureProfileAsync.js +1 -2
- package/lib/login.js +32 -9
- package/lib/loginStates.js +10 -9
- package/package.json +9 -4
- package/.release-please-manifest.json +0 -3
- package/issue/issues.md +0 -1169
- package/release-please-config.json +0 -8
- package/vitest.config.ts +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0](https://github.com/kuma0128/az2aws/compare/v1.3.0...v1.4.0) (2026-02-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add GovCloud region warning ([#104](https://github.com/kuma0128/az2aws/issues/104)) ([1e169cc](https://github.com/kuma0128/az2aws/commit/1e169cc77c35a5453728f71952aa4201842c8430))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* honor http_proxy for browser and STS ([#92](https://github.com/kuma0128/az2aws/issues/92)) ([0e002ae](https://github.com/kuma0128/az2aws/commit/0e002ae362466cd9434bb364150bf54227738225))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Performance Improvements
|
|
17
|
+
|
|
18
|
+
* optimize keyboard input clearing with select + backspace ([#116](https://github.com/kuma0128/az2aws/issues/116)) ([84b4cfb](https://github.com/kuma0128/az2aws/commit/84b4cfbef32917a6f6d2f9ef56d5a13b09a91f3a))
|
|
19
|
+
* replace lodash with native array methods ([#115](https://github.com/kuma0128/az2aws/issues/115)) ([f61786f](https://github.com/kuma0128/az2aws/commit/f61786f0ab1f215d351fe3ddba15d22cfb048198))
|
|
20
|
+
|
|
3
21
|
## [1.3.0](https://github.com/kuma0128/az2aws/compare/v1.2.0...v1.3.0) (2026-01-27)
|
|
4
22
|
|
|
5
23
|
|
package/CONTRIBUTING.md
CHANGED
|
@@ -49,10 +49,10 @@ mise use --global node@24
|
|
|
49
49
|
node -v
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
5.
|
|
52
|
+
5. Enable pnpm via corepack:
|
|
53
53
|
|
|
54
54
|
```sh
|
|
55
|
-
|
|
55
|
+
corepack enable
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
### Setup
|
|
@@ -67,32 +67,33 @@ cd az2aws
|
|
|
67
67
|
2. Install dependencies:
|
|
68
68
|
|
|
69
69
|
```sh
|
|
70
|
-
|
|
70
|
+
pnpm install
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
3. Start development mode:
|
|
74
74
|
|
|
75
75
|
```sh
|
|
76
|
-
|
|
76
|
+
pnpm start
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
Or build and run production mode:
|
|
80
80
|
|
|
81
81
|
```sh
|
|
82
|
-
|
|
82
|
+
pnpm build && node ./lib/index.js
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
### Available Scripts
|
|
86
86
|
|
|
87
87
|
| Script | Description |
|
|
88
88
|
|--------|-------------|
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
89
|
+
| `pnpm start` | Start development mode with hot reload |
|
|
90
|
+
| `pnpm build` | Build for production |
|
|
91
|
+
| `pnpm test` | Run unit tests |
|
|
92
|
+
| `pnpm test:coverage` | Run unit tests with coverage |
|
|
93
|
+
| `pnpm lint` | Run ESLint and formatting checks |
|
|
94
|
+
| `pnpm eslint` | Run ESLint |
|
|
95
|
+
| `pnpm prettier:check` | Check code formatting |
|
|
96
|
+
| `pnpm prettier:write` | Auto-fix code formatting |
|
|
96
97
|
|
|
97
98
|
## Development Workflow
|
|
98
99
|
|
|
@@ -107,7 +108,7 @@ git checkout -b fix/your-bug-fix
|
|
|
107
108
|
2. Make your changes and ensure tests pass:
|
|
108
109
|
|
|
109
110
|
```sh
|
|
110
|
-
|
|
111
|
+
pnpm test
|
|
111
112
|
```
|
|
112
113
|
|
|
113
114
|
3. Commit your changes following our [commit message guidelines](#commit-message-guidelines).
|
|
@@ -118,8 +119,8 @@ yarn test
|
|
|
118
119
|
|
|
119
120
|
### Before Submitting
|
|
120
121
|
|
|
121
|
-
- [ ] Run `
|
|
122
|
-
- [ ] Run `
|
|
122
|
+
- [ ] Run `pnpm test` and ensure all checks pass
|
|
123
|
+
- [ ] Run `pnpm build` to verify the build succeeds
|
|
123
124
|
- [ ] Update documentation if you changed any user-facing behavior
|
|
124
125
|
- [ ] Add tests for new functionality
|
|
125
126
|
|
|
@@ -164,13 +165,13 @@ This project uses ESLint and Prettier. Your code will be automatically checked.
|
|
|
164
165
|
|
|
165
166
|
```sh
|
|
166
167
|
# Check formatting
|
|
167
|
-
|
|
168
|
+
pnpm prettier:check
|
|
168
169
|
|
|
169
170
|
# Auto-fix formatting
|
|
170
|
-
|
|
171
|
+
pnpm prettier:write
|
|
171
172
|
|
|
172
173
|
# Run linter
|
|
173
|
-
|
|
174
|
+
pnpm eslint
|
|
174
175
|
```
|
|
175
176
|
|
|
176
177
|
### File Organization
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[](https://www.npmjs.org/package/az2aws)
|
|
2
|
-
[](https://www.npmjs.org/package/az2aws)
|
|
2
|
+
[](https://www.npmjs.org/package/az2aws)
|
|
3
3
|
[](https://github.com/kuma0128/az2aws/actions/workflows/main.yml)
|
|
4
4
|
[](https://codecov.io/gh/kuma0128/az2aws)
|
|
5
5
|
|
|
@@ -121,6 +121,10 @@ Set the `region` in your ~/.aws/config to use non-standard AWS partitions:
|
|
|
121
121
|
- **GovCloud**: us-gov-west-1, us-gov-east-1
|
|
122
122
|
- **China**: cn-north-1, cn-northwest-1
|
|
123
123
|
|
|
124
|
+
For GovCloud, make sure your AWS CLI default region is set to a GovCloud
|
|
125
|
+
region if you do not set a profile region; otherwise STS calls may target the
|
|
126
|
+
standard partition.
|
|
127
|
+
|
|
124
128
|
#### Stay Logged In
|
|
125
129
|
|
|
126
130
|
Enable "Stay logged in" during configuration to use `--no-prompt` without storing passwords:
|
|
@@ -178,7 +182,7 @@ You'll be prompted for username, password, and MFA if required. After login, use
|
|
|
178
182
|
**Tips:**
|
|
179
183
|
- Set `AWS_PROFILE` env var instead of using `--profile`
|
|
180
184
|
- Use `--mode gui --disable-gpu` on VMs or if rendering fails
|
|
181
|
-
- Set `https_proxy` env var for corporate proxy
|
|
185
|
+
- Set `https_proxy` or `http_proxy` env var for corporate proxy
|
|
182
186
|
|
|
183
187
|
#### Troubleshooting
|
|
184
188
|
|
package/lib/awsConfig.js
CHANGED
|
@@ -47,6 +47,11 @@ exports.awsConfig = {
|
|
|
47
47
|
expirationDate = new Date(config[profileName].aws_expiration);
|
|
48
48
|
}
|
|
49
49
|
const timeDifference = expirationDate.getTime() - new Date().getTime();
|
|
50
|
+
// If expiration date is invalid (NaN), treat as expired for safety
|
|
51
|
+
if (isNaN(timeDifference)) {
|
|
52
|
+
debug("Invalid expiration date, treating as expired");
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
50
55
|
debug(`Remaining time till credential expiration: ${timeDifference / 1000}s, refresh due if time lower than: ${refreshLimitInMs / 1000}s`);
|
|
51
56
|
return timeDifference < refreshLimitInMs;
|
|
52
57
|
},
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.configureProfileAsync =
|
|
6
|
+
exports.configureProfileAsync = configureProfileAsync;
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
8
|
const awsConfig_1 = require("./awsConfig");
|
|
9
9
|
async function configureProfileAsync(profileName) {
|
|
@@ -74,4 +74,3 @@ async function configureProfileAsync(profileName) {
|
|
|
74
74
|
});
|
|
75
75
|
console.log("Profile saved.");
|
|
76
76
|
}
|
|
77
|
-
exports.configureProfileAsync = configureProfileAsync;
|
package/lib/login.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.login = void 0;
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
7
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
9
8
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
9
|
const zlib_1 = __importDefault(require("zlib"));
|
|
@@ -19,6 +18,7 @@ const awsConfig_1 = require("./awsConfig");
|
|
|
19
18
|
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
20
19
|
const paths_1 = require("./paths");
|
|
21
20
|
const mkdirp_1 = __importDefault(require("mkdirp"));
|
|
21
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
22
22
|
const https_1 = require("https");
|
|
23
23
|
const node_http_handler_1 = require("@smithy/node-http-handler");
|
|
24
24
|
const loginStates_1 = require("./loginStates");
|
|
@@ -32,6 +32,10 @@ const AZURE_AD_SSO = "autologon.microsoftazuread-sso.com";
|
|
|
32
32
|
const AWS_SAML_ENDPOINT = "https://signin.aws.amazon.com/saml";
|
|
33
33
|
const AWS_CN_SAML_ENDPOINT = "https://signin.amazonaws.cn/saml";
|
|
34
34
|
const AWS_GOV_SAML_ENDPOINT = "https://signin.amazonaws-us-gov.com/saml";
|
|
35
|
+
const getProxyUrl = () => process.env.https_proxy ||
|
|
36
|
+
process.env.HTTPS_PROXY ||
|
|
37
|
+
process.env.http_proxy ||
|
|
38
|
+
process.env.HTTP_PROXY;
|
|
35
39
|
exports.login = {
|
|
36
40
|
async loginAsync(profileName, mode, disableSandbox, noPrompt, enableChromeNetworkService, awsNoVerifySsl, enableChromeSeamlessSso, noDisableExtensions, disableGpu) {
|
|
37
41
|
let headless, cliProxy;
|
|
@@ -208,8 +212,9 @@ exports.login = {
|
|
|
208
212
|
args.push(`--profile-directory=${paths_1.paths.profileDir}`);
|
|
209
213
|
}
|
|
210
214
|
}
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
const proxyUrl = getProxyUrl();
|
|
216
|
+
if (proxyUrl) {
|
|
217
|
+
args.push(`--proxy-server=${proxyUrl}`);
|
|
213
218
|
}
|
|
214
219
|
const ignoreDefaultArgs = noDisableExtensions
|
|
215
220
|
? ["--disable-extensions"]
|
|
@@ -225,7 +230,24 @@ exports.login = {
|
|
|
225
230
|
if (paths_1.paths.chromeBin) {
|
|
226
231
|
launchParams.executablePath = paths_1.paths.chromeBin;
|
|
227
232
|
}
|
|
228
|
-
|
|
233
|
+
try {
|
|
234
|
+
browser = await puppeteer_1.default.launch(launchParams);
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
if (e instanceof Error &&
|
|
238
|
+
e.constructor.name === "TargetCloseError" &&
|
|
239
|
+
rememberMe) {
|
|
240
|
+
const userDataDir = paths_1.paths.userDataDir || paths_1.paths.chromium;
|
|
241
|
+
debug(`Browser launch failed with TargetCloseError. Resetting profile at ${userDataDir}`);
|
|
242
|
+
console.warn("Browser profile appears incompatible. Resetting profile data and retrying...");
|
|
243
|
+
await promises_1.default.rm(userDataDir, { recursive: true, force: true });
|
|
244
|
+
await (0, mkdirp_1.default)(userDataDir);
|
|
245
|
+
browser = await puppeteer_1.default.launch(launchParams);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
throw e;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
229
251
|
// Wait for a bit as sometimes the browser isn't ready.
|
|
230
252
|
await bluebird_1.default.delay(200);
|
|
231
253
|
const pages = await browser.pages();
|
|
@@ -417,7 +439,7 @@ exports.login = {
|
|
|
417
439
|
if (!defaultRoleArn) {
|
|
418
440
|
throw new CLIError_1.CLIError("--no-prompt requires azure_default_role_arn when multiple roles are available.");
|
|
419
441
|
}
|
|
420
|
-
role =
|
|
442
|
+
role = roles.find((r) => r.roleArn === defaultRoleArn);
|
|
421
443
|
if (!role) {
|
|
422
444
|
throw new CLIError_1.CLIError(`Default role ARN '${defaultRoleArn}' was not found in the SAML response.`);
|
|
423
445
|
}
|
|
@@ -429,7 +451,7 @@ exports.login = {
|
|
|
429
451
|
name: "role",
|
|
430
452
|
message: "Role:",
|
|
431
453
|
type: "list",
|
|
432
|
-
choices:
|
|
454
|
+
choices: roles.map((r) => r.roleArn).sort(),
|
|
433
455
|
default: defaultRoleArn,
|
|
434
456
|
});
|
|
435
457
|
}
|
|
@@ -461,7 +483,7 @@ exports.login = {
|
|
|
461
483
|
if (questions.length > 0) {
|
|
462
484
|
const answers = await inquirer_1.default.prompt(questions);
|
|
463
485
|
if (!role)
|
|
464
|
-
role =
|
|
486
|
+
role = roles.find((r) => r.roleArn === answers.role);
|
|
465
487
|
if (answers.durationHours) {
|
|
466
488
|
durationHours = parseInt(answers.durationHours, 10);
|
|
467
489
|
}
|
|
@@ -491,12 +513,13 @@ exports.login = {
|
|
|
491
513
|
"This makes the connection vulnerable to MITM attacks. " +
|
|
492
514
|
"Consider using NODE_EXTRA_CA_CERTS environment variable instead.");
|
|
493
515
|
}
|
|
494
|
-
|
|
516
|
+
const proxyUrl = getProxyUrl();
|
|
517
|
+
if (proxyUrl) {
|
|
495
518
|
const proxyOptions = awsNoVerifySsl ? { rejectUnauthorized: false } : {};
|
|
496
519
|
stsOptions = {
|
|
497
520
|
...stsOptions,
|
|
498
521
|
requestHandler: new node_http_handler_1.NodeHttpHandler({
|
|
499
|
-
httpsAgent: new https_proxy_agent_1.HttpsProxyAgent(
|
|
522
|
+
httpsAgent: new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, proxyOptions),
|
|
500
523
|
}),
|
|
501
524
|
};
|
|
502
525
|
}
|
package/lib/loginStates.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.states = void 0;
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
7
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
9
8
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
9
|
const debug_1 = __importDefault(require("debug"));
|
|
@@ -54,9 +53,10 @@ exports.states = [
|
|
|
54
53
|
debug("Focusing on username input");
|
|
55
54
|
await page.focus(`input[name="loginfmt"]`);
|
|
56
55
|
debug("Clearing input");
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
56
|
+
await page.$eval('input[name="loginfmt"]', (el) => {
|
|
57
|
+
el.select();
|
|
58
|
+
});
|
|
59
|
+
await page.keyboard.press("Backspace");
|
|
60
60
|
debug("Typing username");
|
|
61
61
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
62
62
|
await page.keyboard.type(username);
|
|
@@ -116,11 +116,11 @@ exports.states = [
|
|
|
116
116
|
name: "account",
|
|
117
117
|
message: "Account:",
|
|
118
118
|
type: "list",
|
|
119
|
-
choices:
|
|
119
|
+
choices: accounts.map((a) => a.message),
|
|
120
120
|
default: aadTileMessage,
|
|
121
121
|
},
|
|
122
122
|
]);
|
|
123
|
-
account =
|
|
123
|
+
account = accounts.find((a) => a.message === answers.account);
|
|
124
124
|
}
|
|
125
125
|
if (!account) {
|
|
126
126
|
throw new Error("Unable to find account");
|
|
@@ -281,9 +281,10 @@ exports.states = [
|
|
|
281
281
|
debug("Focusing on verification code input");
|
|
282
282
|
await page.focus(`input[name="otc"]`);
|
|
283
283
|
debug("Clearing input");
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
284
|
+
await page.$eval('input[name="otc"]', (el) => {
|
|
285
|
+
el.select();
|
|
286
|
+
});
|
|
287
|
+
await page.keyboard.press("Backspace");
|
|
287
288
|
debug("Typing verification code");
|
|
288
289
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
289
290
|
await page.keyboard.type(verificationCode);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "az2aws",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Use Azure AD SSO to log into the AWS CLI. A modern, actively maintained alternative to aws-azure-login.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": {
|
|
@@ -37,6 +37,13 @@
|
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=24.0"
|
|
39
39
|
},
|
|
40
|
+
"packageManager": "pnpm@10.29.3",
|
|
41
|
+
"pnpm": {
|
|
42
|
+
"onlyBuiltDependencies": [
|
|
43
|
+
"esbuild",
|
|
44
|
+
"puppeteer"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
40
47
|
"bin": {
|
|
41
48
|
"az2aws": "lib/index.js"
|
|
42
49
|
},
|
|
@@ -50,7 +57,7 @@
|
|
|
50
57
|
"test": "vitest run",
|
|
51
58
|
"test:watch": "vitest",
|
|
52
59
|
"test:coverage": "vitest run --coverage",
|
|
53
|
-
"lint": "
|
|
60
|
+
"lint": "pnpm eslint && pnpm prettier:check"
|
|
54
61
|
},
|
|
55
62
|
"dependencies": {
|
|
56
63
|
"@aws-sdk/client-sts": "^3.723.0",
|
|
@@ -63,7 +70,6 @@
|
|
|
63
70
|
"https-proxy-agent": "^7.0.6",
|
|
64
71
|
"ini": "^3.0.1",
|
|
65
72
|
"inquirer": "^8.2.6",
|
|
66
|
-
"lodash": "^4.17.21",
|
|
67
73
|
"mkdirp": "^2.1.6",
|
|
68
74
|
"puppeteer": "^24.34.0",
|
|
69
75
|
"uuid": "^9.0.1"
|
|
@@ -74,7 +80,6 @@
|
|
|
74
80
|
"@types/debug": "^4.1.12",
|
|
75
81
|
"@types/ini": "^1.3.34",
|
|
76
82
|
"@types/inquirer": "^8.2.10",
|
|
77
|
-
"@types/lodash": "^4.17.0",
|
|
78
83
|
"@types/mkdirp": "^1.0.2",
|
|
79
84
|
"@types/node": "^24.0.0",
|
|
80
85
|
"@types/uuid": "^8.3.4",
|