Skip to content

Commit a6c6846

Browse files
committed
add -w option to open selected account in web console
1 parent 099e8ef commit a6c6846

File tree

5 files changed

+812
-15
lines changed

5 files changed

+812
-15
lines changed

app.js

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#!/usr/bin/env node
2+
23
import yargs from "yargs";
4+
import chalk from "chalk";
5+
import open from "open";
36
import { hideBin } from "yargs/helpers";
47
import Configstore from "configstore";
8+
import { getSigninUrl } from "./lib/web.js";
59
import { refreshCredentials } from "./lib/auth.js";
610
import { handleError } from "./lib/error.js";
711
import {
@@ -23,19 +27,20 @@ const configstore = new Configstore("aws-sso-cli");
2327

2428
const signInHandler = async (argv) => {
2529
try {
26-
const profile =
27-
"profile" in argv
28-
? argv.profile
29-
: await chooseProfile(configstore);
30-
30+
const profile = "profile" in argv ? argv.profile : await chooseProfile(configstore);
31+
3132
const config = await refreshCredentials(loadConfig(configstore, profile), argv.forceNewToken);
3233
updateConfig(configstore, profile, config);
33-
const { token: { accessToken }, region, } = config;
34+
const {
35+
token: { accessToken },
36+
region,
37+
} = config;
3438

3539
const { accountId } =
3640
"account" in argv
3741
? await findAccountByName(accessToken, argv.account, region)
3842
: await chooseAccount(accessToken, region);
43+
3944
const { roleName } =
4045
"role" in argv
4146
? await findRoleByName(accessToken, argv.role, accountId, region)
@@ -45,14 +50,19 @@ const signInHandler = async (argv) => {
4550
roleCredentials: { accessKeyId, secretAccessKey, sessionToken },
4651
} = await getCredentials(accessToken, accountId, roleName, region);
4752

48-
console.log(
49-
"",
50-
`export AWS_ACCESS_KEY_ID=${accessKeyId}`,
51-
"\n",
52-
`export AWS_SECRET_ACCESS_KEY=${secretAccessKey}`,
53-
"\n",
54-
`export AWS_SESSION_TOKEN=${sessionToken}`
55-
);
53+
if (argv.web) {
54+
open(await getSigninUrl(accessKeyId, secretAccessKey, sessionToken, region));
55+
} else {
56+
console.log(
57+
"",
58+
`export AWS_ACCESS_KEY_ID=${accessKeyId}`,
59+
"\n",
60+
`export AWS_SECRET_ACCESS_KEY=${secretAccessKey}`,
61+
"\n",
62+
`export AWS_SESSION_TOKEN=${sessionToken}`
63+
);
64+
}
65+
console.error(chalk.bold.green("\nAll set!"));
5666
} catch (err) {
5767
handleError(err);
5868
}
@@ -115,5 +125,10 @@ yargs(hideBin(process.argv))
115125
describe: "Force fetch a new access token for AWS SSO.",
116126
type: "boolean",
117127
})
128+
.option("w", {
129+
alias: "web",
130+
describe: "Open selected AWS account in your web browser.",
131+
type: "boolean",
132+
})
118133
.wrap(90)
119134
.help("help", "Show help.").argv;

lib/error.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export const handleError = (error) => {
2121
else if (error.code === "ERR_ROLE_NOT_FOUND") {
2222
console.error("Error: The specified role could not be found for the specified AWS account.");
2323
}
24+
else if (error.code === "ERR_GET_SIGNIN_URL") {
25+
console.error(error.message);
26+
}
2427
else {
2528
console.error(error);
2629
}

lib/web.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import axios from "axios";
2+
import os from "os";
3+
import { buildError } from "./error.js";
4+
5+
const buildURLQuery = (obj) =>
6+
Object.entries(obj)
7+
.map((pair) => pair.map(encodeURIComponent).join("="))
8+
.join("&");
9+
10+
export const getSigninUrl = async (accessKeyId, secretAccessKey, sessionToken, region) => {
11+
const federationUrl = "https://signin.aws.amazon.com/federation";
12+
const destinationUrl = `https://console.aws.amazon.com/console/home?region=${region}`;
13+
14+
try {
15+
const response = await axios.get(federationUrl, {
16+
params: {
17+
Action: "getSigninToken",
18+
Session: JSON.stringify({
19+
sessionId: accessKeyId,
20+
sessionKey: secretAccessKey,
21+
sessionToken: sessionToken,
22+
}),
23+
},
24+
});
25+
26+
const urlParams = buildURLQuery({
27+
Action: "login",
28+
Issuer: encodeURI(os.hostname),
29+
Destination: encodeURI(destinationUrl),
30+
SigninToken: encodeURI(response?.data?.SigninToken),
31+
});
32+
33+
return `${federationUrl}?${urlParams}`;
34+
} catch (err) {
35+
throw buildError("ERR_GET_SIGNIN_URL", `${err}`);
36+
}
37+
};

0 commit comments

Comments
 (0)