ag-awsauth 0.0.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/LICENSE.md ADDED
@@ -0,0 +1,11 @@
1
+ ISC License
2
+ ---
3
+
4
+ ag-awsauth - Copyright 2021 Andrei Gec
5
+ check out https://github.com/andreigec/ag-awsauth or https://gec.dev for more info
6
+
7
+ ---
8
+
9
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # ag-awsauth
2
+
3
+ ## Usage
4
+
5
+ npm i -g awsauth
6
+
7
+ awsauth -c
8
+
9
+ awsauth
package/bin/awsauth.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
4
+ var lib = require('../dist/index.js');
5
+ void lib.run();
@@ -0,0 +1,8 @@
1
+ export declare const logPath = "log.txt";
2
+ export declare const stsDurationSeconds: number;
3
+ export declare const nativeStsDurationSeconds: number;
4
+ export declare const identityCenterRegion: () => string;
5
+ export declare const ssoStartUrl: () => string;
6
+ export declare const targetRegion: () => string;
7
+ export declare const validateConfig: () => boolean;
8
+ export declare const runConfig: () => void;
package/dist/config.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runConfig = exports.validateConfig = exports.targetRegion = exports.ssoStartUrl = exports.identityCenterRegion = exports.nativeStsDurationSeconds = exports.stsDurationSeconds = exports.logPath = void 0;
7
+ const envfile_1 = require("envfile");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ exports.logPath = 'log.txt';
11
+ exports.stsDurationSeconds = 60 * 60 * 4; //4h
12
+ exports.nativeStsDurationSeconds = 60 * 60 * 1; //1h
13
+ const identityCenterRegion = () => process.env.identityCenterRegion;
14
+ exports.identityCenterRegion = identityCenterRegion;
15
+ const ssoStartUrl = () => process.env.ssoStartUrl;
16
+ exports.ssoStartUrl = ssoStartUrl;
17
+ const targetRegion = () => process.env.targetRegion;
18
+ exports.targetRegion = targetRegion;
19
+ const validateConfig = () => {
20
+ if (!(0, exports.identityCenterRegion)() || !(0, exports.ssoStartUrl)() || !(0, exports.targetRegion)()) {
21
+ return false;
22
+ }
23
+ return true;
24
+ };
25
+ exports.validateConfig = validateConfig;
26
+ const runConfig = () => {
27
+ const pn = path_1.default.resolve(__dirname + '/../.env');
28
+ if (!fs_1.default.existsSync(pn)) {
29
+ fs_1.default.writeFileSync(pn, '');
30
+ }
31
+ const c = (0, envfile_1.parse)(fs_1.default.readFileSync(pn).toString());
32
+ if (!c.ssoStartUrl) {
33
+ c.ssoStartUrl = ' //eg https://d-xxx.awsapps.com/start';
34
+ }
35
+ if (!c.targetRegion) {
36
+ c.targetRegion = ' //eg ap-southeast-1';
37
+ }
38
+ if (!c.identityCenterRegion) {
39
+ c.identityCenterRegion = ' //eg us-east-1';
40
+ }
41
+ fs_1.default.writeFileSync(pn, (0, envfile_1.stringify)(c));
42
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
43
+ require('child_process').exec(`start "" "${pn}"`);
44
+ };
45
+ exports.runConfig = runConfig;
@@ -0,0 +1 @@
1
+ export {};
package/dist/direct.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const dotenv_1 = require("dotenv");
4
+ const _1 = require(".");
5
+ (0, dotenv_1.config)();
6
+ void (0, _1.run)();
@@ -0,0 +1,3 @@
1
+ import { IAwsCreds, IAwsCredsRaw } from '../types';
2
+ export declare const getAwsCredentials: () => Promise<Record<string, IAwsCredsRaw>>;
3
+ export declare const updateAwsCredentials: (p: IAwsCreds | undefined) => Promise<void>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.updateAwsCredentials = exports.getAwsCredentials = void 0;
16
+ const shared_ini_file_loader_1 = require("@aws-sdk/shared-ini-file-loader");
17
+ //@ts-ignore
18
+ const getCredentialsFilepath_1 = require("@aws-sdk/shared-ini-file-loader/dist-cjs/getCredentialsFilepath");
19
+ const log_1 = require("ag-common/dist/common/helpers/log");
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const ini_1 = require("ini");
22
+ const getAwsCredentials = () => __awaiter(void 0, void 0, void 0, function* () {
23
+ const config = yield (0, shared_ini_file_loader_1.loadSharedConfigFiles)();
24
+ const creds = config.credentialsFile;
25
+ if (!creds.default) {
26
+ creds.default = {};
27
+ }
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const ret = creds;
30
+ return ret;
31
+ });
32
+ exports.getAwsCredentials = getAwsCredentials;
33
+ const updateAwsCredentials = (p) => __awaiter(void 0, void 0, void 0, function* () {
34
+ const creds = yield (0, exports.getAwsCredentials)();
35
+ if (!p) {
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ creds.default = {};
38
+ }
39
+ else {
40
+ creds.default.region = p.region;
41
+ creds.default.aws_access_key_id = p.accessKeyId;
42
+ creds.default.aws_secret_access_key = p.secretAccessKey;
43
+ creds.default.aws_session_token = p.sessionToken;
44
+ creds.default.aws_access_token = p.accessToken;
45
+ creds.default.aws_sso_authn = p.ssoAuthn;
46
+ }
47
+ const newcreds = (0, ini_1.stringify)(creds);
48
+ (0, log_1.info)(`saving updated default creds to .aws/credentials`);
49
+ const credspath = (0, getCredentialsFilepath_1.getCredentialsFilepath)();
50
+ fs_1.default.writeFileSync(credspath, newcreds);
51
+ });
52
+ exports.updateAwsCredentials = updateAwsCredentials;
@@ -0,0 +1,12 @@
1
+ export declare const closeBrowser: () => Promise<void>;
2
+ export declare const launchBrowser: () => Promise<void>;
3
+ export declare const goToPage: (url: string) => Promise<import("puppeteer").Page>;
4
+ export declare function getMFA(p: {
5
+ verificationUriComplete: string;
6
+ creds: {
7
+ username: string;
8
+ password: string;
9
+ };
10
+ }): Promise<{
11
+ ssoAuthn: string;
12
+ }>;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getMFA = exports.goToPage = exports.launchBrowser = exports.closeBrowser = void 0;
13
+ const log_1 = require("ag-common/dist/common/helpers/log");
14
+ const sleep_1 = require("ag-common/dist/common/helpers/sleep");
15
+ const puppeteer_1 = require("puppeteer");
16
+ const input_1 = require("./input");
17
+ let browser;
18
+ const closeBrowser = () => __awaiter(void 0, void 0, void 0, function* () {
19
+ try {
20
+ if (!browser) {
21
+ return;
22
+ }
23
+ yield browser.close();
24
+ browser = undefined;
25
+ }
26
+ catch (e) {
27
+ (0, log_1.warn)('error closing browser:', e);
28
+ }
29
+ });
30
+ exports.closeBrowser = closeBrowser;
31
+ const launchBrowser = () => __awaiter(void 0, void 0, void 0, function* () {
32
+ const opt = {
33
+ defaultViewport: { height: 1000, width: 500 },
34
+ headless: true,
35
+ ignoreHTTPSErrors: true,
36
+ devtools: false,
37
+ };
38
+ if (!opt.args) {
39
+ opt.args = [];
40
+ }
41
+ opt.args.push('--disable-features=AudioServiceOutOfProcess');
42
+ opt.args.push('--disable-features=AudioServiceOutOfProcessKillAtHang');
43
+ opt.args.push('--disable-software-rasterizer');
44
+ opt.args.push('--disable-gpu');
45
+ opt.args.push('--disable-dev-shm-usage');
46
+ yield (0, exports.closeBrowser)();
47
+ (0, log_1.debug)('launch browser, opt=', opt);
48
+ browser = (yield (0, puppeteer_1.launch)(opt));
49
+ (0, log_1.debug)('browser created');
50
+ });
51
+ exports.launchBrowser = launchBrowser;
52
+ const goToPage = (url) => __awaiter(void 0, void 0, void 0, function* () {
53
+ try {
54
+ if (!browser) {
55
+ yield (0, exports.launchBrowser)();
56
+ }
57
+ if (!browser) {
58
+ throw new Error('no browser');
59
+ }
60
+ (0, log_1.info)(`go to page:${url}`);
61
+ const page = yield browser.newPage();
62
+ yield page.goto(url, {
63
+ waitUntil: ['networkidle2'],
64
+ timeout: 10000,
65
+ });
66
+ return page;
67
+ }
68
+ catch (e) {
69
+ const em = 'browser error:' + e.toString();
70
+ (0, log_1.error)(em);
71
+ throw new Error(em);
72
+ }
73
+ });
74
+ exports.goToPage = goToPage;
75
+ function getMFA(p) {
76
+ var _a;
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ //go to browser site for auth
79
+ (0, log_1.info)('start mfa');
80
+ const page = yield (0, exports.goToPage)(p.verificationUriComplete);
81
+ (0, log_1.info)('username block');
82
+ yield page.waitForSelector('#username-input');
83
+ yield page.focus('#username-input input');
84
+ yield page.keyboard.type(p.creds.username);
85
+ yield page.$eval('#username-submit-button button', (el) => el.click());
86
+ //
87
+ (0, log_1.info)('password block');
88
+ yield page.waitForSelector('#password-input');
89
+ yield page.focus('#password-input input');
90
+ yield page.keyboard.type(p.creds.password);
91
+ yield page.$eval('#password-submit-button button', (el) => el.click());
92
+ yield (0, sleep_1.sleep)(250);
93
+ yield page.waitForNetworkIdle({ idleTime: 250 });
94
+ //
95
+ try {
96
+ const messageDiv = yield page.waitForSelector('.awsui-alert-message', {
97
+ timeout: 2000,
98
+ });
99
+ const value = yield page.evaluate((el) => { var _a; return (_a = el === null || el === void 0 ? void 0 : el.textContent) !== null && _a !== void 0 ? _a : ''; }, messageDiv);
100
+ if (value) {
101
+ throw new Error(value);
102
+ }
103
+ }
104
+ catch (e) {
105
+ const em = e.toString();
106
+ if (!em.includes('exceeded')) {
107
+ const em2 = `creds error:` + em;
108
+ (0, log_1.error)(em2);
109
+ throw new Error(em2);
110
+ }
111
+ }
112
+ //
113
+ let retry = true;
114
+ do {
115
+ (0, log_1.info)('mfa block');
116
+ const { mfa } = (0, input_1.enterMFA)();
117
+ yield page.waitForSelector('#input-0');
118
+ yield page.focus('#input-0 input');
119
+ yield page.keyboard.type(mfa);
120
+ yield page.$eval('.awsui-signin-button-container button', (el) => el.click());
121
+ //
122
+ try {
123
+ yield (0, sleep_1.sleep)(250);
124
+ yield page.waitForNetworkIdle({ idleTime: 250 });
125
+ const messageDiv = yield page.waitForSelector('.awsui-alert-message', {
126
+ timeout: 2000,
127
+ });
128
+ const value = yield page.evaluate((el) => { var _a; return (_a = el === null || el === void 0 ? void 0 : el.textContent) !== null && _a !== void 0 ? _a : ''; }, messageDiv);
129
+ if (value) {
130
+ throw new Error(value);
131
+ }
132
+ retry = false;
133
+ }
134
+ catch (e) {
135
+ const em = e.toString();
136
+ if (!em.includes('exceeded')) {
137
+ const em2 = `mfa error:` + em + ' retry';
138
+ (0, log_1.error)(em2);
139
+ }
140
+ else {
141
+ retry = false;
142
+ }
143
+ }
144
+ } while (retry);
145
+ //
146
+ yield (0, sleep_1.sleep)(3000);
147
+ yield page.waitForNetworkIdle({ idleTime: 250 });
148
+ yield page.waitForSelector('#cli_login_button', { timeout: 5000 });
149
+ yield page.$eval('#cli_login_button', (el) => el.click());
150
+ yield (0, sleep_1.sleep)(250);
151
+ yield page.waitForNetworkIdle({ idleTime: 250 });
152
+ yield page.waitForSelector('.awsui-icon-variant-success', { timeout: 5000 });
153
+ (0, log_1.warn)('mfa success');
154
+ const cookies = yield (page === null || page === void 0 ? void 0 : page.cookies());
155
+ const ssoAuthn = (_a = cookies === null || cookies === void 0 ? void 0 : cookies.find((c) => c.name === 'x-amz-sso_authn')) === null || _a === void 0 ? void 0 : _a.value;
156
+ if (!ssoAuthn) {
157
+ throw new Error('no aws authn');
158
+ }
159
+ yield (0, exports.closeBrowser)();
160
+ return { ssoAuthn };
161
+ });
162
+ }
163
+ exports.getMFA = getMFA;
@@ -0,0 +1,10 @@
1
+ import { IAppInstance, IApplicationArgs } from '../types';
2
+ export declare function chooseAppInstance(ai: IAppInstance[], args: IApplicationArgs): Promise<IAppInstance>;
3
+ export declare function readArguments(): Promise<IApplicationArgs>;
4
+ export declare function enterCreds(): {
5
+ username: string;
6
+ password: string;
7
+ };
8
+ export declare function enterMFA(): {
9
+ mfa: string;
10
+ };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.enterMFA = exports.enterCreds = exports.readArguments = exports.chooseAppInstance = void 0;
16
+ const log_1 = require("ag-common/dist/common/helpers/log");
17
+ const string_1 = require("ag-common/dist/common/helpers/string");
18
+ const cli_select_1 = __importDefault(require("cli-select"));
19
+ const readline_sync_1 = require("readline-sync");
20
+ const yargs_1 = __importDefault(require("yargs"));
21
+ const helpers_1 = require("yargs/helpers");
22
+ const valueRenderer = (a) => `${a.name} [${a.id}]`;
23
+ function chooseAppInstance(ai, args) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ let ret;
26
+ if (args.applicationfilter) {
27
+ ret = ai.find((a) => (0, string_1.containsInsensitive)(valueRenderer(a), args.applicationfilter));
28
+ if (!ret) {
29
+ throw new Error('didnt find application with filter');
30
+ }
31
+ }
32
+ if (ret) {
33
+ (0, log_1.info)(`preselecting ${valueRenderer(ret)} from input ${args.applicationfilter}`);
34
+ return ret;
35
+ }
36
+ (0, log_1.info)('Choose app instance to connect to');
37
+ const res = yield (0, cli_select_1.default)({
38
+ values: ai,
39
+ valueRenderer,
40
+ });
41
+ return res.value;
42
+ });
43
+ }
44
+ exports.chooseAppInstance = chooseAppInstance;
45
+ function readArguments() {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ const { applicationfilter, verbose, wipe, config } = yield (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
48
+ .help('h')
49
+ .alias('h', 'help')
50
+ .option('applicationfilter', {
51
+ alias: 'af',
52
+ type: 'string',
53
+ description: 'Will select account that matches passed in string',
54
+ })
55
+ .boolean('verbose')
56
+ .alias('v', 'verbose')
57
+ .default('verbose', true)
58
+ .boolean('wipe')
59
+ .alias('w', 'wipe')
60
+ .default('wipe', false)
61
+ .boolean('config')
62
+ .alias('c', 'config')
63
+ .default('config', false)
64
+ .parse();
65
+ return { applicationfilter, verbose, wipe, config };
66
+ });
67
+ }
68
+ exports.readArguments = readArguments;
69
+ function enterCreds() {
70
+ const username = (0, readline_sync_1.question)('Enter username:');
71
+ const password = (0, readline_sync_1.question)('Enter password:', {
72
+ hideEchoBack: true,
73
+ });
74
+ return { username, password };
75
+ }
76
+ exports.enterCreds = enterCreds;
77
+ function enterMFA() {
78
+ return {
79
+ mfa: (0, readline_sync_1.question)('Enter MFA code:', {
80
+ min: 6,
81
+ max: 6,
82
+ hideEchoBack: true,
83
+ }),
84
+ };
85
+ }
86
+ exports.enterMFA = enterMFA;
@@ -0,0 +1,5 @@
1
+ import { IAwsCreds } from '../types';
2
+ export declare function requestMFA(p: {
3
+ identityCenterRegion: string;
4
+ ssoStartUrl: string;
5
+ }): Promise<IAwsCreds>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.requestMFA = void 0;
13
+ const client_sso_oidc_1 = require("@aws-sdk/client-sso-oidc");
14
+ const log_1 = require("ag-common/dist/common/helpers/log");
15
+ const sleep_1 = require("ag-common/dist/common/helpers/sleep");
16
+ const config_1 = require("../config");
17
+ const browser_1 = require("./browser");
18
+ const input_1 = require("./input");
19
+ function requestMFA(p) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const sso_oidc = new client_sso_oidc_1.SSOOIDCClient({ region: p.identityCenterRegion });
22
+ (0, log_1.warn)('starting MFA flow');
23
+ const creds = (0, input_1.enterCreds)();
24
+ const rcc = yield sso_oidc.send(new client_sso_oidc_1.RegisterClientCommand({
25
+ clientName: creds.username,
26
+ clientType: 'public',
27
+ }));
28
+ const sda = yield sso_oidc.send(new client_sso_oidc_1.StartDeviceAuthorizationCommand({
29
+ clientId: rcc.clientId,
30
+ clientSecret: rcc.clientSecret,
31
+ startUrl: p.ssoStartUrl,
32
+ }));
33
+ if (!sda.verificationUriComplete) {
34
+ throw new Error('no verif url');
35
+ }
36
+ const { ssoAuthn } = yield (0, browser_1.getMFA)({
37
+ verificationUriComplete: sda.verificationUriComplete,
38
+ creds,
39
+ });
40
+ let accessToken;
41
+ //keep trying to receive auth until user clicks, or timeout
42
+ let trycount = 0;
43
+ do {
44
+ if (trycount > 3) {
45
+ throw new Error('too many fails');
46
+ }
47
+ trycount += 1;
48
+ try {
49
+ const ctc = yield sso_oidc.send(new client_sso_oidc_1.CreateTokenCommand({
50
+ clientId: rcc.clientId,
51
+ clientSecret: rcc.clientSecret,
52
+ code: sda.userCode,
53
+ deviceCode: sda.deviceCode,
54
+ grantType: 'urn:ietf:params:oauth:grant-type:device_code',
55
+ }));
56
+ accessToken = ctc.accessToken;
57
+ if (!accessToken) {
58
+ throw new Error('no access token');
59
+ }
60
+ }
61
+ catch (e) {
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ const es = e.toString();
64
+ if (!es.includes('AuthorizationPendingException')) {
65
+ throw e;
66
+ }
67
+ (0, log_1.warn)('waiting for device approval...');
68
+ yield (0, sleep_1.sleep)(5000);
69
+ }
70
+ } while (!accessToken);
71
+ return {
72
+ accessToken,
73
+ ssoAuthn,
74
+ region: (0, config_1.identityCenterRegion)(),
75
+ accessKeyId: '',
76
+ secretAccessKey: '',
77
+ sessionToken: '',
78
+ };
79
+ });
80
+ }
81
+ exports.requestMFA = requestMFA;
@@ -0,0 +1,21 @@
1
+ import { IAppInstance, IAwsCreds } from '../types';
2
+ export declare const getAssumedRole: (p: {
3
+ accessToken: string;
4
+ accountId?: string;
5
+ }) => Promise<{
6
+ accountId: string;
7
+ roleName: string;
8
+ }>;
9
+ export declare const getOIDCCredentialsFromAccessToken: (p: {
10
+ accessToken: string;
11
+ ssoAuthn: string;
12
+ }) => Promise<IAwsCreds>;
13
+ export declare function appInstances(p: {
14
+ ssoAuthn: string;
15
+ }): Promise<IAppInstance[]>;
16
+ export declare function getSamlAssertion(p: IAwsCreds, instance: IAppInstance): Promise<{
17
+ samlAssertion: string;
18
+ providerArn: string;
19
+ roleArn: string;
20
+ }>;
21
+ export declare const tryExistingCredentials: () => Promise<IAwsCreds | undefined>;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.tryExistingCredentials = exports.getSamlAssertion = exports.appInstances = exports.getOIDCCredentialsFromAccessToken = exports.getAssumedRole = void 0;
16
+ const client_sso_1 = require("@aws-sdk/client-sso");
17
+ const log_1 = require("ag-common/dist/common/helpers/log");
18
+ const string_1 = require("ag-common/dist/common/helpers/string");
19
+ const node_fetch_1 = __importDefault(require("node-fetch"));
20
+ const config_1 = require("../config");
21
+ const awsconfig_1 = require("./awsconfig");
22
+ const sts_1 = require("./sts");
23
+ const getAssumedRole = (p) => __awaiter(void 0, void 0, void 0, function* () {
24
+ var _a, _b, _c, _d;
25
+ const sso = new client_sso_1.SSOClient({ region: (0, config_1.identityCenterRegion)() });
26
+ let accountId = p.accountId;
27
+ if (!accountId) {
28
+ const accounts = yield sso.send(new client_sso_1.ListAccountsCommand({ accessToken: p.accessToken }));
29
+ accountId = (_b = (_a = accounts.accountList) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.accountId;
30
+ }
31
+ if (!accountId) {
32
+ throw new Error('no account id');
33
+ }
34
+ const rolesResult = yield sso.send(new client_sso_1.ListAccountRolesCommand({
35
+ accessToken: p.accessToken,
36
+ accountId,
37
+ }));
38
+ const roles = ((_d = (_c = rolesResult.roleList) === null || _c === void 0 ? void 0 : _c.map((r) => ({
39
+ accountId: r.accountId || '',
40
+ roleName: r.roleName || '',
41
+ }))) === null || _d === void 0 ? void 0 : _d.filter((r) => r.accountId && r.roleName)) || [];
42
+ if (roles.length === 0) {
43
+ throw new Error('no roles can be assumed');
44
+ }
45
+ if (roles.length > 1) {
46
+ throw new Error('too many roles' + JSON.stringify(roles, null, 2));
47
+ }
48
+ const role = roles[0];
49
+ return role;
50
+ });
51
+ exports.getAssumedRole = getAssumedRole;
52
+ const getOIDCCredentialsFromAccessToken = (p) => __awaiter(void 0, void 0, void 0, function* () {
53
+ const sso = new client_sso_1.SSOClient({ region: (0, config_1.identityCenterRegion)() });
54
+ const role = yield (0, exports.getAssumedRole)({ accessToken: p.accessToken });
55
+ const ssoResp = yield sso.send(new client_sso_1.GetRoleCredentialsCommand(Object.assign(Object.assign({}, role), { accessToken: p.accessToken })));
56
+ const rc = ssoResp.roleCredentials;
57
+ if (!(rc === null || rc === void 0 ? void 0 : rc.accessKeyId) ||
58
+ !(rc === null || rc === void 0 ? void 0 : rc.expiration) ||
59
+ !(rc === null || rc === void 0 ? void 0 : rc.secretAccessKey) ||
60
+ !(rc === null || rc === void 0 ? void 0 : rc.sessionToken)) {
61
+ throw new Error('role creds undefined:' + JSON.stringify(rc, null, 2));
62
+ }
63
+ return Object.assign(Object.assign({}, p), { accessKeyId: rc.accessKeyId, secretAccessKey: rc.secretAccessKey, sessionToken: rc.sessionToken, region: (0, config_1.identityCenterRegion)() });
64
+ });
65
+ exports.getOIDCCredentialsFromAccessToken = getOIDCCredentialsFromAccessToken;
66
+ function appInstances(p) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const ai = (yield (yield (0, node_fetch_1.default)(`https://portal.sso.${(0, config_1.identityCenterRegion)()}.amazonaws.com/instance/appinstances`, { headers: { 'x-amz-sso_bearer_token': p.ssoAuthn } })).json());
69
+ if (!(ai === null || ai === void 0 ? void 0 : ai.result)) {
70
+ throw new Error('appinstance error' + JSON.stringify(ai, null, 2));
71
+ }
72
+ return ai.result;
73
+ });
74
+ }
75
+ exports.appInstances = appInstances;
76
+ function getSamlAssertion(p, instance) {
77
+ var _a, _b;
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ const det = (yield (yield (0, node_fetch_1.default)(`https://portal.sso.${(0, config_1.identityCenterRegion)()}.amazonaws.com/instance/appinstance/${instance.id}/profiles`, { headers: { 'x-amz-sso_bearer_token': p.ssoAuthn } })).json());
80
+ const asserturl = (_b = (_a = det === null || det === void 0 ? void 0 : det.result) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.url;
81
+ if (!asserturl) {
82
+ throw new Error('assertion url cant be found');
83
+ }
84
+ const assertion = (yield (yield (0, node_fetch_1.default)(asserturl, {
85
+ headers: { 'x-amz-sso_bearer_token': p.ssoAuthn },
86
+ })).json());
87
+ const decoded = (0, string_1.fromBase64)(assertion.encodedResponse);
88
+ const res = new RegExp(/<saml2:AttributeValue xmlns:xsi="http:\/\/www.w3.org\/2001\/XMLSchema-instance" xsi:type="xsd:string">(arn.*?)</gim).exec(decoded);
89
+ if (!(res === null || res === void 0 ? void 0 : res[1])) {
90
+ throw new Error('bad saml');
91
+ }
92
+ const [providerArn, roleArn] = res[1].split(',');
93
+ return { samlAssertion: assertion.encodedResponse, providerArn, roleArn };
94
+ });
95
+ }
96
+ exports.getSamlAssertion = getSamlAssertion;
97
+ const tryExistingCredentials = () => __awaiter(void 0, void 0, void 0, function* () {
98
+ const credraw = yield (0, awsconfig_1.getAwsCredentials)();
99
+ if (!credraw.default.aws_access_token) {
100
+ return undefined;
101
+ }
102
+ let credentials = {
103
+ accessKeyId: credraw.default.aws_access_key_id,
104
+ secretAccessKey: credraw.default.aws_secret_access_key,
105
+ sessionToken: credraw.default.aws_session_token,
106
+ accessToken: credraw.default.aws_access_token,
107
+ ssoAuthn: credraw.default.aws_sso_authn,
108
+ region: (0, config_1.identityCenterRegion)(),
109
+ };
110
+ const v = yield (0, sts_1.validateCredentials)(credentials);
111
+ if (v) {
112
+ return credentials;
113
+ }
114
+ if (credraw.default.aws_access_token && credraw.default.aws_sso_authn) {
115
+ try {
116
+ (0, log_1.info)('trying oidc refresh');
117
+ credentials = yield (0, exports.getOIDCCredentialsFromAccessToken)({
118
+ accessToken: credraw.default.aws_access_token,
119
+ ssoAuthn: credraw.default.aws_sso_authn,
120
+ });
121
+ return credentials;
122
+ }
123
+ catch (e) {
124
+ //
125
+ (0, log_1.info)('access token or sso expired, need to wipe', e);
126
+ }
127
+ }
128
+ return {
129
+ accessToken: '',
130
+ ssoAuthn: '',
131
+ region: (0, config_1.identityCenterRegion)(),
132
+ accessKeyId: '',
133
+ secretAccessKey: '',
134
+ sessionToken: '',
135
+ };
136
+ });
137
+ exports.tryExistingCredentials = tryExistingCredentials;
@@ -0,0 +1,24 @@
1
+ import { IAwsCreds, SearchMetadata } from '../types';
2
+ export declare function validateCredentials(credentials: IAwsCreds): Promise<{
3
+ accountId: string;
4
+ principalArn: string;
5
+ } | undefined>;
6
+ export declare function getApplicationCreds(p: {
7
+ originCreds: IAwsCreds;
8
+ targetRegion: string;
9
+ samlAssertion: string;
10
+ providerArn: string;
11
+ roleArn: string;
12
+ }): Promise<IAwsCreds>;
13
+ export declare function directStsAssume(p: {
14
+ credentials: IAwsCreds;
15
+ targetRegion: string;
16
+ metadata: SearchMetadata;
17
+ }): Promise<{
18
+ region: string;
19
+ accessKeyId: string;
20
+ secretAccessKey: string;
21
+ sessionToken: string;
22
+ accessToken: string;
23
+ ssoAuthn: string;
24
+ }>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.directStsAssume = exports.getApplicationCreds = exports.validateCredentials = void 0;
13
+ const client_sts_1 = require("@aws-sdk/client-sts");
14
+ const log_1 = require("ag-common/dist/common/helpers/log");
15
+ const config_1 = require("../config");
16
+ const sso_1 = require("./sso");
17
+ function validateCredentials(credentials) {
18
+ var _a, _b;
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const sts = new client_sts_1.STS({
21
+ credentials,
22
+ region: credentials.region,
23
+ });
24
+ try {
25
+ const stub = yield sts.getCallerIdentity({});
26
+ yield (0, sso_1.appInstances)(credentials);
27
+ if (((_b = (_a = stub === null || stub === void 0 ? void 0 : stub.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode) !== null && _b !== void 0 ? _b : 500) < 400 &&
28
+ stub.Account &&
29
+ stub.Arn) {
30
+ (0, log_1.info)(`test cached credentials OK`);
31
+ return { accountId: stub.Account, principalArn: stub.Arn };
32
+ }
33
+ }
34
+ catch (e) {
35
+ const es = e.toString();
36
+ if (es.includes('expired')) {
37
+ (0, log_1.warn)('creds have expired');
38
+ }
39
+ (0, log_1.warn)('other saml error:' + es);
40
+ return undefined;
41
+ }
42
+ });
43
+ }
44
+ exports.validateCredentials = validateCredentials;
45
+ function getApplicationCreds(p) {
46
+ var _a, _b, _c, _d;
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const sts = new client_sts_1.STS({
49
+ credentials: p.originCreds,
50
+ region: p.targetRegion,
51
+ });
52
+ const ret = yield sts.assumeRoleWithSAML({
53
+ PrincipalArn: p.providerArn,
54
+ RoleArn: p.roleArn,
55
+ SAMLAssertion: p.samlAssertion,
56
+ DurationSeconds: config_1.stsDurationSeconds,
57
+ });
58
+ if (((_a = ret.$metadata.httpStatusCode) !== null && _a !== void 0 ? _a : 500) >= 400) {
59
+ (0, log_1.error)('bad assume saml role', ret);
60
+ throw new Error('bad assume saml role');
61
+ }
62
+ if (!((_b = ret === null || ret === void 0 ? void 0 : ret.Credentials) === null || _b === void 0 ? void 0 : _b.AccessKeyId) ||
63
+ !((_c = ret === null || ret === void 0 ? void 0 : ret.Credentials) === null || _c === void 0 ? void 0 : _c.SecretAccessKey) ||
64
+ !((_d = ret === null || ret === void 0 ? void 0 : ret.Credentials) === null || _d === void 0 ? void 0 : _d.SessionToken)) {
65
+ throw new Error('no creds');
66
+ }
67
+ return Object.assign(Object.assign({}, p.originCreds), { region: p.targetRegion, accessKeyId: ret.Credentials.AccessKeyId, secretAccessKey: ret.Credentials.SecretAccessKey, sessionToken: ret.Credentials.SessionToken });
68
+ });
69
+ }
70
+ exports.getApplicationCreds = getApplicationCreds;
71
+ function directStsAssume(p) {
72
+ var _a, _b, _c, _d;
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const role = yield (0, sso_1.getAssumedRole)({
75
+ accessToken: p.credentials.accessToken,
76
+ accountId: p.metadata.AccountId,
77
+ });
78
+ const sts = new client_sts_1.STS({
79
+ credentials: p.credentials,
80
+ region: p.targetRegion,
81
+ });
82
+ const ar = yield sts.assumeRole({
83
+ RoleArn: `arn:aws:iam::${role.accountId}:role/${role.roleName}`,
84
+ RoleSessionName: 'awsauth',
85
+ DurationSeconds: config_1.nativeStsDurationSeconds,
86
+ });
87
+ if (((_a = ar.$metadata.httpStatusCode) !== null && _a !== void 0 ? _a : 500) >= 400) {
88
+ throw new Error('assume role error' + JSON.stringify(ar, null, 2));
89
+ }
90
+ if (!((_b = ar === null || ar === void 0 ? void 0 : ar.Credentials) === null || _b === void 0 ? void 0 : _b.AccessKeyId) ||
91
+ !((_c = ar === null || ar === void 0 ? void 0 : ar.Credentials) === null || _c === void 0 ? void 0 : _c.SecretAccessKey) ||
92
+ !((_d = ar === null || ar === void 0 ? void 0 : ar.Credentials) === null || _d === void 0 ? void 0 : _d.SessionToken)) {
93
+ throw new Error('no creds');
94
+ }
95
+ return Object.assign(Object.assign({}, p.credentials), { region: p.targetRegion, accessKeyId: ar.Credentials.AccessKeyId, secretAccessKey: ar.Credentials.SecretAccessKey, sessionToken: ar.Credentials.SessionToken });
96
+ });
97
+ }
98
+ exports.directStsAssume = directStsAssume;
@@ -0,0 +1,3 @@
1
+ import { IApplicationArgs } from './types';
2
+ export declare function main(args: IApplicationArgs): Promise<void>;
3
+ export declare function run(): Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.run = exports.main = void 0;
16
+ /* eslint-disable padding-line-between-statements */
17
+ const log_1 = require("ag-common/dist/common/helpers/log");
18
+ const dotenv_1 = require("dotenv");
19
+ const fs_1 = __importDefault(require("fs"));
20
+ const config_1 = require("./config");
21
+ const awsconfig_1 = require("./helpers/awsconfig");
22
+ const input_1 = require("./helpers/input");
23
+ const oidc_1 = require("./helpers/oidc");
24
+ const sso_1 = require("./helpers/sso");
25
+ const sts_1 = require("./helpers/sts");
26
+ (0, dotenv_1.config)();
27
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
28
+ const beep = require('node-beep');
29
+ function main(args) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ (0, log_1.SetLogLevel)(args.verbose ? 'INFO' : 'WARN');
32
+ (0, log_1.SetLogShim)((...a1) => {
33
+ // eslint-disable-next-line no-console
34
+ console.log(...a1);
35
+ try {
36
+ fs_1.default.appendFileSync(config_1.logPath, JSON.stringify(a1, null, 2));
37
+ }
38
+ catch (e) {
39
+ //
40
+ }
41
+ });
42
+ if (args.config) {
43
+ (0, log_1.info)('running config');
44
+ (0, config_1.runConfig)();
45
+ return;
46
+ }
47
+ if (!(0, config_1.validateConfig)()) {
48
+ console.error('please run config (-c)');
49
+ return;
50
+ }
51
+ if (args.wipe) {
52
+ (0, log_1.info)('wiping args');
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ yield (0, awsconfig_1.updateAwsCredentials)(undefined);
55
+ return;
56
+ }
57
+ let credentials = yield (0, sso_1.tryExistingCredentials)();
58
+ if (!(credentials === null || credentials === void 0 ? void 0 : credentials.accessToken) || !(credentials === null || credentials === void 0 ? void 0 : credentials.ssoAuthn)) {
59
+ (0, log_1.info)('no creds, get access token through manual sign in');
60
+ credentials = yield (0, oidc_1.requestMFA)({
61
+ identityCenterRegion: (0, config_1.identityCenterRegion)(),
62
+ ssoStartUrl: (0, config_1.ssoStartUrl)(),
63
+ });
64
+ (0, log_1.info)('get oidc creds');
65
+ credentials = yield (0, sso_1.getOIDCCredentialsFromAccessToken)(credentials);
66
+ }
67
+ //
68
+ (0, log_1.info)('save aws creds to file');
69
+ yield (0, awsconfig_1.updateAwsCredentials)(credentials);
70
+ (0, log_1.info)('get app instances and display');
71
+ const instances = yield (0, sso_1.appInstances)(credentials);
72
+ const instance = yield (0, input_1.chooseAppInstance)(instances, args);
73
+ let debugRole = '';
74
+ if (instance.searchMetadata) {
75
+ (0, log_1.info)('account is native aws, directly connecting');
76
+ credentials = yield (0, sts_1.directStsAssume)({
77
+ credentials,
78
+ targetRegion: (0, config_1.targetRegion)(),
79
+ metadata: instance.searchMetadata,
80
+ });
81
+ debugRole = instance.searchMetadata.AccountId;
82
+ }
83
+ else {
84
+ (0, log_1.info)('account is external app, getting saml');
85
+ const samlDetails = yield (0, sso_1.getSamlAssertion)(credentials, instance);
86
+ credentials = yield (0, sts_1.getApplicationCreds)(Object.assign(Object.assign({}, samlDetails), { originCreds: credentials, targetRegion: (0, config_1.targetRegion)() }));
87
+ debugRole = samlDetails.roleArn;
88
+ }
89
+ yield (0, awsconfig_1.updateAwsCredentials)(credentials);
90
+ (0, log_1.warn)(`successfully authed into ${debugRole}`);
91
+ });
92
+ }
93
+ exports.main = main;
94
+ function run() {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ try {
97
+ const args = yield (0, input_1.readArguments)();
98
+ yield main(args);
99
+ beep(1);
100
+ }
101
+ catch (e) {
102
+ (0, log_1.error)('error:' + e);
103
+ beep(2);
104
+ if (e === null || e === void 0 ? void 0 : e.toString) {
105
+ (0, log_1.error)('error:' + e.toString());
106
+ }
107
+ }
108
+ });
109
+ }
110
+ exports.run = run;
@@ -0,0 +1,55 @@
1
+ export interface IAwsCreds {
2
+ accessKeyId: string;
3
+ secretAccessKey: string;
4
+ sessionToken: string;
5
+ region: string;
6
+ accessToken: string;
7
+ ssoAuthn: string;
8
+ }
9
+ export interface IAwsCredsRaw {
10
+ region: string;
11
+ aws_access_key_id: string;
12
+ aws_secret_access_key: string;
13
+ aws_session_token: string;
14
+ aws_access_token: string;
15
+ aws_sso_authn: string;
16
+ aws_application_id: string;
17
+ }
18
+ export interface IAppInstances {
19
+ result: IAppInstance[];
20
+ }
21
+ export interface IAppInstance {
22
+ id: string;
23
+ name: string;
24
+ description: string;
25
+ applicationId: string;
26
+ applicationName: string;
27
+ icon: string;
28
+ searchMetadata?: SearchMetadata;
29
+ }
30
+ export interface SearchMetadata {
31
+ AccountId: string;
32
+ AccountName: string;
33
+ AccountEmail: string;
34
+ }
35
+ export interface IAppInstanceDetails {
36
+ result: IAppInstanceDetailsResult[];
37
+ }
38
+ export interface IAppInstanceDetailsResult {
39
+ id: string;
40
+ name: string;
41
+ description: string;
42
+ url: string;
43
+ protocol: string;
44
+ }
45
+ export interface ISamlAssertion {
46
+ encodedResponse: string;
47
+ destination: string;
48
+ prettyPrintedXml: string;
49
+ }
50
+ export interface IApplicationArgs {
51
+ applicationfilter?: string;
52
+ verbose: boolean;
53
+ wipe: boolean;
54
+ config: boolean;
55
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "ag-awsauth",
3
+ "description": "auth to aws sso/iamv2 easily",
4
+ "main": "dist/index.js",
5
+ "author": "andrei gec (andreigec@hotmail.com)",
6
+ "license": "ISC",
7
+ "private": false,
8
+ "version": "0.0.1",
9
+ "preferGlobal": true,
10
+ "bin": {
11
+ "awsauth": "./bin/awsauth.js"
12
+ },
13
+ "files": [
14
+ "bin/**/*",
15
+ "dist/**/*",
16
+ "README.md",
17
+ "LICENSE.md"
18
+ ],
19
+ "dependencies": {
20
+ "@aws-sdk/client-sso": "3.271.0",
21
+ "@aws-sdk/client-sso-oidc": "3.271.0",
22
+ "@aws-sdk/client-sts": "3.271.0",
23
+ "@aws-sdk/shared-ini-file-loader": "3.271.0",
24
+ "ag-common": "0.0.412",
25
+ "cli-select": "1.1.2",
26
+ "dotenv": "16.0.3",
27
+ "envfile": "6.18.0",
28
+ "esbuild": "0.17.8",
29
+ "eslint-config-e7npm": "0.0.8",
30
+ "ini": "3.0.1",
31
+ "node-beep": "0.0.3",
32
+ "node-fetch": "2.6.9",
33
+ "puppeteer": "19.7.0",
34
+ "readline-sync": "1.4.10",
35
+ "ts-node": "10.9.1",
36
+ "typescript": "4.9.5",
37
+ "yargs": "17.6.2"
38
+ },
39
+ "devDependencies": {
40
+ "@types/ini": "1.3.31",
41
+ "@types/node": "18.13.0",
42
+ "@types/node-fetch": "2.6.2",
43
+ "@types/readline-sync": "1.4.4",
44
+ "@types/yargs": "17.0.22"
45
+ },
46
+ "engines": {
47
+ "node": ">=16.0.0",
48
+ "yarn": "use pnpm",
49
+ "npm": "use pnpm",
50
+ "pnpm": ">=3"
51
+ },
52
+ "scripts": {
53
+ "format": "eslint --ext .ts,.tsx ./src --fix",
54
+ "lint": "tsc && eslint --ext .ts,.tsx ./src",
55
+ "start": "ts-node src/direct.ts",
56
+ "build": "tsc"
57
+ }
58
+ }