@padua/cli 1.0.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/README.md +158 -0
- package/dist/commands/login/codeartifact.d.ts +11 -0
- package/dist/commands/login/codeartifact.d.ts.map +1 -0
- package/dist/commands/login/codeartifact.js +77 -0
- package/dist/commands/login/codeartifact.js.map +1 -0
- package/dist/commands/login/config.d.ts +11 -0
- package/dist/commands/login/config.d.ts.map +1 -0
- package/dist/commands/login/config.js +99 -0
- package/dist/commands/login/config.js.map +1 -0
- package/dist/commands/login/ecr.d.ts +11 -0
- package/dist/commands/login/ecr.d.ts.map +1 -0
- package/dist/commands/login/ecr.js +107 -0
- package/dist/commands/login/ecr.js.map +1 -0
- package/dist/commands/login/index.d.ts +6 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +177 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/login/sso.d.ts +17 -0
- package/dist/commands/login/sso.d.ts.map +1 -0
- package/dist/commands/login/sso.js +87 -0
- package/dist/commands/login/sso.js.map +1 -0
- package/dist/commands/login/types.d.ts +100 -0
- package/dist/commands/login/types.d.ts.map +1 -0
- package/dist/commands/login/types.js +69 -0
- package/dist/commands/login/types.js.map +1 -0
- package/dist/commands/login/utils.d.ts +24 -0
- package/dist/commands/login/utils.d.ts.map +1 -0
- package/dist/commands/login/utils.js +93 -0
- package/dist/commands/login/utils.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Padua CLI
|
|
2
|
+
|
|
3
|
+
A unified CLI for AWS infrastructure management—authentication, tunneling, and container tools in one place.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @padua/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
- [Node.js](https://nodejs.org/) v18+
|
|
14
|
+
- [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
|
|
15
|
+
- [Session Manager Plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html) (for tunneling)
|
|
16
|
+
- [Docker](https://www.docker.com/) (optional, for ECR)
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# 1. Create config file
|
|
22
|
+
cp padua.config.example.json padua.config.json
|
|
23
|
+
|
|
24
|
+
# 2. Edit with your AWS account details
|
|
25
|
+
# 3. Run login
|
|
26
|
+
padua login
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
| Category | Feature | Description |
|
|
32
|
+
|----------|---------|-------------|
|
|
33
|
+
| **Auth** | SSO Login | AWS SSO authentication and session management |
|
|
34
|
+
| | Profiles | Multiple AWS CLI profile management |
|
|
35
|
+
| | CodeArtifact | Automatic npm registry authentication |
|
|
36
|
+
| | ECR | Docker registry authentication |
|
|
37
|
+
| **Tunnel** | RDS/Aurora | PostgreSQL & MySQL via Session Manager |
|
|
38
|
+
| | OpenSearch | Kibana dashboard access |
|
|
39
|
+
| | EC2 | Direct SSM sessions to instances |
|
|
40
|
+
| **ECS** | Exec | Container command execution with pre-flight checks |
|
|
41
|
+
|
|
42
|
+
## Login Command
|
|
43
|
+
|
|
44
|
+
Authenticate to AWS SSO, CodeArtifact (npm), and ECR (Docker) with a single command.
|
|
45
|
+
|
|
46
|
+
### Basic Usage
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
padua login # Full login (SSO + CodeArtifact + ECR)
|
|
50
|
+
padua login --profile staging # Use specific AWS profile
|
|
51
|
+
padua login --sso-only # SSO only, skip CodeArtifact and ECR
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Options
|
|
55
|
+
|
|
56
|
+
| Flag | Description |
|
|
57
|
+
|------|-------------|
|
|
58
|
+
| `-p, --profile <name>` | AWS SSO profile to use |
|
|
59
|
+
| `--sso-only` | Only authenticate to SSO |
|
|
60
|
+
| `-v, --verbose` | Show detailed output |
|
|
61
|
+
| `-q, --quiet` | Suppress non-error output |
|
|
62
|
+
| `--no-color` | Disable colored output |
|
|
63
|
+
|
|
64
|
+
### Exit Codes
|
|
65
|
+
|
|
66
|
+
| Code | Meaning |
|
|
67
|
+
|------|---------|
|
|
68
|
+
| 0 | Success (SSO + at least one other service) |
|
|
69
|
+
| 1 | SSO succeeded but CodeArtifact and ECR both failed |
|
|
70
|
+
| 2 | SSO failed (other services not attempted) |
|
|
71
|
+
|
|
72
|
+
### What `padua login` replaces
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Before: 3 separate commands
|
|
76
|
+
aws sso login --profile development
|
|
77
|
+
aws codeartifact login --tool npm --repository npm-repo --domain my-domain \
|
|
78
|
+
--domain-owner 123456789012 --region ap-southeast-2 --profile development
|
|
79
|
+
aws ecr get-login-password --region ap-southeast-2 | \
|
|
80
|
+
docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com
|
|
81
|
+
|
|
82
|
+
# After: 1 command
|
|
83
|
+
padua login
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Example Output
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
[1/3] AWS SSO ...
|
|
90
|
+
✓ authenticated (profile: development)
|
|
91
|
+
[2/3] CodeArtifact (npm) ...
|
|
92
|
+
✓ configured
|
|
93
|
+
[3/3] ECR (Docker) ...
|
|
94
|
+
✓ configured
|
|
95
|
+
|
|
96
|
+
=== Login Results ===
|
|
97
|
+
SSO: ✓ OK
|
|
98
|
+
CodeArtifact: ✓ OK
|
|
99
|
+
ECR: ✓ OK
|
|
100
|
+
|
|
101
|
+
Total: 3/3 services authenticated
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
Create a `padua.config.json` file in your project root or `~/.padua/`:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"defaultProfile": "development",
|
|
111
|
+
"region": "ap-southeast-2",
|
|
112
|
+
"codeartifact": {
|
|
113
|
+
"domain": "my-domain",
|
|
114
|
+
"domainOwner": "123456789012",
|
|
115
|
+
"repository": "npm-repo"
|
|
116
|
+
},
|
|
117
|
+
"ecr": {
|
|
118
|
+
"accountId": "123456789012",
|
|
119
|
+
"region": "ap-southeast-2"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Config Priority
|
|
125
|
+
|
|
126
|
+
1. CLI flags (`--profile`)
|
|
127
|
+
2. Environment variables (`PADUA_PROFILE`)
|
|
128
|
+
3. `padua.config.json` in current directory
|
|
129
|
+
4. `~/.padua/padua.config.json`
|
|
130
|
+
5. Default values
|
|
131
|
+
|
|
132
|
+
## Other Commands
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
padua tunnel rds # RDS PostgreSQL via jumpbox
|
|
136
|
+
padua tunnel aurora # Aurora PostgreSQL via jumpbox
|
|
137
|
+
padua tunnel rds --legacy # MySQL via bastion-host (roma)
|
|
138
|
+
padua tunnel opensearch # OpenSearch/Kibana dashboard
|
|
139
|
+
padua tunnel ec2 <name> # SSM session to EC2 instance
|
|
140
|
+
|
|
141
|
+
padua ecs exec <cluster> <task> # Execute in ECS container
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
git clone <repository-url>
|
|
148
|
+
cd padua-cli
|
|
149
|
+
npm install
|
|
150
|
+
npm run build
|
|
151
|
+
npm link # Makes 'padua' available globally
|
|
152
|
+
npm test # Run tests
|
|
153
|
+
npm run test:coverage # Run tests with coverage
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ServiceResult, LoginOptions, CodeArtifactConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Configure npm to use CodeArtifact registry
|
|
4
|
+
*
|
|
5
|
+
* @param config - CodeArtifact configuration
|
|
6
|
+
* @param profile - AWS profile to use
|
|
7
|
+
* @param options - Login command options
|
|
8
|
+
* @returns ServiceResult indicating success/failure
|
|
9
|
+
*/
|
|
10
|
+
export declare function configureCodeArtifact(config: CodeArtifactConfig, profile: string, options: LoginOptions): Promise<ServiceResult>;
|
|
11
|
+
//# sourceMappingURL=codeartifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeartifact.d.ts","sourceRoot":"","sources":["../../../src/commands/login/codeartifact.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAK1E;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CAuExB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureCodeArtifact = configureCodeArtifact;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
const CODEARTIFACT_TIMEOUT_MS = 30000; // 30 seconds
|
|
7
|
+
/**
|
|
8
|
+
* Configure npm to use CodeArtifact registry
|
|
9
|
+
*
|
|
10
|
+
* @param config - CodeArtifact configuration
|
|
11
|
+
* @param profile - AWS profile to use
|
|
12
|
+
* @param options - Login command options
|
|
13
|
+
* @returns ServiceResult indicating success/failure
|
|
14
|
+
*/
|
|
15
|
+
async function configureCodeArtifact(config, profile, options) {
|
|
16
|
+
(0, utils_1.validateProfileName)(profile);
|
|
17
|
+
if (options.verbose) {
|
|
18
|
+
console.log(` [verbose] Configuring CodeArtifact: ${config.domain}/${config.repository}`);
|
|
19
|
+
}
|
|
20
|
+
// Use aws codeartifact login which handles token and npm config
|
|
21
|
+
const args = [
|
|
22
|
+
'codeartifact', 'login',
|
|
23
|
+
'--tool', 'npm',
|
|
24
|
+
'--repository', config.repository,
|
|
25
|
+
'--domain', config.domain,
|
|
26
|
+
'--domain-owner', config.domainOwner,
|
|
27
|
+
'--profile', profile,
|
|
28
|
+
];
|
|
29
|
+
if (options.verbose) {
|
|
30
|
+
console.log(` [verbose] Running: aws ${args.join(' ')}`);
|
|
31
|
+
}
|
|
32
|
+
const result = (0, child_process_1.spawnSync)('aws', args, {
|
|
33
|
+
shell: false,
|
|
34
|
+
timeout: CODEARTIFACT_TIMEOUT_MS,
|
|
35
|
+
maxBuffer: 1024 * 1024,
|
|
36
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
37
|
+
env: {
|
|
38
|
+
...(0, utils_1.getSubprocessEnv)(),
|
|
39
|
+
AWS_PROFILE: profile,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (result.error) {
|
|
43
|
+
if (result.error.message.includes('ENOENT')) {
|
|
44
|
+
throw new Error('AWS CLI not found. Please install AWS CLI v2.');
|
|
45
|
+
}
|
|
46
|
+
if (result.error.message.includes('ETIMEDOUT')) {
|
|
47
|
+
throw new Error('CodeArtifact login timed out.');
|
|
48
|
+
}
|
|
49
|
+
throw new Error((0, utils_1.sanitizeOutput)(result.error.message));
|
|
50
|
+
}
|
|
51
|
+
if (result.status !== 0) {
|
|
52
|
+
const stderr = result.stderr?.toString() || '';
|
|
53
|
+
const stdout = result.stdout?.toString() || '';
|
|
54
|
+
// Parse common error conditions
|
|
55
|
+
if (stderr.includes('ResourceNotFoundException')) {
|
|
56
|
+
throw new Error(`CodeArtifact domain '${config.domain}' or repository '${config.repository}' not found.`);
|
|
57
|
+
}
|
|
58
|
+
if (stderr.includes('AccessDeniedException')) {
|
|
59
|
+
throw new Error(`Access denied to CodeArtifact. Check IAM permissions for profile '${profile}'.`);
|
|
60
|
+
}
|
|
61
|
+
if (stderr.includes('ExpiredTokenException') || stderr.includes('credentials')) {
|
|
62
|
+
throw new Error('AWS credentials expired. SSO session may have ended.');
|
|
63
|
+
}
|
|
64
|
+
const errorOutput = (0, utils_1.sanitizeOutput)(stderr || stdout || 'Unknown error');
|
|
65
|
+
throw new Error(`CodeArtifact login failed: ${errorOutput}`);
|
|
66
|
+
}
|
|
67
|
+
if (options.verbose) {
|
|
68
|
+
const stdout = result.stdout?.toString() || '';
|
|
69
|
+
console.log(` [verbose] CodeArtifact configured: ${(0, utils_1.sanitizeOutput)(stdout)}`);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
skipped: false,
|
|
74
|
+
duration: 0,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=codeartifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeartifact.js","sourceRoot":"","sources":["../../../src/commands/login/codeartifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PaduaConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Load configuration from padua.config.json
|
|
4
|
+
* Returns null if no config file found
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadConfig(): Promise<PaduaConfig | null>;
|
|
7
|
+
/**
|
|
8
|
+
* Save configuration to padua.config.json
|
|
9
|
+
*/
|
|
10
|
+
export declare function saveConfig(config: PaduaConfig, location?: 'local' | 'global'): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/commands/login/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwBtC;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAc9D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAE,OAAO,GAAG,QAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3G"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadConfig = loadConfig;
|
|
37
|
+
exports.saveConfig = saveConfig;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const CONFIG_FILENAME = 'padua.config.json';
|
|
42
|
+
/**
|
|
43
|
+
* Get the path to the config file
|
|
44
|
+
* Priority: 1) Current directory, 2) ~/.padua/
|
|
45
|
+
*/
|
|
46
|
+
function getConfigPath() {
|
|
47
|
+
// Check current directory first
|
|
48
|
+
const localPath = path.join(process.cwd(), CONFIG_FILENAME);
|
|
49
|
+
if (fs.existsSync(localPath)) {
|
|
50
|
+
return localPath;
|
|
51
|
+
}
|
|
52
|
+
// Check ~/.padua/ directory
|
|
53
|
+
const globalPath = path.join(os.homedir(), '.padua', CONFIG_FILENAME);
|
|
54
|
+
if (fs.existsSync(globalPath)) {
|
|
55
|
+
return globalPath;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Load configuration from padua.config.json
|
|
61
|
+
* Returns null if no config file found
|
|
62
|
+
*/
|
|
63
|
+
async function loadConfig() {
|
|
64
|
+
const configPath = getConfigPath();
|
|
65
|
+
if (!configPath) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
70
|
+
const config = JSON.parse(content);
|
|
71
|
+
return config;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw new Error(`Failed to load config from ${configPath}: ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Save configuration to padua.config.json
|
|
79
|
+
*/
|
|
80
|
+
async function saveConfig(config, location = 'local') {
|
|
81
|
+
let configPath;
|
|
82
|
+
if (location === 'global') {
|
|
83
|
+
const paduaDir = path.join(os.homedir(), '.padua');
|
|
84
|
+
if (!fs.existsSync(paduaDir)) {
|
|
85
|
+
fs.mkdirSync(paduaDir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
configPath = path.join(paduaDir, CONFIG_FILENAME);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
configPath = path.join(process.cwd(), CONFIG_FILENAME);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new Error(`Failed to save config to ${configPath}: ${error.message}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/commands/login/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,gCAcC;AAKD,gCAkBC;AApED,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGzB,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C;;;GAGG;AACH,SAAS,aAAa;IACpB,gCAAgC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,4BAA4B;IAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACtE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAClD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,MAAmB,EAAE,WAA+B,OAAO;IAC1F,IAAI,UAAkB,CAAC;IAEvB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ServiceResult, LoginOptions, EcrConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Configure Docker to use ECR registry
|
|
4
|
+
*
|
|
5
|
+
* @param config - ECR configuration
|
|
6
|
+
* @param profile - AWS profile to use
|
|
7
|
+
* @param options - Login command options
|
|
8
|
+
* @returns ServiceResult indicating success/failure
|
|
9
|
+
*/
|
|
10
|
+
export declare function configureECR(config: EcrConfig, profile: string, options: LoginOptions): Promise<ServiceResult>;
|
|
11
|
+
//# sourceMappingURL=ecr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecr.d.ts","sourceRoot":"","sources":["../../../src/commands/login/ecr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAKjE;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA6GxB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureECR = configureECR;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
const ECR_TIMEOUT_MS = 30000; // 30 seconds
|
|
7
|
+
/**
|
|
8
|
+
* Configure Docker to use ECR registry
|
|
9
|
+
*
|
|
10
|
+
* @param config - ECR configuration
|
|
11
|
+
* @param profile - AWS profile to use
|
|
12
|
+
* @param options - Login command options
|
|
13
|
+
* @returns ServiceResult indicating success/failure
|
|
14
|
+
*/
|
|
15
|
+
async function configureECR(config, profile, options) {
|
|
16
|
+
(0, utils_1.validateProfileName)(profile);
|
|
17
|
+
const registryUrl = `${config.accountId}.dkr.ecr.${config.region}.amazonaws.com`;
|
|
18
|
+
if (options.verbose) {
|
|
19
|
+
console.log(` [verbose] Configuring ECR: ${registryUrl}`);
|
|
20
|
+
}
|
|
21
|
+
// Check if Docker is running
|
|
22
|
+
const dockerCheck = (0, child_process_1.spawnSync)('docker', ['info'], {
|
|
23
|
+
shell: false,
|
|
24
|
+
timeout: 5000,
|
|
25
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
26
|
+
env: (0, utils_1.getSubprocessEnv)(),
|
|
27
|
+
});
|
|
28
|
+
if (dockerCheck.status !== 0) {
|
|
29
|
+
throw new Error('Docker is not running. Please start Docker Desktop or Docker daemon.');
|
|
30
|
+
}
|
|
31
|
+
// Get ECR login password
|
|
32
|
+
if (options.verbose) {
|
|
33
|
+
console.log(` [verbose] Running: aws ecr get-login-password --region ${config.region} --profile ${profile}`);
|
|
34
|
+
}
|
|
35
|
+
const getPasswordResult = (0, child_process_1.spawnSync)('aws', [
|
|
36
|
+
'ecr', 'get-login-password',
|
|
37
|
+
'--region', config.region,
|
|
38
|
+
'--profile', profile,
|
|
39
|
+
], {
|
|
40
|
+
shell: false,
|
|
41
|
+
timeout: ECR_TIMEOUT_MS,
|
|
42
|
+
maxBuffer: 1024 * 1024,
|
|
43
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
|
+
env: {
|
|
45
|
+
...(0, utils_1.getSubprocessEnv)(),
|
|
46
|
+
AWS_PROFILE: profile,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
if (getPasswordResult.error) {
|
|
50
|
+
if (getPasswordResult.error.message.includes('ENOENT')) {
|
|
51
|
+
throw new Error('AWS CLI not found. Please install AWS CLI v2.');
|
|
52
|
+
}
|
|
53
|
+
if (getPasswordResult.error.message.includes('ETIMEDOUT')) {
|
|
54
|
+
throw new Error('ECR get-login-password timed out.');
|
|
55
|
+
}
|
|
56
|
+
throw new Error((0, utils_1.sanitizeOutput)(getPasswordResult.error.message));
|
|
57
|
+
}
|
|
58
|
+
if (getPasswordResult.status !== 0) {
|
|
59
|
+
const stderr = getPasswordResult.stderr?.toString() || '';
|
|
60
|
+
if (stderr.includes('ExpiredTokenException') || stderr.includes('credentials')) {
|
|
61
|
+
throw new Error('AWS credentials expired. SSO session may have ended.');
|
|
62
|
+
}
|
|
63
|
+
if (stderr.includes('AccessDeniedException')) {
|
|
64
|
+
throw new Error(`Access denied to ECR. Check IAM permissions for profile '${profile}'.`);
|
|
65
|
+
}
|
|
66
|
+
const errorOutput = (0, utils_1.sanitizeOutput)(stderr || 'Unknown error');
|
|
67
|
+
throw new Error(`ECR get-login-password failed: ${errorOutput}`);
|
|
68
|
+
}
|
|
69
|
+
const password = getPasswordResult.stdout?.toString().trim();
|
|
70
|
+
if (!password) {
|
|
71
|
+
throw new Error('ECR returned empty password.');
|
|
72
|
+
}
|
|
73
|
+
// Docker login using the password
|
|
74
|
+
if (options.verbose) {
|
|
75
|
+
console.log(` [verbose] Running: docker login --username AWS --password-stdin ${registryUrl}`);
|
|
76
|
+
}
|
|
77
|
+
const dockerLoginResult = (0, child_process_1.spawnSync)('docker', [
|
|
78
|
+
'login',
|
|
79
|
+
'--username', 'AWS',
|
|
80
|
+
'--password-stdin',
|
|
81
|
+
registryUrl,
|
|
82
|
+
], {
|
|
83
|
+
shell: false,
|
|
84
|
+
timeout: ECR_TIMEOUT_MS,
|
|
85
|
+
maxBuffer: 1024 * 1024,
|
|
86
|
+
input: password,
|
|
87
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
88
|
+
env: (0, utils_1.getSubprocessEnv)(),
|
|
89
|
+
});
|
|
90
|
+
if (dockerLoginResult.error) {
|
|
91
|
+
throw new Error((0, utils_1.sanitizeOutput)(dockerLoginResult.error.message));
|
|
92
|
+
}
|
|
93
|
+
if (dockerLoginResult.status !== 0) {
|
|
94
|
+
const stderr = dockerLoginResult.stderr?.toString() || '';
|
|
95
|
+
const errorOutput = (0, utils_1.sanitizeOutput)(stderr || 'Unknown error');
|
|
96
|
+
throw new Error(`Docker login failed: ${errorOutput}`);
|
|
97
|
+
}
|
|
98
|
+
if (options.verbose) {
|
|
99
|
+
console.log(' [verbose] ECR authentication successful');
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
skipped: false,
|
|
104
|
+
duration: 0,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=ecr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecr.js","sourceRoot":"","sources":["../../../src/commands/login/ecr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;GAEG;AACH,eAAO,MAAM,YAAY,SAOH,CAAC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
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.loginCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const config_1 = require("./config");
|
|
10
|
+
const sso_1 = require("./sso");
|
|
11
|
+
const codeartifact_1 = require("./codeartifact");
|
|
12
|
+
const ecr_1 = require("./ecr");
|
|
13
|
+
const types_1 = require("./types");
|
|
14
|
+
/**
|
|
15
|
+
* Main login command that orchestrates SSO, CodeArtifact, and ECR authentication
|
|
16
|
+
*/
|
|
17
|
+
exports.loginCommand = new commander_1.Command('login')
|
|
18
|
+
.description('Authenticate to AWS SSO, CodeArtifact (npm), and ECR (Docker)')
|
|
19
|
+
.option('-p, --profile <name>', 'AWS SSO profile to use')
|
|
20
|
+
.option('--sso-only', 'Only authenticate to SSO, skip CodeArtifact and ECR')
|
|
21
|
+
.option('--no-color', 'Disable colored output')
|
|
22
|
+
.option('-q, --quiet', 'Suppress non-error output')
|
|
23
|
+
.option('-v, --verbose', 'Show detailed output')
|
|
24
|
+
.action(handleLogin);
|
|
25
|
+
/**
|
|
26
|
+
* Handle the login command execution
|
|
27
|
+
*/
|
|
28
|
+
async function handleLogin(options) {
|
|
29
|
+
const config = await (0, config_1.loadConfig)();
|
|
30
|
+
const profile = (0, types_1.getEffectiveProfile)(options, config ?? undefined);
|
|
31
|
+
const result = {
|
|
32
|
+
sso: { success: false, skipped: false, duration: 0 },
|
|
33
|
+
codeartifact: { success: false, skipped: false, duration: 0 },
|
|
34
|
+
ecr: { success: false, skipped: false, duration: 0 },
|
|
35
|
+
};
|
|
36
|
+
// Step 1: SSO Authentication (REQUIRED)
|
|
37
|
+
if (!options.quiet) {
|
|
38
|
+
console.log(chalk_1.default.blue(`[1/3] AWS SSO ...`));
|
|
39
|
+
}
|
|
40
|
+
const ssoStart = Date.now();
|
|
41
|
+
try {
|
|
42
|
+
result.sso = await (0, sso_1.authenticateSSO)(profile, options);
|
|
43
|
+
result.sso.duration = Date.now() - ssoStart;
|
|
44
|
+
if (!options.quiet) {
|
|
45
|
+
console.log(chalk_1.default.green(` ✓ authenticated (profile: ${profile})`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
result.sso = {
|
|
50
|
+
success: false,
|
|
51
|
+
skipped: false,
|
|
52
|
+
error: error.message,
|
|
53
|
+
duration: Date.now() - ssoStart,
|
|
54
|
+
};
|
|
55
|
+
// SSO failed - skip remaining services
|
|
56
|
+
result.codeartifact = { success: false, skipped: true, duration: 0 };
|
|
57
|
+
result.ecr = { success: false, skipped: true, duration: 0 };
|
|
58
|
+
reportResults(result, options);
|
|
59
|
+
process.exit(2); // Exit code 2 = SSO failure
|
|
60
|
+
}
|
|
61
|
+
// Check if --sso-only flag is set
|
|
62
|
+
if (options.ssoOnly) {
|
|
63
|
+
result.codeartifact = { success: false, skipped: true, duration: 0 };
|
|
64
|
+
result.ecr = { success: false, skipped: true, duration: 0 };
|
|
65
|
+
reportResults(result, options);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
// Step 2: CodeArtifact (npm) - depends on SSO
|
|
69
|
+
if (!options.quiet) {
|
|
70
|
+
console.log(chalk_1.default.blue(`[2/3] CodeArtifact (npm) ...`));
|
|
71
|
+
}
|
|
72
|
+
if (config && (0, types_1.hasCodeArtifactConfig)(config)) {
|
|
73
|
+
const caStart = Date.now();
|
|
74
|
+
try {
|
|
75
|
+
result.codeartifact = await (0, codeartifact_1.configureCodeArtifact)(config.codeartifact, profile, options);
|
|
76
|
+
result.codeartifact.duration = Date.now() - caStart;
|
|
77
|
+
if (!options.quiet) {
|
|
78
|
+
console.log(chalk_1.default.green(` ✓ configured`));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
result.codeartifact = {
|
|
83
|
+
success: false,
|
|
84
|
+
skipped: false,
|
|
85
|
+
error: error.message,
|
|
86
|
+
duration: Date.now() - caStart,
|
|
87
|
+
};
|
|
88
|
+
if (!options.quiet) {
|
|
89
|
+
console.log(chalk_1.default.yellow(` ⚠ failed: ${error.message}`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
result.codeartifact = { success: false, skipped: true, duration: 0 };
|
|
95
|
+
if (!options.quiet) {
|
|
96
|
+
console.log(chalk_1.default.gray(` ○ skipped (not configured)`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Step 3: ECR (Docker) - depends on SSO, independent of CodeArtifact
|
|
100
|
+
if (!options.quiet) {
|
|
101
|
+
console.log(chalk_1.default.blue(`[3/3] ECR (Docker) ...`));
|
|
102
|
+
}
|
|
103
|
+
if (config && (0, types_1.hasEcrConfig)(config)) {
|
|
104
|
+
const ecrStart = Date.now();
|
|
105
|
+
try {
|
|
106
|
+
result.ecr = await (0, ecr_1.configureECR)(config.ecr, profile, options);
|
|
107
|
+
result.ecr.duration = Date.now() - ecrStart;
|
|
108
|
+
if (!options.quiet) {
|
|
109
|
+
console.log(chalk_1.default.green(` ✓ configured`));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
result.ecr = {
|
|
114
|
+
success: false,
|
|
115
|
+
skipped: false,
|
|
116
|
+
error: error.message,
|
|
117
|
+
duration: Date.now() - ecrStart,
|
|
118
|
+
};
|
|
119
|
+
if (!options.quiet) {
|
|
120
|
+
console.log(chalk_1.default.yellow(` ⚠ failed: ${error.message}`));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
result.ecr = { success: false, skipped: true, duration: 0 };
|
|
126
|
+
if (!options.quiet) {
|
|
127
|
+
console.log(chalk_1.default.gray(` ○ skipped (not configured)`));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
reportResults(result, options);
|
|
131
|
+
// Exit codes:
|
|
132
|
+
// 0 = SSO succeeded + at least one of (CodeArtifact, ECR) succeeded or was skipped intentionally
|
|
133
|
+
// 1 = SSO succeeded but both CodeArtifact and ECR failed (not skipped)
|
|
134
|
+
const caOk = result.codeartifact.success || result.codeartifact.skipped;
|
|
135
|
+
const ecrOk = result.ecr.success || result.ecr.skipped;
|
|
136
|
+
const postSsoSuccess = caOk || ecrOk;
|
|
137
|
+
process.exit(postSsoSuccess ? 0 : 1);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Report login results to console
|
|
141
|
+
*/
|
|
142
|
+
function reportResults(result, options) {
|
|
143
|
+
if (options.quiet)
|
|
144
|
+
return;
|
|
145
|
+
console.log('');
|
|
146
|
+
console.log('=== Login Results ===');
|
|
147
|
+
const services = [
|
|
148
|
+
{ name: 'SSO', result: result.sso },
|
|
149
|
+
{ name: 'CodeArtifact', result: result.codeartifact },
|
|
150
|
+
{ name: 'ECR', result: result.ecr },
|
|
151
|
+
];
|
|
152
|
+
let successCount = 0;
|
|
153
|
+
let skippedCount = 0;
|
|
154
|
+
for (const service of services) {
|
|
155
|
+
let status;
|
|
156
|
+
if (service.result.skipped) {
|
|
157
|
+
status = chalk_1.default.gray('○ SKIPPED');
|
|
158
|
+
skippedCount++;
|
|
159
|
+
}
|
|
160
|
+
else if (service.result.success) {
|
|
161
|
+
status = chalk_1.default.green('✓ OK');
|
|
162
|
+
successCount++;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
status = chalk_1.default.red('✗ FAILED');
|
|
166
|
+
}
|
|
167
|
+
console.log(`${service.name}: ${status}`);
|
|
168
|
+
if (!service.result.success && !service.result.skipped && service.result.error) {
|
|
169
|
+
console.log(chalk_1.default.red(` → ${service.result.error}`));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const total = services.length - skippedCount;
|
|
173
|
+
console.log('');
|
|
174
|
+
console.log(`Total: ${successCount}/${total} services authenticated`);
|
|
175
|
+
console.log('');
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/login/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ServiceResult, LoginOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Authenticate to AWS SSO using the AWS CLI
|
|
4
|
+
*
|
|
5
|
+
* @param profile - AWS profile name to authenticate with
|
|
6
|
+
* @param options - Login command options
|
|
7
|
+
* @returns ServiceResult indicating success/failure
|
|
8
|
+
*/
|
|
9
|
+
export declare function authenticateSSO(profile: string, options: LoginOptions): Promise<ServiceResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Check if SSO session is valid for the given profile
|
|
12
|
+
*
|
|
13
|
+
* @param profile - AWS profile name to check
|
|
14
|
+
* @returns true if session is valid, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkSSOSession(profile: string): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=sso.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../../../src/commands/login/sso.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKtD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA2DxB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAevE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authenticateSSO = authenticateSSO;
|
|
4
|
+
exports.checkSSOSession = checkSSOSession;
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
const SSO_TIMEOUT_MS = 60000; // 60 seconds for browser interaction
|
|
8
|
+
/**
|
|
9
|
+
* Authenticate to AWS SSO using the AWS CLI
|
|
10
|
+
*
|
|
11
|
+
* @param profile - AWS profile name to authenticate with
|
|
12
|
+
* @param options - Login command options
|
|
13
|
+
* @returns ServiceResult indicating success/failure
|
|
14
|
+
*/
|
|
15
|
+
async function authenticateSSO(profile, options) {
|
|
16
|
+
// Validate profile name to prevent injection
|
|
17
|
+
(0, utils_1.validateProfileName)(profile);
|
|
18
|
+
if (options.verbose) {
|
|
19
|
+
console.log(` [verbose] Running: aws sso login --profile ${profile}`);
|
|
20
|
+
}
|
|
21
|
+
const result = (0, child_process_1.spawnSync)('aws', ['sso', 'login', '--profile', profile], {
|
|
22
|
+
shell: false,
|
|
23
|
+
timeout: SSO_TIMEOUT_MS,
|
|
24
|
+
maxBuffer: 1024 * 1024,
|
|
25
|
+
stdio: ['inherit', 'pipe', 'pipe'], // inherit stdin for browser interaction
|
|
26
|
+
env: {
|
|
27
|
+
...(0, utils_1.getSubprocessEnv)(),
|
|
28
|
+
AWS_PROFILE: profile,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
if (result.error) {
|
|
32
|
+
// Handle spawn errors (command not found, timeout, etc.)
|
|
33
|
+
if (result.error.message.includes('ENOENT')) {
|
|
34
|
+
throw new Error('AWS CLI not found. Please install AWS CLI v2: https://aws.amazon.com/cli/');
|
|
35
|
+
}
|
|
36
|
+
if (result.error.message.includes('ETIMEDOUT')) {
|
|
37
|
+
throw new Error('SSO login timed out. Please try again.');
|
|
38
|
+
}
|
|
39
|
+
throw new Error((0, utils_1.sanitizeOutput)(result.error.message));
|
|
40
|
+
}
|
|
41
|
+
if (result.status !== 0) {
|
|
42
|
+
const stderr = result.stderr?.toString() || '';
|
|
43
|
+
const stdout = result.stdout?.toString() || '';
|
|
44
|
+
// Parse common error conditions
|
|
45
|
+
if (stderr.includes('profile') && stderr.includes('not found')) {
|
|
46
|
+
throw new Error(`Profile '${profile}' not found. Run: aws configure list-profiles`);
|
|
47
|
+
}
|
|
48
|
+
if (stderr.includes('Token has expired')) {
|
|
49
|
+
throw new Error('SSO session expired. Browser authentication required.');
|
|
50
|
+
}
|
|
51
|
+
if (stderr.includes('No SSO configuration')) {
|
|
52
|
+
throw new Error(`Profile '${profile}' is not configured for SSO. Check ~/.aws/config`);
|
|
53
|
+
}
|
|
54
|
+
// Generic error with sanitized output
|
|
55
|
+
const errorOutput = (0, utils_1.sanitizeOutput)(stderr || stdout || 'Unknown error');
|
|
56
|
+
throw new Error(`SSO login failed: ${errorOutput}`);
|
|
57
|
+
}
|
|
58
|
+
if (options.verbose) {
|
|
59
|
+
console.log(' [verbose] SSO authentication successful');
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
skipped: false,
|
|
64
|
+
duration: 0, // Will be set by caller
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if SSO session is valid for the given profile
|
|
69
|
+
*
|
|
70
|
+
* @param profile - AWS profile name to check
|
|
71
|
+
* @returns true if session is valid, false otherwise
|
|
72
|
+
*/
|
|
73
|
+
async function checkSSOSession(profile) {
|
|
74
|
+
(0, utils_1.validateProfileName)(profile);
|
|
75
|
+
const result = (0, child_process_1.spawnSync)('aws', ['sts', 'get-caller-identity', '--profile', profile], {
|
|
76
|
+
shell: false,
|
|
77
|
+
timeout: 10000,
|
|
78
|
+
maxBuffer: 1024 * 1024,
|
|
79
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
80
|
+
env: {
|
|
81
|
+
...(0, utils_1.getSubprocessEnv)(),
|
|
82
|
+
AWS_PROFILE: profile,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return result.status === 0;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=sso.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso.js","sourceRoot":"","sources":["../../../src/commands/login/sso.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Models for Full Login Feature
|
|
3
|
+
*
|
|
4
|
+
* Defines TypeScript interfaces for the Padua CLI login workflow including:
|
|
5
|
+
* - Configuration schema (padua.config.json)
|
|
6
|
+
* - Authentication service results
|
|
7
|
+
* - Login command outcomes
|
|
8
|
+
* - CLI command options
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* PaduaConfig - Main configuration object persisted to padua.config.json
|
|
12
|
+
*/
|
|
13
|
+
export interface PaduaConfig {
|
|
14
|
+
/** Default AWS SSO profile to use if not specified via CLI flag */
|
|
15
|
+
defaultProfile?: string;
|
|
16
|
+
/** Default AWS region for all service operations (default: "us-east-1") */
|
|
17
|
+
region?: string;
|
|
18
|
+
/** CodeArtifact repository configuration for npm authentication */
|
|
19
|
+
codeartifact?: CodeArtifactConfig;
|
|
20
|
+
/** ECR registry configuration for Docker authentication */
|
|
21
|
+
ecr?: EcrConfig;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* CodeArtifactConfig - Configuration for AWS CodeArtifact npm repository access
|
|
25
|
+
*/
|
|
26
|
+
export interface CodeArtifactConfig {
|
|
27
|
+
/** CodeArtifact domain name (1-127 chars, alphanumeric with hyphens) */
|
|
28
|
+
domain: string;
|
|
29
|
+
/** AWS account ID owning the CodeArtifact domain (12-digit) */
|
|
30
|
+
domainOwner: string;
|
|
31
|
+
/** Repository name within the CodeArtifact domain */
|
|
32
|
+
repository: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* EcrConfig - Configuration for AWS ECR Docker registry access
|
|
36
|
+
*/
|
|
37
|
+
export interface EcrConfig {
|
|
38
|
+
/** AWS account ID containing the ECR registry (12-digit) */
|
|
39
|
+
accountId: string;
|
|
40
|
+
/** AWS region containing the ECR registry */
|
|
41
|
+
region: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* ServiceResult - Outcome of authenticating to a single service
|
|
45
|
+
*/
|
|
46
|
+
export interface ServiceResult {
|
|
47
|
+
/** Whether authentication succeeded */
|
|
48
|
+
success: boolean;
|
|
49
|
+
/** Whether this service was skipped (not attempted) */
|
|
50
|
+
skipped: boolean;
|
|
51
|
+
/** Error message if authentication failed */
|
|
52
|
+
error?: string;
|
|
53
|
+
/** Time in milliseconds for this authentication operation */
|
|
54
|
+
duration: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* LoginResult - Aggregated outcome of the full login operation
|
|
58
|
+
*/
|
|
59
|
+
export interface LoginResult {
|
|
60
|
+
/** AWS SSO authentication result */
|
|
61
|
+
sso: ServiceResult;
|
|
62
|
+
/** CodeArtifact npm repository authentication result */
|
|
63
|
+
codeartifact: ServiceResult;
|
|
64
|
+
/** ECR Docker registry authentication result */
|
|
65
|
+
ecr: ServiceResult;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* LoginOptions - Command-line options and flags for `padua login`
|
|
69
|
+
*/
|
|
70
|
+
export interface LoginOptions {
|
|
71
|
+
/** AWS SSO profile to authenticate with */
|
|
72
|
+
profile?: string;
|
|
73
|
+
/** Authenticate to SSO only, skip CodeArtifact and ECR */
|
|
74
|
+
ssoOnly?: boolean;
|
|
75
|
+
/** Disable colored output in terminal */
|
|
76
|
+
noColor?: boolean;
|
|
77
|
+
/** Suppress all output except errors */
|
|
78
|
+
quiet?: boolean;
|
|
79
|
+
/** Enable verbose output with debugging information */
|
|
80
|
+
verbose?: boolean;
|
|
81
|
+
}
|
|
82
|
+
/** Check if a value is a valid AWS account ID (12-digit string) */
|
|
83
|
+
export declare function isValidAccountId(value: string): boolean;
|
|
84
|
+
/** Check if a value is a valid AWS region code */
|
|
85
|
+
export declare function isValidRegion(value: string): boolean;
|
|
86
|
+
/** Check if a value is a valid profile name (alphanumeric, hyphens, underscores) */
|
|
87
|
+
export declare function isValidProfileName(value: string): boolean;
|
|
88
|
+
/** Check if a value is a valid domain name (alphanumeric, hyphens) */
|
|
89
|
+
export declare function isValidDomainName(value: string): boolean;
|
|
90
|
+
/** Check if a value is a valid repository name (lowercase alphanumeric, hyphens) */
|
|
91
|
+
export declare function isValidRepositoryName(value: string): boolean;
|
|
92
|
+
/** Check if configuration has CodeArtifact configured */
|
|
93
|
+
export declare function hasCodeArtifactConfig(config: PaduaConfig): boolean;
|
|
94
|
+
/** Check if configuration has ECR configured */
|
|
95
|
+
export declare function hasEcrConfig(config: PaduaConfig): boolean;
|
|
96
|
+
/** Get the effective profile to use (preference order: options, config, default) */
|
|
97
|
+
export declare function getEffectiveProfile(options: LoginOptions, config?: PaduaConfig): string;
|
|
98
|
+
/** Get the effective region to use (preference order: config, default) */
|
|
99
|
+
export declare function getEffectiveRegion(config?: PaduaConfig): string;
|
|
100
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/login/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mEAAmE;IACnE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAElC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IAEf,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IAEpB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAElB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IAEjB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,GAAG,EAAE,aAAa,CAAC;IAEnB,wDAAwD;IACxD,YAAY,EAAE,aAAa,CAAC;IAE5B,gDAAgD;IAChD,GAAG,EAAE,aAAa,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,wCAAwC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAapD;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAElE;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEzD;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAEvF;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Data Models for Full Login Feature
|
|
4
|
+
*
|
|
5
|
+
* Defines TypeScript interfaces for the Padua CLI login workflow including:
|
|
6
|
+
* - Configuration schema (padua.config.json)
|
|
7
|
+
* - Authentication service results
|
|
8
|
+
* - Login command outcomes
|
|
9
|
+
* - CLI command options
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.isValidAccountId = isValidAccountId;
|
|
13
|
+
exports.isValidRegion = isValidRegion;
|
|
14
|
+
exports.isValidProfileName = isValidProfileName;
|
|
15
|
+
exports.isValidDomainName = isValidDomainName;
|
|
16
|
+
exports.isValidRepositoryName = isValidRepositoryName;
|
|
17
|
+
exports.hasCodeArtifactConfig = hasCodeArtifactConfig;
|
|
18
|
+
exports.hasEcrConfig = hasEcrConfig;
|
|
19
|
+
exports.getEffectiveProfile = getEffectiveProfile;
|
|
20
|
+
exports.getEffectiveRegion = getEffectiveRegion;
|
|
21
|
+
// Type Guards
|
|
22
|
+
/** Check if a value is a valid AWS account ID (12-digit string) */
|
|
23
|
+
function isValidAccountId(value) {
|
|
24
|
+
return /^\d{12}$/.test(value);
|
|
25
|
+
}
|
|
26
|
+
/** Check if a value is a valid AWS region code */
|
|
27
|
+
function isValidRegion(value) {
|
|
28
|
+
const validRegions = [
|
|
29
|
+
'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2',
|
|
30
|
+
'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-central-1', 'eu-north-1',
|
|
31
|
+
'ap-northeast-1', 'ap-northeast-2', 'ap-northeast-3',
|
|
32
|
+
'ap-southeast-1', 'ap-southeast-2',
|
|
33
|
+
'ap-south-1',
|
|
34
|
+
'ca-central-1',
|
|
35
|
+
'sa-east-1',
|
|
36
|
+
'af-south-1',
|
|
37
|
+
'me-south-1',
|
|
38
|
+
];
|
|
39
|
+
return validRegions.includes(value);
|
|
40
|
+
}
|
|
41
|
+
/** Check if a value is a valid profile name (alphanumeric, hyphens, underscores) */
|
|
42
|
+
function isValidProfileName(value) {
|
|
43
|
+
return /^[a-zA-Z0-9\-_]{1,128}$/.test(value);
|
|
44
|
+
}
|
|
45
|
+
/** Check if a value is a valid domain name (alphanumeric, hyphens) */
|
|
46
|
+
function isValidDomainName(value) {
|
|
47
|
+
return /^[a-z0-9\-]{1,127}$/.test(value) && !value.startsWith('-') && !value.endsWith('-');
|
|
48
|
+
}
|
|
49
|
+
/** Check if a value is a valid repository name (lowercase alphanumeric, hyphens) */
|
|
50
|
+
function isValidRepositoryName(value) {
|
|
51
|
+
return /^[a-z0-9\-]{1,100}$/.test(value) && !value.startsWith('-') && !value.endsWith('-');
|
|
52
|
+
}
|
|
53
|
+
/** Check if configuration has CodeArtifact configured */
|
|
54
|
+
function hasCodeArtifactConfig(config) {
|
|
55
|
+
return !!(config.codeartifact?.domain && config.codeartifact?.domainOwner && config.codeartifact?.repository);
|
|
56
|
+
}
|
|
57
|
+
/** Check if configuration has ECR configured */
|
|
58
|
+
function hasEcrConfig(config) {
|
|
59
|
+
return !!(config.ecr?.accountId && config.ecr?.region);
|
|
60
|
+
}
|
|
61
|
+
/** Get the effective profile to use (preference order: options, config, default) */
|
|
62
|
+
function getEffectiveProfile(options, config) {
|
|
63
|
+
return options.profile || config?.defaultProfile || 'default';
|
|
64
|
+
}
|
|
65
|
+
/** Get the effective region to use (preference order: config, default) */
|
|
66
|
+
function getEffectiveRegion(config) {
|
|
67
|
+
return config?.region || 'us-east-1';
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/login/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAkGH,4CAEC;AAGD,sCAaC;AAGD,gDAEC;AAGD,8CAEC;AAGD,sDAEC;AAGD,sDAEC;AAGD,oCAEC;AAGD,kDAEC;AAGD,gDAEC;AAxDD,cAAc;AAEd,mEAAmE;AACnE,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,kDAAkD;AAClD,SAAgB,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG;QACnB,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW;QAClD,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY;QACnE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB;QACpD,gBAAgB,EAAE,gBAAgB;QAClC,YAAY;QACZ,cAAc;QACd,WAAW;QACX,YAAY;QACZ,YAAY;KACb,CAAC;IACF,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,oFAAoF;AACpF,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,OAAO,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,sEAAsE;AACtE,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED,oFAAoF;AACpF,SAAgB,qBAAqB,CAAC,KAAa;IACjD,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED,yDAAyD;AACzD,SAAgB,qBAAqB,CAAC,MAAmB;IACvD,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,WAAW,IAAI,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAChH,CAAC;AAED,gDAAgD;AAChD,SAAgB,YAAY,CAAC,MAAmB;IAC9C,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,oFAAoF;AACpF,SAAgB,mBAAmB,CAAC,OAAqB,EAAE,MAAoB;IAC7E,OAAO,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,cAAc,IAAI,SAAS,CAAC;AAChE,CAAC;AAED,0EAA0E;AAC1E,SAAgB,kBAAkB,CAAC,MAAoB;IACrD,OAAO,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate profile name before using in subprocess
|
|
3
|
+
* Throws if invalid to prevent injection attacks
|
|
4
|
+
*/
|
|
5
|
+
export declare function validateProfileName(profile: string): void;
|
|
6
|
+
/**
|
|
7
|
+
* Sanitize tokens and credentials from output
|
|
8
|
+
* Removes AWS access keys, session tokens, and other sensitive data
|
|
9
|
+
*/
|
|
10
|
+
export declare function sanitizeOutput(output: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize error messages before displaying to user
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeErrorMessage(error: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Get environment variables safe to pass to subprocesses
|
|
17
|
+
* Only passes necessary variables to minimize exposure
|
|
18
|
+
*/
|
|
19
|
+
export declare function getSubprocessEnv(): NodeJS.ProcessEnv;
|
|
20
|
+
/**
|
|
21
|
+
* Format duration in milliseconds to human readable string
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatDuration(ms: number): string;
|
|
24
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/commands/login/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,UAAU,CAqCpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAKjD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateProfileName = validateProfileName;
|
|
4
|
+
exports.sanitizeOutput = sanitizeOutput;
|
|
5
|
+
exports.sanitizeErrorMessage = sanitizeErrorMessage;
|
|
6
|
+
exports.getSubprocessEnv = getSubprocessEnv;
|
|
7
|
+
exports.formatDuration = formatDuration;
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
/**
|
|
10
|
+
* Validate profile name before using in subprocess
|
|
11
|
+
* Throws if invalid to prevent injection attacks
|
|
12
|
+
*/
|
|
13
|
+
function validateProfileName(profile) {
|
|
14
|
+
if (!(0, types_1.isValidProfileName)(profile)) {
|
|
15
|
+
throw new Error(`Invalid profile name: ${profile}. Profile names must be alphanumeric with hyphens/underscores (1-128 chars).`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Sanitize tokens and credentials from output
|
|
20
|
+
* Removes AWS access keys, session tokens, and other sensitive data
|
|
21
|
+
*/
|
|
22
|
+
function sanitizeOutput(output) {
|
|
23
|
+
// Remove AWS access key IDs (AKIA...)
|
|
24
|
+
let sanitized = output.replace(/AKIA[A-Z0-9]{16}/g, '[REDACTED_ACCESS_KEY]');
|
|
25
|
+
// Remove AWS secret access keys (40 char base64)
|
|
26
|
+
sanitized = sanitized.replace(/[A-Za-z0-9/+=]{40}/g, (match) => {
|
|
27
|
+
// Only redact if it looks like a secret key (contains mixed case and special chars)
|
|
28
|
+
if (/[A-Z]/.test(match) && /[a-z]/.test(match) && /[/+=]/.test(match)) {
|
|
29
|
+
return '[REDACTED_SECRET]';
|
|
30
|
+
}
|
|
31
|
+
return match;
|
|
32
|
+
});
|
|
33
|
+
// Remove session tokens (long base64 strings)
|
|
34
|
+
sanitized = sanitized.replace(/[A-Za-z0-9/+=]{100,}/g, '[REDACTED_TOKEN]');
|
|
35
|
+
// Remove password-like patterns after common keywords
|
|
36
|
+
sanitized = sanitized.replace(/(password|token|secret|credential)[\s:=]+\S+/gi, '$1=[REDACTED]');
|
|
37
|
+
return sanitized;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sanitize error messages before displaying to user
|
|
41
|
+
*/
|
|
42
|
+
function sanitizeErrorMessage(error) {
|
|
43
|
+
return sanitizeOutput(error);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get environment variables safe to pass to subprocesses
|
|
47
|
+
* Only passes necessary variables to minimize exposure
|
|
48
|
+
*/
|
|
49
|
+
function getSubprocessEnv() {
|
|
50
|
+
const safeEnv = {};
|
|
51
|
+
// Whitelist of environment variables to pass
|
|
52
|
+
const whitelist = [
|
|
53
|
+
'PATH',
|
|
54
|
+
'HOME',
|
|
55
|
+
'USER',
|
|
56
|
+
'SHELL',
|
|
57
|
+
'TERM',
|
|
58
|
+
'AWS_PROFILE',
|
|
59
|
+
'AWS_DEFAULT_REGION',
|
|
60
|
+
'AWS_CONFIG_FILE',
|
|
61
|
+
'AWS_SHARED_CREDENTIALS_FILE',
|
|
62
|
+
// Required for Windows
|
|
63
|
+
'SYSTEMROOT',
|
|
64
|
+
'COMSPEC',
|
|
65
|
+
'PATHEXT',
|
|
66
|
+
'APPDATA',
|
|
67
|
+
'LOCALAPPDATA',
|
|
68
|
+
'USERPROFILE',
|
|
69
|
+
'TEMP',
|
|
70
|
+
'TMP',
|
|
71
|
+
'HOMEDRIVE',
|
|
72
|
+
'HOMEPATH',
|
|
73
|
+
// Required for macOS/Linux
|
|
74
|
+
'TMPDIR',
|
|
75
|
+
'XDG_CONFIG_HOME',
|
|
76
|
+
];
|
|
77
|
+
for (const key of whitelist) {
|
|
78
|
+
if (process.env[key]) {
|
|
79
|
+
safeEnv[key] = process.env[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return safeEnv;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Format duration in milliseconds to human readable string
|
|
86
|
+
*/
|
|
87
|
+
function formatDuration(ms) {
|
|
88
|
+
if (ms < 1000) {
|
|
89
|
+
return `${ms}ms`;
|
|
90
|
+
}
|
|
91
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/commands/login/utils.ts"],"names":[],"mappings":";;AAMA,kDAIC;AAMD,wCAoBC;AAKD,oDAEC;AAMD,4CAqCC;AAKD,wCAKC;AAhGD,mCAA6C;AAE7C;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,8EAA8E,CAAC,CAAC;IAClI,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,MAAc;IAC3C,sCAAsC;IACtC,IAAI,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;IAE7E,iDAAiD;IACjD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC7D,oFAAoF;QACpF,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,8CAA8C;IAC9C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;IAE3E,sDAAsD;IACtD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,gDAAgD,EAAE,eAAe,CAAC,CAAC;IAEjG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IAChD,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,6CAA6C;IAC7C,MAAM,SAAS,GAAG;QAChB,MAAM;QACN,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,aAAa;QACb,oBAAoB;QACpB,iBAAiB;QACjB,6BAA6B;QAC7B,uBAAuB;QACvB,YAAY;QACZ,SAAS;QACT,SAAS;QACT,SAAS;QACT,cAAc;QACd,aAAa;QACb,MAAM;QACN,KAAK;QACL,WAAW;QACX,UAAU;QACV,2BAA2B;QAC3B,QAAQ;QACR,iBAAiB;KAClB,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACd,OAAO,GAAG,EAAE,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const login_1 = require("./commands/login");
|
|
6
|
+
const program = new commander_1.Command();
|
|
7
|
+
program
|
|
8
|
+
.name('padua')
|
|
9
|
+
.description('Unified AWS infrastructure management CLI')
|
|
10
|
+
.version('1.0.0');
|
|
11
|
+
// Register commands
|
|
12
|
+
program.addCommand(login_1.loginCommand);
|
|
13
|
+
program.parse();
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAEhD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@padua/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified AWS infrastructure management CLI",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"padua": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"lint": "eslint src --ext .ts",
|
|
15
|
+
"type-check": "tsc --noEmit",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"test:coverage": "jest --coverage",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"keywords": [
|
|
28
|
+
"aws",
|
|
29
|
+
"sso",
|
|
30
|
+
"cli",
|
|
31
|
+
"codeartifact",
|
|
32
|
+
"ecr",
|
|
33
|
+
"authentication"
|
|
34
|
+
],
|
|
35
|
+
"author": "",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"commander": "^12.1.0",
|
|
39
|
+
"chalk": "^4.1.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^20.10.0",
|
|
43
|
+
"typescript": "^5.3.0",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
45
|
+
"@typescript-eslint/parser": "^6.13.0",
|
|
46
|
+
"eslint": "^8.55.0",
|
|
47
|
+
"jest": "^29.7.0",
|
|
48
|
+
"@types/jest": "^29.5.0",
|
|
49
|
+
"ts-jest": "^29.1.0"
|
|
50
|
+
}
|
|
51
|
+
}
|