az2aws 1.6.1 → 1.6.2
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 +7 -0
- package/README.md +11 -0
- package/lib/awsConfig.js +2 -2
- package/lib/login.js +9 -10
- package/lib/loginStates.js +8 -8
- package/package.json +6 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.2](https://github.com/kuma0128/az2aws/compare/v1.6.1...v1.6.2) (2026-04-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **deps:** remove unnecessary dependency for security hardening ([#156](https://github.com/kuma0128/az2aws/issues/156)) ([b1ac64d](https://github.com/kuma0128/az2aws/commit/b1ac64d358197db094603dbc948c5f49cfa78c88))
|
|
9
|
+
|
|
3
10
|
## [1.6.1](https://github.com/kuma0128/az2aws/compare/v1.6.0...v1.6.1) (2026-04-02)
|
|
4
11
|
|
|
5
12
|
|
package/README.md
CHANGED
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
Log in to AWS CLI using [Azure Active Directory](https://azure.microsoft.com) SSO. Supports MFA and places temporary credentials in the proper location for AWS CLI and SDKs.
|
|
9
9
|
|
|
10
|
+
> **💡 Tip:** Let's be honest — typing `az2aws` correctly on the first try is harder than the AWS certification exam. Save your sanity:
|
|
11
|
+
>
|
|
12
|
+
> ```sh
|
|
13
|
+
> # Add to your ~/.zshrc or ~/.bashrc
|
|
14
|
+
> alias a2='az2aws'
|
|
15
|
+
> # or
|
|
16
|
+
> alias aa='az2aws'
|
|
17
|
+
> ```
|
|
18
|
+
>
|
|
19
|
+
> Your fingers will thank you. Your keyboard will thank you. Your coworkers will stop hearing you swear.
|
|
20
|
+
|
|
10
21
|
## Installation
|
|
11
22
|
|
|
12
23
|
### mise (Recommended)
|
package/lib/awsConfig.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.awsConfig = void 0;
|
|
|
7
7
|
const ini_1 = __importDefault(require("ini"));
|
|
8
8
|
const debug_1 = __importDefault(require("debug"));
|
|
9
9
|
const paths_1 = require("./paths");
|
|
10
|
-
const
|
|
10
|
+
const promises_1 = require("node:fs/promises");
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
12
|
const util_1 = __importDefault(require("util"));
|
|
13
13
|
const debug = (0, debug_1.default)("az2aws");
|
|
@@ -101,7 +101,7 @@ exports.awsConfig = {
|
|
|
101
101
|
debug(`Stringifying ${type} INI data`);
|
|
102
102
|
const text = ini_1.default.stringify(data);
|
|
103
103
|
debug(`Creating AWS config directory '${paths_1.paths.awsDir}' if not exists.`);
|
|
104
|
-
await (0,
|
|
104
|
+
await (0, promises_1.mkdir)(paths_1.paths.awsDir, { recursive: true });
|
|
105
105
|
debug(`Writing '${type}' INI to file '${paths_1.paths[type]}'`);
|
|
106
106
|
await writeFile(paths_1.paths[type], text);
|
|
107
107
|
},
|
package/lib/login.js
CHANGED
|
@@ -4,20 +4,19 @@ 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
|
|
7
|
+
const promises_1 = require("node:timers/promises");
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
10
|
const zlib_1 = __importDefault(require("zlib"));
|
|
10
11
|
const client_sts_1 = require("@aws-sdk/client-sts");
|
|
11
12
|
const cheerio_1 = require("cheerio");
|
|
12
|
-
const uuid_1 = require("uuid");
|
|
13
13
|
const puppeteer_1 = __importDefault(require("puppeteer"));
|
|
14
14
|
const querystring_1 = __importDefault(require("querystring"));
|
|
15
15
|
const debug_1 = __importDefault(require("debug"));
|
|
16
16
|
const CLIError_1 = require("./CLIError");
|
|
17
17
|
const awsConfig_1 = require("./awsConfig");
|
|
18
18
|
const paths_1 = require("./paths");
|
|
19
|
-
const
|
|
20
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
19
|
+
const promises_2 = __importDefault(require("fs/promises"));
|
|
21
20
|
const https_1 = require("https");
|
|
22
21
|
const node_http_handler_1 = require("@smithy/node-http-handler");
|
|
23
22
|
const loginStates_1 = require("./loginStates");
|
|
@@ -150,7 +149,7 @@ exports.login = {
|
|
|
150
149
|
*/
|
|
151
150
|
_createLoginUrlAsync(appIdUri, tenantId, assertionConsumerServiceURL) {
|
|
152
151
|
debug("Generating UUID for SAML request");
|
|
153
|
-
const id =
|
|
152
|
+
const id = node_crypto_1.default.randomUUID();
|
|
154
153
|
const samlRequest = `
|
|
155
154
|
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="id${id}" Version="2.0" IssueInstant="${new Date().toISOString()}" IsPassive="false" AssertionConsumerServiceURL="${assertionConsumerServiceURL}" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
156
155
|
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">${appIdUri}</Issuer>
|
|
@@ -212,7 +211,7 @@ exports.login = {
|
|
|
212
211
|
args.push(`--user-data-dir=${paths_1.paths.userDataDir}`);
|
|
213
212
|
}
|
|
214
213
|
else {
|
|
215
|
-
await
|
|
214
|
+
await promises_2.default.mkdir(paths_1.paths.chromium, { recursive: true });
|
|
216
215
|
args.push(`--user-data-dir=${paths_1.paths.chromium}`);
|
|
217
216
|
}
|
|
218
217
|
// --profile-directory requires --user-data-dir to work properly
|
|
@@ -251,8 +250,8 @@ exports.login = {
|
|
|
251
250
|
!paths_1.paths.userDataDir) {
|
|
252
251
|
debug(`Browser launch failed with TargetCloseError. Resetting profile at ${paths_1.paths.chromium}`);
|
|
253
252
|
console.warn("Browser profile appears incompatible. Resetting profile data and retrying...");
|
|
254
|
-
await
|
|
255
|
-
await
|
|
253
|
+
await promises_2.default.rm(paths_1.paths.chromium, { recursive: true, force: true });
|
|
254
|
+
await promises_2.default.mkdir(paths_1.paths.chromium, { recursive: true });
|
|
256
255
|
browser = await puppeteer_1.default.launch(launchParams);
|
|
257
256
|
}
|
|
258
257
|
else {
|
|
@@ -260,7 +259,7 @@ exports.login = {
|
|
|
260
259
|
}
|
|
261
260
|
}
|
|
262
261
|
// Wait for a bit as sometimes the browser isn't ready.
|
|
263
|
-
await
|
|
262
|
+
await (0, promises_1.setTimeout)(200);
|
|
264
263
|
let page;
|
|
265
264
|
if (incognito) {
|
|
266
265
|
const existingPages = await browser.pages();
|
|
@@ -372,7 +371,7 @@ exports.login = {
|
|
|
372
371
|
throw new CLIError_1.CLIError(`Unable to recognize page state! A screenshot has been dumped to ${path}. If this problem persists, try running with --mode=gui or --mode=debug`);
|
|
373
372
|
}
|
|
374
373
|
totalUnrecognizedDelay += DELAY_ON_UNRECOGNIZED_PAGE;
|
|
375
|
-
await
|
|
374
|
+
await (0, promises_1.setTimeout)(DELAY_ON_UNRECOGNIZED_PAGE);
|
|
376
375
|
}
|
|
377
376
|
}
|
|
378
377
|
}
|
package/lib/loginStates.js
CHANGED
|
@@ -4,7 +4,7 @@ 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
|
|
7
|
+
const promises_1 = require("node:timers/promises");
|
|
8
8
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
9
|
const debug_1 = __importDefault(require("debug"));
|
|
10
10
|
const CLIError_1 = require("./CLIError");
|
|
@@ -62,7 +62,7 @@ exports.states = [
|
|
|
62
62
|
debug("Typing username");
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
64
64
|
await page.keyboard.type(username);
|
|
65
|
-
await
|
|
65
|
+
await (0, promises_1.setTimeout)(500);
|
|
66
66
|
debug("Waiting for submit button to be visible");
|
|
67
67
|
await page.waitForSelector(`input[type=submit]`, {
|
|
68
68
|
visible: true,
|
|
@@ -70,12 +70,12 @@ exports.states = [
|
|
|
70
70
|
});
|
|
71
71
|
debug("Submitting form");
|
|
72
72
|
await page.click("input[type=submit]");
|
|
73
|
-
await
|
|
73
|
+
await (0, promises_1.setTimeout)(500);
|
|
74
74
|
debug("Waiting for submission to finish");
|
|
75
75
|
await Promise.race([
|
|
76
76
|
page.waitForSelector(`input[name=loginfmt].has-error,input[name=loginfmt].moveOffScreen`, { timeout: 60000 }),
|
|
77
77
|
(async () => {
|
|
78
|
-
await
|
|
78
|
+
await (0, promises_1.setTimeout)(1000);
|
|
79
79
|
await page.waitForSelector(`input[name=loginfmt]`, {
|
|
80
80
|
hidden: true,
|
|
81
81
|
timeout: 60000,
|
|
@@ -129,7 +129,7 @@ exports.states = [
|
|
|
129
129
|
}
|
|
130
130
|
debug(`Proceeding with account ${account.selector}`);
|
|
131
131
|
await page.click(account.selector);
|
|
132
|
-
await
|
|
132
|
+
await (0, promises_1.setTimeout)(500);
|
|
133
133
|
},
|
|
134
134
|
},
|
|
135
135
|
{
|
|
@@ -206,7 +206,7 @@ exports.states = [
|
|
|
206
206
|
debug("Submitting form");
|
|
207
207
|
await page.click("span[class=submit],input[type=submit]");
|
|
208
208
|
debug("Waiting for a delay");
|
|
209
|
-
await
|
|
209
|
+
await (0, promises_1.setTimeout)(500);
|
|
210
210
|
},
|
|
211
211
|
},
|
|
212
212
|
{
|
|
@@ -299,7 +299,7 @@ exports.states = [
|
|
|
299
299
|
await Promise.race([
|
|
300
300
|
page.waitForSelector(`input[name=otc].has-error,input[name=otc].moveOffScreen`, { timeout: 60000 }),
|
|
301
301
|
(async () => {
|
|
302
|
-
await
|
|
302
|
+
await (0, promises_1.setTimeout)(1000);
|
|
303
303
|
await page.waitForSelector(`input[name=otc]`, {
|
|
304
304
|
hidden: true,
|
|
305
305
|
timeout: 60000,
|
|
@@ -321,7 +321,7 @@ exports.states = [
|
|
|
321
321
|
await page.click("#idBtn_Back");
|
|
322
322
|
}
|
|
323
323
|
debug("Waiting for a delay");
|
|
324
|
-
await
|
|
324
|
+
await (0, promises_1.setTimeout)(500);
|
|
325
325
|
},
|
|
326
326
|
},
|
|
327
327
|
{
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "az2aws",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Use Azure AD SSO to log into the AWS CLI. A modern, actively maintained alternative to aws-azure-login.",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "az2aws devs",
|
|
8
8
|
"url": "https://github.com/az2aws"
|
|
@@ -44,14 +44,6 @@
|
|
|
44
44
|
"puppeteer"
|
|
45
45
|
],
|
|
46
46
|
"overrides": {
|
|
47
|
-
"brace-expansion@<1.1.12": "1.1.12",
|
|
48
|
-
"brace-expansion@>=2.0.0 <2.0.2": "2.0.2",
|
|
49
|
-
"brace-expansion@>=3.0.0 <3.0.1": "3.0.1",
|
|
50
|
-
"brace-expansion@>=4.0.0 <4.0.1": "4.0.1",
|
|
51
|
-
"flatted@<3.4.2": "3.4.2",
|
|
52
|
-
"minimatch@>=9.0.0 <9.0.7": "9.0.7",
|
|
53
|
-
"picomatch@<2.3.2": "2.3.2",
|
|
54
|
-
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
|
|
55
47
|
"yauzl@<3.2.1": "3.2.1"
|
|
56
48
|
}
|
|
57
49
|
},
|
|
@@ -73,19 +65,15 @@
|
|
|
73
65
|
"dependencies": {
|
|
74
66
|
"@aws-sdk/client-sts": "^3.1009.0",
|
|
75
67
|
"@smithy/node-http-handler": "^4.4.16",
|
|
76
|
-
"bluebird": "^3.7.2",
|
|
77
68
|
"cheerio": "^1.2.0",
|
|
78
69
|
"commander": "^14.0.3",
|
|
79
70
|
"debug": "^4.4.3",
|
|
80
|
-
"https-proxy-agent": "^
|
|
71
|
+
"https-proxy-agent": "^9.0.0",
|
|
81
72
|
"ini": "^6.0.0",
|
|
82
|
-
"inquirer": "^13.
|
|
83
|
-
"
|
|
84
|
-
"puppeteer": "^24.39.1",
|
|
85
|
-
"uuid": "^13.0.0"
|
|
73
|
+
"inquirer": "^13.4.0",
|
|
74
|
+
"puppeteer": "^24.39.1"
|
|
86
75
|
},
|
|
87
76
|
"devDependencies": {
|
|
88
|
-
"@types/bluebird": "^3.5.42",
|
|
89
77
|
"@types/debug": "^4.1.12",
|
|
90
78
|
"@types/ini": "^4.1.1",
|
|
91
79
|
"@types/node": "^25.5.0",
|
|
@@ -97,6 +85,7 @@
|
|
|
97
85
|
"prettier": "^3.8.1",
|
|
98
86
|
"ts-node-dev": "^2.0.0",
|
|
99
87
|
"typescript": "^6.0.2",
|
|
88
|
+
"vite": "^8.0.7",
|
|
100
89
|
"vitest": "^4.1.0"
|
|
101
90
|
}
|
|
102
91
|
}
|