@zhafron/opencode-kiro-auth 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 +85 -0
- package/dist/constants.d.ts +26 -0
- package/dist/constants.js +60 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/kiro/auth.d.ts +5 -0
- package/dist/kiro/auth.js +24 -0
- package/dist/kiro/oauth-idc.d.ts +24 -0
- package/dist/kiro/oauth-idc.js +132 -0
- package/dist/kiro/oauth-social.d.ts +17 -0
- package/dist/kiro/oauth-social.js +51 -0
- package/dist/plugin/accounts.d.ts +28 -0
- package/dist/plugin/accounts.js +156 -0
- package/dist/plugin/auth-page.d.ts +3 -0
- package/dist/plugin/auth-page.js +568 -0
- package/dist/plugin/cli.d.ts +6 -0
- package/dist/plugin/cli.js +98 -0
- package/dist/plugin/config/index.d.ts +3 -0
- package/dist/plugin/config/index.js +2 -0
- package/dist/plugin/config/loader.d.ts +6 -0
- package/dist/plugin/config/loader.js +125 -0
- package/dist/plugin/config/schema.d.ts +44 -0
- package/dist/plugin/config/schema.js +28 -0
- package/dist/plugin/debug.d.ts +2 -0
- package/dist/plugin/debug.js +9 -0
- package/dist/plugin/errors.d.ts +17 -0
- package/dist/plugin/errors.js +34 -0
- package/dist/plugin/logger.d.ts +4 -0
- package/dist/plugin/logger.js +37 -0
- package/dist/plugin/models.d.ts +3 -0
- package/dist/plugin/models.js +14 -0
- package/dist/plugin/oauth-parser.d.ts +5 -0
- package/dist/plugin/oauth-parser.js +23 -0
- package/dist/plugin/quota.d.ts +15 -0
- package/dist/plugin/quota.js +68 -0
- package/dist/plugin/recovery.d.ts +19 -0
- package/dist/plugin/recovery.js +302 -0
- package/dist/plugin/refresh-queue.d.ts +14 -0
- package/dist/plugin/refresh-queue.js +69 -0
- package/dist/plugin/request.d.ts +4 -0
- package/dist/plugin/request.js +240 -0
- package/dist/plugin/response.d.ts +6 -0
- package/dist/plugin/response.js +246 -0
- package/dist/plugin/server.d.ts +24 -0
- package/dist/plugin/server.js +96 -0
- package/dist/plugin/storage.d.ts +7 -0
- package/dist/plugin/storage.js +75 -0
- package/dist/plugin/streaming.d.ts +3 -0
- package/dist/plugin/streaming.js +503 -0
- package/dist/plugin/token.d.ts +2 -0
- package/dist/plugin/token.js +56 -0
- package/dist/plugin/types.d.ts +148 -0
- package/dist/plugin/types.js +0 -0
- package/dist/plugin/usage.d.ts +3 -0
- package/dist/plugin/usage.js +36 -0
- package/dist/plugin.d.ts +32 -0
- package/dist/plugin.js +222 -0
- package/dist/src/constants.d.ts +22 -0
- package/dist/src/constants.js +35 -0
- package/dist/src/kiro/auth.d.ts +5 -0
- package/dist/src/kiro/auth.js +69 -0
- package/dist/src/kiro/oauth-idc.d.ts +22 -0
- package/dist/src/kiro/oauth-idc.js +99 -0
- package/dist/src/kiro/oauth-social.d.ts +17 -0
- package/dist/src/kiro/oauth-social.js +69 -0
- package/dist/src/plugin/accounts.d.ts +23 -0
- package/dist/src/plugin/accounts.js +265 -0
- package/dist/src/plugin/cli.d.ts +6 -0
- package/dist/src/plugin/cli.js +98 -0
- package/dist/src/plugin/config/index.d.ts +3 -0
- package/dist/src/plugin/config/index.js +2 -0
- package/dist/src/plugin/config/loader.d.ts +7 -0
- package/dist/src/plugin/config/loader.js +143 -0
- package/dist/src/plugin/config/schema.d.ts +68 -0
- package/dist/src/plugin/config/schema.js +44 -0
- package/dist/src/plugin/debug.d.ts +2 -0
- package/dist/src/plugin/debug.js +9 -0
- package/dist/src/plugin/errors.d.ts +17 -0
- package/dist/src/plugin/errors.js +34 -0
- package/dist/src/plugin/logger.d.ts +4 -0
- package/dist/src/plugin/logger.js +17 -0
- package/dist/src/plugin/models.d.ts +3 -0
- package/dist/src/plugin/models.js +14 -0
- package/dist/src/plugin/oauth-parser.d.ts +5 -0
- package/dist/src/plugin/oauth-parser.js +23 -0
- package/dist/src/plugin/quota.d.ts +25 -0
- package/dist/src/plugin/quota.js +175 -0
- package/dist/src/plugin/recovery.d.ts +19 -0
- package/dist/src/plugin/recovery.js +302 -0
- package/dist/src/plugin/refresh-queue.d.ts +14 -0
- package/dist/src/plugin/refresh-queue.js +69 -0
- package/dist/src/plugin/request.d.ts +35 -0
- package/dist/src/plugin/request.js +411 -0
- package/dist/src/plugin/response.d.ts +6 -0
- package/dist/src/plugin/response.js +246 -0
- package/dist/src/plugin/server.d.ts +10 -0
- package/dist/src/plugin/server.js +203 -0
- package/dist/src/plugin/storage.d.ts +5 -0
- package/dist/src/plugin/storage.js +106 -0
- package/dist/src/plugin/streaming.d.ts +12 -0
- package/dist/src/plugin/streaming.js +444 -0
- package/dist/src/plugin/token.d.ts +8 -0
- package/dist/src/plugin/token.js +130 -0
- package/dist/src/plugin/types.d.ts +144 -0
- package/dist/src/plugin/types.js +0 -0
- package/dist/src/plugin/usage.d.ts +28 -0
- package/dist/src/plugin/usage.js +159 -0
- package/dist/src/plugin.d.ts +2 -0
- package/dist/src/plugin.js +341 -0
- package/package.json +57 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
function escapeHtml(text) {
|
|
2
|
+
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
3
|
+
}
|
|
4
|
+
export function getIDCAuthHtml(verificationUrl, userCode, statusUrl) {
|
|
5
|
+
const escapedUrl = escapeHtml(verificationUrl);
|
|
6
|
+
const escapedCode = escapeHtml(userCode);
|
|
7
|
+
const escapedStatusUrl = escapeHtml(statusUrl);
|
|
8
|
+
return `<!DOCTYPE html>
|
|
9
|
+
<html lang="en">
|
|
10
|
+
<head>
|
|
11
|
+
<meta charset="UTF-8">
|
|
12
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
13
|
+
<title>AWS Builder ID Authentication</title>
|
|
14
|
+
<style>
|
|
15
|
+
* {
|
|
16
|
+
margin: 0;
|
|
17
|
+
padding: 0;
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
}
|
|
20
|
+
body {
|
|
21
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
22
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
23
|
+
min-height: 100vh;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
padding: 20px;
|
|
28
|
+
}
|
|
29
|
+
.container {
|
|
30
|
+
background: white;
|
|
31
|
+
border-radius: 16px;
|
|
32
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
33
|
+
max-width: 500px;
|
|
34
|
+
width: 100%;
|
|
35
|
+
padding: 48px 40px;
|
|
36
|
+
text-align: center;
|
|
37
|
+
animation: slideIn 0.4s ease-out;
|
|
38
|
+
}
|
|
39
|
+
@keyframes slideIn {
|
|
40
|
+
from {
|
|
41
|
+
opacity: 0;
|
|
42
|
+
transform: translateY(-20px);
|
|
43
|
+
}
|
|
44
|
+
to {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
transform: translateY(0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
h1 {
|
|
50
|
+
color: #1a202c;
|
|
51
|
+
font-size: 28px;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
margin-bottom: 12px;
|
|
54
|
+
}
|
|
55
|
+
.subtitle {
|
|
56
|
+
color: #718096;
|
|
57
|
+
font-size: 16px;
|
|
58
|
+
margin-bottom: 32px;
|
|
59
|
+
line-height: 1.5;
|
|
60
|
+
}
|
|
61
|
+
.code-container {
|
|
62
|
+
background: #f7fafc;
|
|
63
|
+
border: 2px solid #e2e8f0;
|
|
64
|
+
border-radius: 12px;
|
|
65
|
+
padding: 24px;
|
|
66
|
+
margin-bottom: 24px;
|
|
67
|
+
position: relative;
|
|
68
|
+
}
|
|
69
|
+
.code-label {
|
|
70
|
+
color: #4a5568;
|
|
71
|
+
font-size: 14px;
|
|
72
|
+
font-weight: 600;
|
|
73
|
+
text-transform: uppercase;
|
|
74
|
+
letter-spacing: 0.5px;
|
|
75
|
+
margin-bottom: 12px;
|
|
76
|
+
}
|
|
77
|
+
.code {
|
|
78
|
+
font-family: 'Courier New', monospace;
|
|
79
|
+
font-size: 32px;
|
|
80
|
+
font-weight: 700;
|
|
81
|
+
color: #2d3748;
|
|
82
|
+
letter-spacing: 4px;
|
|
83
|
+
user-select: all;
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
padding: 8px;
|
|
86
|
+
border-radius: 6px;
|
|
87
|
+
transition: background 0.2s;
|
|
88
|
+
}
|
|
89
|
+
.code:hover {
|
|
90
|
+
background: #edf2f7;
|
|
91
|
+
}
|
|
92
|
+
.copy-hint {
|
|
93
|
+
color: #a0aec0;
|
|
94
|
+
font-size: 12px;
|
|
95
|
+
margin-top: 8px;
|
|
96
|
+
}
|
|
97
|
+
.url-container {
|
|
98
|
+
margin-bottom: 32px;
|
|
99
|
+
}
|
|
100
|
+
.url-label {
|
|
101
|
+
color: #4a5568;
|
|
102
|
+
font-size: 14px;
|
|
103
|
+
font-weight: 600;
|
|
104
|
+
margin-bottom: 12px;
|
|
105
|
+
}
|
|
106
|
+
.url-link {
|
|
107
|
+
display: inline-block;
|
|
108
|
+
color: #4299e1;
|
|
109
|
+
text-decoration: none;
|
|
110
|
+
font-size: 16px;
|
|
111
|
+
padding: 12px 24px;
|
|
112
|
+
border: 2px solid #4299e1;
|
|
113
|
+
border-radius: 8px;
|
|
114
|
+
transition: all 0.2s;
|
|
115
|
+
font-weight: 600;
|
|
116
|
+
}
|
|
117
|
+
.url-link:hover {
|
|
118
|
+
background: #4299e1;
|
|
119
|
+
color: white;
|
|
120
|
+
transform: translateY(-2px);
|
|
121
|
+
box-shadow: 0 4px 12px rgba(66, 153, 225, 0.4);
|
|
122
|
+
}
|
|
123
|
+
.status {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
gap: 12px;
|
|
128
|
+
color: #718096;
|
|
129
|
+
font-size: 14px;
|
|
130
|
+
margin-top: 32px;
|
|
131
|
+
padding-top: 24px;
|
|
132
|
+
border-top: 1px solid #e2e8f0;
|
|
133
|
+
}
|
|
134
|
+
.spinner {
|
|
135
|
+
width: 20px;
|
|
136
|
+
height: 20px;
|
|
137
|
+
border: 3px solid #e2e8f0;
|
|
138
|
+
border-top-color: #4299e1;
|
|
139
|
+
border-radius: 50%;
|
|
140
|
+
animation: spin 0.8s linear infinite;
|
|
141
|
+
}
|
|
142
|
+
@keyframes spin {
|
|
143
|
+
to { transform: rotate(360deg); }
|
|
144
|
+
}
|
|
145
|
+
.instructions {
|
|
146
|
+
background: #edf2f7;
|
|
147
|
+
border-radius: 8px;
|
|
148
|
+
padding: 16px;
|
|
149
|
+
margin-bottom: 24px;
|
|
150
|
+
text-align: left;
|
|
151
|
+
}
|
|
152
|
+
.instructions ol {
|
|
153
|
+
margin-left: 20px;
|
|
154
|
+
color: #4a5568;
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
line-height: 1.8;
|
|
157
|
+
}
|
|
158
|
+
.instructions li {
|
|
159
|
+
margin-bottom: 8px;
|
|
160
|
+
}
|
|
161
|
+
@media (max-width: 600px) {
|
|
162
|
+
.container {
|
|
163
|
+
padding: 32px 24px;
|
|
164
|
+
}
|
|
165
|
+
h1 {
|
|
166
|
+
font-size: 24px;
|
|
167
|
+
}
|
|
168
|
+
.code {
|
|
169
|
+
font-size: 24px;
|
|
170
|
+
letter-spacing: 2px;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
</style>
|
|
174
|
+
</head>
|
|
175
|
+
<body>
|
|
176
|
+
<div class="container">
|
|
177
|
+
<h1>AWS Builder ID Authentication</h1>
|
|
178
|
+
<p class="subtitle">Complete the authentication in your browser</p>
|
|
179
|
+
|
|
180
|
+
<div class="instructions">
|
|
181
|
+
<ol>
|
|
182
|
+
<li>A browser window will open automatically</li>
|
|
183
|
+
<li>Enter the code shown below</li>
|
|
184
|
+
<li>Complete the authentication process</li>
|
|
185
|
+
</ol>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div class="code-container">
|
|
189
|
+
<div class="code-label">Your Code</div>
|
|
190
|
+
<div class="code" onclick="copyCode()">${escapedCode}</div>
|
|
191
|
+
<div class="copy-hint">Click to copy</div>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="url-container">
|
|
195
|
+
<div class="url-label">Verification URL</div>
|
|
196
|
+
<a href="${escapedUrl}" target="_blank" class="url-link">Open Browser</a>
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
<div class="status">
|
|
200
|
+
<div class="spinner"></div>
|
|
201
|
+
<span>Waiting for authentication...</span>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<script>
|
|
206
|
+
const statusUrl = '${escapedStatusUrl}';
|
|
207
|
+
const verificationUrl = '${escapedUrl}';
|
|
208
|
+
|
|
209
|
+
function copyCode() {
|
|
210
|
+
const code = '${escapedCode}';
|
|
211
|
+
navigator.clipboard.writeText(code).then(() => {
|
|
212
|
+
const codeEl = document.querySelector('.code');
|
|
213
|
+
const originalBg = codeEl.style.background;
|
|
214
|
+
codeEl.style.background = '#48bb78';
|
|
215
|
+
codeEl.style.color = 'white';
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
codeEl.style.background = originalBg;
|
|
218
|
+
codeEl.style.color = '#2d3748';
|
|
219
|
+
}, 300);
|
|
220
|
+
}).catch(() => {});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
window.addEventListener('load', () => {
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
window.open(verificationUrl, '_blank');
|
|
226
|
+
}, 500);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
async function checkStatus() {
|
|
230
|
+
try {
|
|
231
|
+
const response = await fetch(statusUrl);
|
|
232
|
+
const data = await response.json();
|
|
233
|
+
|
|
234
|
+
if (data.status === 'success') {
|
|
235
|
+
window.location.href = '/success';
|
|
236
|
+
} else if (data.status === 'failed' || data.status === 'timeout') {
|
|
237
|
+
window.location.href = '/error?message=' + encodeURIComponent(data.message || 'Authentication failed');
|
|
238
|
+
}
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error('Status check failed:', error);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
setInterval(checkStatus, 2000);
|
|
245
|
+
checkStatus();
|
|
246
|
+
</script>
|
|
247
|
+
</body>
|
|
248
|
+
</html>`;
|
|
249
|
+
}
|
|
250
|
+
export function getSuccessHtml() {
|
|
251
|
+
return `<!DOCTYPE html>
|
|
252
|
+
<html lang="en">
|
|
253
|
+
<head>
|
|
254
|
+
<meta charset="UTF-8">
|
|
255
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
256
|
+
<title>Authentication Successful</title>
|
|
257
|
+
<style>
|
|
258
|
+
* {
|
|
259
|
+
margin: 0;
|
|
260
|
+
padding: 0;
|
|
261
|
+
box-sizing: border-box;
|
|
262
|
+
}
|
|
263
|
+
body {
|
|
264
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
265
|
+
background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
|
|
266
|
+
min-height: 100vh;
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
justify-content: center;
|
|
270
|
+
padding: 20px;
|
|
271
|
+
}
|
|
272
|
+
.container {
|
|
273
|
+
background: white;
|
|
274
|
+
border-radius: 16px;
|
|
275
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
276
|
+
max-width: 450px;
|
|
277
|
+
width: 100%;
|
|
278
|
+
padding: 48px 40px;
|
|
279
|
+
text-align: center;
|
|
280
|
+
animation: slideIn 0.4s ease-out;
|
|
281
|
+
}
|
|
282
|
+
@keyframes slideIn {
|
|
283
|
+
from {
|
|
284
|
+
opacity: 0;
|
|
285
|
+
transform: scale(0.9);
|
|
286
|
+
}
|
|
287
|
+
to {
|
|
288
|
+
opacity: 1;
|
|
289
|
+
transform: scale(1);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
.checkmark {
|
|
293
|
+
width: 80px;
|
|
294
|
+
height: 80px;
|
|
295
|
+
margin: 0 auto 24px;
|
|
296
|
+
position: relative;
|
|
297
|
+
}
|
|
298
|
+
.checkmarkcle {
|
|
299
|
+
width: 80px;
|
|
300
|
+
height: 80px;
|
|
301
|
+
border-radius: 50%;
|
|
302
|
+
background: #48bb78;
|
|
303
|
+
animation: scaleIn 0.5s ease-out;
|
|
304
|
+
}
|
|
305
|
+
@keyframes scaleIn {
|
|
306
|
+
from {
|
|
307
|
+
transform: scale(0);
|
|
308
|
+
}
|
|
309
|
+
to {
|
|
310
|
+
transform: scale(1);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
.checkmark-check {
|
|
314
|
+
position: absolute;
|
|
315
|
+
top: 50%;
|
|
316
|
+
left: 50%;
|
|
317
|
+
transform: translate(-50%, -50%);
|
|
318
|
+
width: 30px;
|
|
319
|
+
height: 50px;
|
|
320
|
+
border: solid white;
|
|
321
|
+
border-width: 0 6px 6px 0;
|
|
322
|
+
transform: translate(-50%, -60%) rotate(45deg);
|
|
323
|
+
animation: checkmark 0.5s 0.3s ease-out forwards;
|
|
324
|
+
opacity: 0;
|
|
325
|
+
}
|
|
326
|
+
@keyframes checkmark {
|
|
327
|
+
to {
|
|
328
|
+
opacity: 1;
|
|
329
|
+
transform: translate(-50%, -60%) rotate(45deg) scale(1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
h1 {
|
|
333
|
+
color: #1a202c;
|
|
334
|
+
font-size: 28px;
|
|
335
|
+
font-weight: 700;
|
|
336
|
+
margin-bottom: 12px;
|
|
337
|
+
}
|
|
338
|
+
.message {
|
|
339
|
+
color: #718096;
|
|
340
|
+
font-size: 16px;
|
|
341
|
+
line-height: 1.6;
|
|
342
|
+
margin-bottom: 24px;
|
|
343
|
+
}
|
|
344
|
+
.auto-close {
|
|
345
|
+
color: #a0aec0;
|
|
346
|
+
font-size: 14px;
|
|
347
|
+
padding-top: 24px;
|
|
348
|
+
border-top: 1px solid #e2e8f0;
|
|
349
|
+
}
|
|
350
|
+
@media (max-width: 600px) {
|
|
351
|
+
.container {
|
|
352
|
+
padding: 32px 24px;
|
|
353
|
+
}
|
|
354
|
+
h1 {
|
|
355
|
+
font-size: 24px;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
</style>
|
|
359
|
+
</head>
|
|
360
|
+
<body>
|
|
361
|
+
<div class="container">
|
|
362
|
+
<div class="checkmark">
|
|
363
|
+
<div class="checkmark-circle"></div>
|
|
364
|
+
<div class="checkmark-check"></div>
|
|
365
|
+
</div>
|
|
366
|
+
<h1>Authentication Successful!</h1>
|
|
367
|
+
<p class="message">You have been successfully authenticated with AWS Builder ID. You can now close this window and return to your terminal.</p>
|
|
368
|
+
<div class="auto-close">This window will close automatically in <span id="countdown">3</span> seconds</div>
|
|
369
|
+
</div>
|
|
370
|
+
|
|
371
|
+
<script>
|
|
372
|
+
let seconds = 3;
|
|
373
|
+
const countdownEl = document.getElementById('countdown');
|
|
374
|
+
|
|
375
|
+
const interval = setInterval(() => {
|
|
376
|
+
seconds--;
|
|
377
|
+
if (countdownEl) {
|
|
378
|
+
countdownEl.textContent = seconds.toString();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (seconds <= 0) {
|
|
382
|
+
clearInterval(interval);
|
|
383
|
+
try {
|
|
384
|
+
window.close();
|
|
385
|
+
} catch (e) {
|
|
386
|
+
console.log('Couluto-close window');
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}, 1000);
|
|
390
|
+
</script>
|
|
391
|
+
</body>
|
|
392
|
+
</html>`;
|
|
393
|
+
}
|
|
394
|
+
export function getErrorHtml(message) {
|
|
395
|
+
const escapedMessage = escapeHtml(message);
|
|
396
|
+
return `<!DOCTYPE html>
|
|
397
|
+
<html lang="en">
|
|
398
|
+
<head>
|
|
399
|
+
<meta charset="UTF-8">
|
|
400
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
401
|
+
<title>Authentication Failed</title>
|
|
402
|
+
<style>
|
|
403
|
+
* {
|
|
404
|
+
margin: 0;
|
|
405
|
+
padding: 0;
|
|
406
|
+
box-sizing: border-box;
|
|
407
|
+
}
|
|
408
|
+
body {
|
|
409
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
410
|
+
background: linear-gradient(135deg, #fc8181 0%, #f56565 100%);
|
|
411
|
+
min-height: 100vh;
|
|
412
|
+
display: flex;
|
|
413
|
+
align-items: center;
|
|
414
|
+
justify-content: center;
|
|
415
|
+
padding: 20px;
|
|
416
|
+
}
|
|
417
|
+
.container {
|
|
418
|
+
background: white;
|
|
419
|
+
border-radius: 16px;
|
|
420
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
421
|
+
max-width: 450px;
|
|
422
|
+
width: 100%;
|
|
423
|
+
padding: 48px 40px;
|
|
424
|
+
text-align: center;
|
|
425
|
+
animation: slideIn 0.4s ease-out;
|
|
426
|
+
}
|
|
427
|
+
@keyframes slideIn {
|
|
428
|
+
from {
|
|
429
|
+
opacity: 0;
|
|
430
|
+
transform: scale(0.9);
|
|
431
|
+
}
|
|
432
|
+
to {
|
|
433
|
+
opacity: 1;
|
|
434
|
+
transform: scale(1);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
.error-icon {
|
|
438
|
+
width: 80px;
|
|
439
|
+
height: 80px;
|
|
440
|
+
margin: 0 auto 24px;
|
|
441
|
+
position: relative;
|
|
442
|
+
}
|
|
443
|
+
.error-circle {
|
|
444
|
+
width: 80px;
|
|
445
|
+
height: 80px;
|
|
446
|
+
border-radius: 50%;
|
|
447
|
+
background: #fc8181;
|
|
448
|
+
animation: scaleIn 0.5s ease-out;
|
|
449
|
+
}
|
|
450
|
+
@keyframes scaleIn {
|
|
451
|
+
from {
|
|
452
|
+
transform: scale(0);
|
|
453
|
+
}
|
|
454
|
+
to {
|
|
455
|
+
transform: scale(1);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
.error-x {
|
|
459
|
+
position: absolute;
|
|
460
|
+
top: 50%;
|
|
461
|
+
left: 50%;
|
|
462
|
+
transform: translate(-50%, -50%);
|
|
463
|
+
width: 40px;
|
|
464
|
+
height: 40px;
|
|
465
|
+
}
|
|
466
|
+
.error-x::before,
|
|
467
|
+
.error-x::after {
|
|
468
|
+
content: '';
|
|
469
|
+
position: absolute;
|
|
470
|
+
top: 50%;
|
|
471
|
+
left: 50%;
|
|
472
|
+
width: 40px;
|
|
473
|
+
height: 6px;
|
|
474
|
+
background: white;
|
|
475
|
+
border-radius: 3px;
|
|
476
|
+
animation: xmark 0.5s 0.3s ease-out forwards;
|
|
477
|
+
opacity: 0;
|
|
478
|
+
}
|
|
479
|
+
.error-x::before {
|
|
480
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
481
|
+
}
|
|
482
|
+
.error-x::after {
|
|
483
|
+
transform: translate(-50%, -50%) rotate(-45deg);
|
|
484
|
+
}
|
|
485
|
+
@keyframes xmark {
|
|
486
|
+
to {
|
|
487
|
+
opacity: 1;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
h1 {
|
|
491
|
+
color: #1a202c;
|
|
492
|
+
font-size: 28px;
|
|
493
|
+
font-weight: 700;
|
|
494
|
+
margin-bottom: 12px;
|
|
495
|
+
}
|
|
496
|
+
.message {
|
|
497
|
+
color: #718096;
|
|
498
|
+
font-size: 16px;
|
|
499
|
+
line-height: 1.6;
|
|
500
|
+
margin-bottom: 16px;
|
|
501
|
+
}
|
|
502
|
+
.error-details {
|
|
503
|
+
background: #fff5f5;
|
|
504
|
+
border: 1px solid #feb2b2;
|
|
505
|
+
border-radius: 8px;
|
|
506
|
+
padding: 16px;
|
|
507
|
+
margin-bottom: 24px;
|
|
508
|
+
color: #c53030;
|
|
509
|
+
font-size: 14px;
|
|
510
|
+
word-break: break-word;
|
|
511
|
+
}
|
|
512
|
+
.instruction {
|
|
513
|
+
color: #4a5568;
|
|
514
|
+
font-size: 15px;
|
|
515
|
+
margin-bottom: 24px;
|
|
516
|
+
}
|
|
517
|
+
.auto-close {
|
|
518
|
+
color: #a0aec0;
|
|
519
|
+
font-size: 14px;
|
|
520
|
+
padding-top: 24px;
|
|
521
|
+
border-top: 1px solid #e2e8f0;
|
|
522
|
+
}
|
|
523
|
+
@media (max-width: 600px) {
|
|
524
|
+
.container {
|
|
525
|
+
padding: 32px 24px;
|
|
526
|
+
}
|
|
527
|
+
h1 {
|
|
528
|
+
font-size: 24px;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
</style>
|
|
532
|
+
</head>
|
|
533
|
+
<body>
|
|
534
|
+
<div class="container">
|
|
535
|
+
<div class="error-icon">
|
|
536
|
+
<div class="error-circle"></div>
|
|
537
|
+
<div class="error-x"></div>
|
|
538
|
+
</div>
|
|
539
|
+
<h1>Authentication Failed</h1>
|
|
540
|
+
<p class="message">We were unable to complete the authentication process.</p>
|
|
541
|
+
<div class="error-details">${escapedMessage}</div>
|
|
542
|
+
<p class="instruction">You can close this window and try again from your terminal.</p>
|
|
543
|
+
<div class="auto-close">This window will close automatically in <span id="countdown">5</span> seconds</div>
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
<script>
|
|
547
|
+
let seconds = 5;
|
|
548
|
+
const countdownEl = document.getElementById('countdown');
|
|
549
|
+
|
|
550
|
+
const interval = setInterval(() => {
|
|
551
|
+
seconds--;
|
|
552
|
+
if (countdownEl) {
|
|
553
|
+
countdownEl.textContent = seconds.toString();
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (seconds <= 0) {
|
|
557
|
+
clearInterval(interval);
|
|
558
|
+
try {
|
|
559
|
+
window.close();
|
|
560
|
+
} catch (e) {
|
|
561
|
+
console.log('Could not auto-close window');
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}, 1000);
|
|
565
|
+
</script>
|
|
566
|
+
</body>
|
|
567
|
+
</html>`;
|
|
568
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { KiroAuthMethod, KiroRegion } from './types';
|
|
2
|
+
export declare function promptAuthMethod(): Promise<KiroAuthMethod>;
|
|
3
|
+
export declare function promptRegion(): Promise<KiroRegion>;
|
|
4
|
+
export declare function promptConfirmation(message: string): Promise<boolean>;
|
|
5
|
+
export declare function displayAuthUrl(url: string): void;
|
|
6
|
+
export declare function cleanup(): void;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
import * as logger from './logger';
|
|
3
|
+
let rl = null;
|
|
4
|
+
function getReadline() {
|
|
5
|
+
if (!rl) {
|
|
6
|
+
rl = createInterface({
|
|
7
|
+
input: process.stdin,
|
|
8
|
+
output: process.stdout,
|
|
9
|
+
});
|
|
10
|
+
rl.on('SIGINT', () => {
|
|
11
|
+
logger.log('Received SIGINT, closing readline');
|
|
12
|
+
closeReadline();
|
|
13
|
+
process.exit(130);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return rl;
|
|
17
|
+
}
|
|
18
|
+
function closeReadline() {
|
|
19
|
+
if (rl) {
|
|
20
|
+
rl.close();
|
|
21
|
+
rl = null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function question(prompt) {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
const readline = getReadline();
|
|
27
|
+
readline.question(prompt, (answer) => {
|
|
28
|
+
resolve(answer.trim());
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function clearLine() {
|
|
33
|
+
if (process.stdout.isTTY) {
|
|
34
|
+
process.stdout.clearLine(0);
|
|
35
|
+
process.stdout.cursorTo(0);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function promptAuthMethod() {
|
|
39
|
+
console.log('\nSelect authentication method:');
|
|
40
|
+
console.log(' 1. Social (GitHub, Google, etc.)');
|
|
41
|
+
console.log(' 2. IDC (Identity Center)');
|
|
42
|
+
while (true) {
|
|
43
|
+
const answer = await question('\nEnter your choice (1 or 2): ');
|
|
44
|
+
if (answer === '1' || answer.toLowerCase() === 'social') {
|
|
45
|
+
clearLine();
|
|
46
|
+
return 'social';
|
|
47
|
+
}
|
|
48
|
+
if (answer === '2' || answer.toLowerCase() === 'idc') {
|
|
49
|
+
clearLine();
|
|
50
|
+
return 'idc';
|
|
51
|
+
}
|
|
52
|
+
console.log('Invalid choice. Please enter 1 or 2.');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function promptRegion() {
|
|
56
|
+
console.log('\nSelect AWS region:');
|
|
57
|
+
console.log(' 1. us-east-1 (default)');
|
|
58
|
+
console.log(' 2. us-west-2');
|
|
59
|
+
while (true) {
|
|
60
|
+
const answer = await question('\nEnter your choice (1 or 2, default: 1): ');
|
|
61
|
+
if (!answer || answer === '1' || answer.toLowerCase() === 'us-east-1') {
|
|
62
|
+
clearLine();
|
|
63
|
+
return 'us-east-1';
|
|
64
|
+
}
|
|
65
|
+
if (answer === '2' || answer.toLowerCase() === 'us-west-2') {
|
|
66
|
+
clearLine();
|
|
67
|
+
return 'us-west-2';
|
|
68
|
+
}
|
|
69
|
+
console.log('Invalid choice. Please enter 1 or 2.');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function promptConfirmation(message) {
|
|
73
|
+
while (true) {
|
|
74
|
+
const answer = await question(`${message} (y/n): `);
|
|
75
|
+
const lower = answer.toLowerCase();
|
|
76
|
+
if (lower === 'y' || lower === 'yes') {
|
|
77
|
+
clearLine();
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (lower === 'n' || lower === 'no') {
|
|
81
|
+
clearLine();
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
console.log('Invalid input. Please enter y or n.');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function displayAuthUrl(url) {
|
|
88
|
+
console.log('\n' + '='.repeat(70));
|
|
89
|
+
console.log('Authentication Required');
|
|
90
|
+
console.log('='.repeat(70));
|
|
91
|
+
console.log('\nPlease open the following URL in your browser to authenticate:\n');
|
|
92
|
+
console.log(` ${url}\n`);
|
|
93
|
+
console.log('Waiting for authentication to complete...');
|
|
94
|
+
console.log('='.repeat(70) + '\n');
|
|
95
|
+
}
|
|
96
|
+
export function cleanup() {
|
|
97
|
+
closeReadline();
|
|
98
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type KiroConfig } from './schema';
|
|
2
|
+
export declare function getUserConfigPath(): string;
|
|
3
|
+
export declare function getProjectConfigPath(directory: string): string;
|
|
4
|
+
export declare function loadConfig(directory: string): KiroConfig;
|
|
5
|
+
export declare function configExists(path: string): boolean;
|
|
6
|
+
export declare function getDefaultLogsDir(): string;
|