@edgible-team/cli 1.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 +136 -0
- package/README.md +450 -0
- package/dist/client/api-client.js +1057 -0
- package/dist/client/index.js +21 -0
- package/dist/commands/agent.js +1280 -0
- package/dist/commands/ai.js +608 -0
- package/dist/commands/application.js +885 -0
- package/dist/commands/auth.js +570 -0
- package/dist/commands/base/BaseCommand.js +93 -0
- package/dist/commands/base/CommandHandler.js +7 -0
- package/dist/commands/base/command-wrapper.js +58 -0
- package/dist/commands/base/middleware.js +77 -0
- package/dist/commands/config.js +116 -0
- package/dist/commands/connectivity.js +59 -0
- package/dist/commands/debug.js +98 -0
- package/dist/commands/discover.js +144 -0
- package/dist/commands/examples/migrated-command-example.js +180 -0
- package/dist/commands/gateway.js +494 -0
- package/dist/commands/managedGateway.js +787 -0
- package/dist/commands/utils/config-validator.js +76 -0
- package/dist/commands/utils/gateway-prompt.js +79 -0
- package/dist/commands/utils/input-parser.js +120 -0
- package/dist/commands/utils/output-formatter.js +109 -0
- package/dist/config/app-config.js +99 -0
- package/dist/detection/SystemCapabilityDetector.js +1244 -0
- package/dist/detection/ToolDetector.js +305 -0
- package/dist/detection/WorkloadDetector.js +314 -0
- package/dist/di/bindings.js +99 -0
- package/dist/di/container.js +88 -0
- package/dist/di/types.js +32 -0
- package/dist/index.js +52 -0
- package/dist/interfaces/IDaemonManager.js +3 -0
- package/dist/repositories/config-repository.js +62 -0
- package/dist/repositories/gateway-repository.js +35 -0
- package/dist/scripts/postinstall.js +101 -0
- package/dist/services/AgentStatusManager.js +299 -0
- package/dist/services/ConnectivityTester.js +271 -0
- package/dist/services/DependencyInstaller.js +475 -0
- package/dist/services/LocalAgentManager.js +2216 -0
- package/dist/services/application/ApplicationService.js +299 -0
- package/dist/services/auth/AuthService.js +214 -0
- package/dist/services/aws.js +644 -0
- package/dist/services/daemon/DaemonManagerFactory.js +65 -0
- package/dist/services/daemon/DockerDaemonManager.js +395 -0
- package/dist/services/daemon/LaunchdDaemonManager.js +257 -0
- package/dist/services/daemon/PodmanDaemonManager.js +369 -0
- package/dist/services/daemon/SystemdDaemonManager.js +221 -0
- package/dist/services/daemon/WindowsServiceDaemonManager.js +210 -0
- package/dist/services/daemon/index.js +16 -0
- package/dist/services/edgible.js +3060 -0
- package/dist/services/gateway/GatewayService.js +334 -0
- package/dist/state/config.js +146 -0
- package/dist/types/AgentConfig.js +5 -0
- package/dist/types/AgentStatus.js +5 -0
- package/dist/types/ApiClient.js +5 -0
- package/dist/types/ApiRequests.js +5 -0
- package/dist/types/ApiResponses.js +5 -0
- package/dist/types/Application.js +5 -0
- package/dist/types/CaddyJson.js +5 -0
- package/dist/types/UnifiedAgentStatus.js +56 -0
- package/dist/types/WireGuard.js +5 -0
- package/dist/types/Workload.js +5 -0
- package/dist/types/agent.js +5 -0
- package/dist/types/command-options.js +5 -0
- package/dist/types/connectivity.js +5 -0
- package/dist/types/errors.js +250 -0
- package/dist/types/gateway-types.js +5 -0
- package/dist/types/index.js +48 -0
- package/dist/types/models/ApplicationData.js +5 -0
- package/dist/types/models/CertificateData.js +5 -0
- package/dist/types/models/DeviceData.js +5 -0
- package/dist/types/models/DevicePoolData.js +5 -0
- package/dist/types/models/OrganizationData.js +5 -0
- package/dist/types/models/OrganizationInviteData.js +5 -0
- package/dist/types/models/ProviderConfiguration.js +5 -0
- package/dist/types/models/ResourceData.js +5 -0
- package/dist/types/models/ServiceResourceData.js +5 -0
- package/dist/types/models/UserData.js +5 -0
- package/dist/types/route.js +5 -0
- package/dist/types/validation/schemas.js +218 -0
- package/dist/types/validation.js +5 -0
- package/dist/utils/FileIntegrityManager.js +256 -0
- package/dist/utils/PathMigration.js +219 -0
- package/dist/utils/PathResolver.js +235 -0
- package/dist/utils/PlatformDetector.js +277 -0
- package/dist/utils/console-logger.js +130 -0
- package/dist/utils/docker-compose-parser.js +179 -0
- package/dist/utils/errors.js +130 -0
- package/dist/utils/health-checker.js +155 -0
- package/dist/utils/json-logger.js +72 -0
- package/dist/utils/log-formatter.js +293 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/network-utils.js +217 -0
- package/dist/utils/output.js +182 -0
- package/dist/utils/passwordValidation.js +91 -0
- package/dist/utils/progress.js +167 -0
- package/dist/utils/sudo-checker.js +22 -0
- package/dist/utils/urls.js +32 -0
- package/dist/utils/validation.js +31 -0
- package/dist/validation/schemas.js +175 -0
- package/dist/validation/validator.js +67 -0
- package/package.json +83 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Application service
|
|
4
|
+
* Handles application management operations
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ApplicationServiceImpl = void 0;
|
|
8
|
+
const client_1 = require("../../client");
|
|
9
|
+
class ApplicationServiceImpl {
|
|
10
|
+
constructor(baseUrl, configRepository, authService, logger) {
|
|
11
|
+
this.applications = [];
|
|
12
|
+
this.baseUrl = baseUrl;
|
|
13
|
+
this.configRepository = configRepository;
|
|
14
|
+
this.authService = authService;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.apiClient = (0, client_1.createApiClient)(baseUrl);
|
|
17
|
+
this.restoreTokensFromApiClient();
|
|
18
|
+
}
|
|
19
|
+
restoreTokensFromApiClient() {
|
|
20
|
+
const accessToken = this.authService.getAccessToken();
|
|
21
|
+
const idToken = this.authService.getIdToken();
|
|
22
|
+
const refreshToken = this.authService.getRefreshToken();
|
|
23
|
+
if (accessToken) {
|
|
24
|
+
this.apiClient.setAccessToken(accessToken);
|
|
25
|
+
}
|
|
26
|
+
if (idToken) {
|
|
27
|
+
this.apiClient.setIdToken(idToken);
|
|
28
|
+
}
|
|
29
|
+
if (refreshToken) {
|
|
30
|
+
this.apiClient.setRefreshToken(refreshToken);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
generateServingIp() {
|
|
34
|
+
// Generate a mock IP in the 10.x.x.x range
|
|
35
|
+
const octet1 = 10;
|
|
36
|
+
const octet2 = Math.floor(Math.random() * 255);
|
|
37
|
+
const octet3 = Math.floor(Math.random() * 255);
|
|
38
|
+
const octet4 = Math.floor(Math.random() * 254) + 1; // Avoid .0
|
|
39
|
+
return `${octet1}.${octet2}.${octet3}.${octet4}`;
|
|
40
|
+
}
|
|
41
|
+
async setupApplication(workload, port, protocol = 'http', description, gatewayId) {
|
|
42
|
+
try {
|
|
43
|
+
// Attempt auto re-login if tokens are missing but credentials are available
|
|
44
|
+
await this.authService.attemptAutoRelogin();
|
|
45
|
+
this.restoreTokensFromApiClient();
|
|
46
|
+
this.logger.info(`Setting up application for workload: ${workload.name}`);
|
|
47
|
+
// Get organization ID from config
|
|
48
|
+
const config = this.configRepository.getConfig();
|
|
49
|
+
if (!config.organizationId) {
|
|
50
|
+
throw new Error('No organization ID found. Please login first.');
|
|
51
|
+
}
|
|
52
|
+
// Generate a serving IP (in real implementation, this would come from the API)
|
|
53
|
+
const servingIp = this.generateServingIp();
|
|
54
|
+
const url = `${protocol}://${servingIp}:${port}`;
|
|
55
|
+
// Create application via API
|
|
56
|
+
const deviceIds = [config.deviceId || 'unknown'];
|
|
57
|
+
const createRequest = {
|
|
58
|
+
name: `${workload.name}-app`,
|
|
59
|
+
description: description || `Application for ${workload.name}`,
|
|
60
|
+
organizationId: config.organizationId,
|
|
61
|
+
configuration: {
|
|
62
|
+
port: port,
|
|
63
|
+
protocol: protocol,
|
|
64
|
+
url,
|
|
65
|
+
},
|
|
66
|
+
deviceIds: deviceIds,
|
|
67
|
+
gatewayIds: gatewayId ? [gatewayId] : [],
|
|
68
|
+
subtype: 'local-preexisting',
|
|
69
|
+
};
|
|
70
|
+
const response = await this.apiClient.createApplication(createRequest);
|
|
71
|
+
// Validate API response
|
|
72
|
+
if (!response || !response.application) {
|
|
73
|
+
throw new Error('Invalid API response: missing application data');
|
|
74
|
+
}
|
|
75
|
+
if (!response.application.id) {
|
|
76
|
+
throw new Error('Invalid API response: missing application ID');
|
|
77
|
+
}
|
|
78
|
+
// Map API response to CLI Application format
|
|
79
|
+
const application = {
|
|
80
|
+
id: response.application.id,
|
|
81
|
+
name: `${workload.name}-app`,
|
|
82
|
+
workloadId: workload.id,
|
|
83
|
+
servingIp: servingIp,
|
|
84
|
+
port: port,
|
|
85
|
+
protocol: protocol,
|
|
86
|
+
status: 'active',
|
|
87
|
+
createdAt: new Date().toISOString(),
|
|
88
|
+
description: description || `Application for ${workload.name}`,
|
|
89
|
+
};
|
|
90
|
+
return application;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
this.logger.error('Error setting up application', error);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async getApplications() {
|
|
98
|
+
try {
|
|
99
|
+
// Attempt auto re-login if tokens are missing but credentials are available
|
|
100
|
+
await this.authService.attemptAutoRelogin();
|
|
101
|
+
this.restoreTokensFromApiClient();
|
|
102
|
+
this.logger.debug('Getting applications');
|
|
103
|
+
const config = this.configRepository.getConfig();
|
|
104
|
+
let organizationId;
|
|
105
|
+
// Check if we have an organization ID in the config (device login)
|
|
106
|
+
if (config.organizationId) {
|
|
107
|
+
organizationId = config.organizationId;
|
|
108
|
+
}
|
|
109
|
+
else if (config.email) {
|
|
110
|
+
// User login - get their organizations first
|
|
111
|
+
this.logger.debug('Getting user organizations');
|
|
112
|
+
const userOrgs = await this.authService.getUserOrganizations(config.email);
|
|
113
|
+
// Filter for standard (non-billing) organizations only
|
|
114
|
+
const standardOrgs = userOrgs.organizations.filter((org) => org.organizationType !== 'billing');
|
|
115
|
+
if (standardOrgs.length === 0) {
|
|
116
|
+
this.logger.warn('No standard organizations found for this user');
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
// Use the first standard organization
|
|
120
|
+
organizationId = standardOrgs[0].organizationId;
|
|
121
|
+
this.logger.debug(`Using organization: ${standardOrgs[0].name}`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.logger.warn('No organization ID or email found. Please login first.');
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
// Call the real API to get organization applications
|
|
128
|
+
const response = await this.apiClient.getOrganizationApplications(organizationId);
|
|
129
|
+
// Map API response to CLI Application format
|
|
130
|
+
const applications = response.applications.map((app) => {
|
|
131
|
+
// Parse URL/hostname safely
|
|
132
|
+
let servingIp = 'unknown';
|
|
133
|
+
let port = 80;
|
|
134
|
+
let protocol = 'http';
|
|
135
|
+
if (app.url) {
|
|
136
|
+
try {
|
|
137
|
+
// Check if it's a full URL or just a hostname
|
|
138
|
+
if (app.url.startsWith('http://') || app.url.startsWith('https://')) {
|
|
139
|
+
const url = new URL(app.url);
|
|
140
|
+
servingIp = url.hostname;
|
|
141
|
+
port = parseInt(url.port) || (url.protocol === 'https:' ? 443 : 80);
|
|
142
|
+
protocol = url.protocol === 'https:' ? 'https' : 'http';
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// It's just a hostname
|
|
146
|
+
servingIp = app.url;
|
|
147
|
+
// Get port and protocol from configuration if available
|
|
148
|
+
if (app.configuration?.port) {
|
|
149
|
+
port = typeof app.configuration.port === 'number'
|
|
150
|
+
? app.configuration.port
|
|
151
|
+
: parseInt(String(app.configuration.port)) || 80;
|
|
152
|
+
}
|
|
153
|
+
if (app.configuration?.protocol) {
|
|
154
|
+
const configProtocol = String(app.configuration.protocol).toLowerCase();
|
|
155
|
+
if (configProtocol === 'https' || configProtocol === 'http' ||
|
|
156
|
+
configProtocol === 'tcp' || configProtocol === 'udp') {
|
|
157
|
+
protocol = configProtocol;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
// If URL parsing fails, treat as hostname
|
|
164
|
+
servingIp = app.url;
|
|
165
|
+
// Get port and protocol from configuration
|
|
166
|
+
if (app.configuration?.port) {
|
|
167
|
+
port = typeof app.configuration.port === 'number'
|
|
168
|
+
? app.configuration.port
|
|
169
|
+
: parseInt(String(app.configuration.port)) || 80;
|
|
170
|
+
}
|
|
171
|
+
if (app.configuration?.protocol) {
|
|
172
|
+
const configProtocol = String(app.configuration.protocol).toLowerCase();
|
|
173
|
+
if (configProtocol === 'https' || configProtocol === 'http' ||
|
|
174
|
+
configProtocol === 'tcp' || configProtocol === 'udp') {
|
|
175
|
+
protocol = configProtocol;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// No URL, try to get from configuration
|
|
182
|
+
if (app.configuration?.port) {
|
|
183
|
+
port = typeof app.configuration.port === 'number'
|
|
184
|
+
? app.configuration.port
|
|
185
|
+
: parseInt(String(app.configuration.port)) || 80;
|
|
186
|
+
}
|
|
187
|
+
if (app.configuration?.protocol) {
|
|
188
|
+
const configProtocol = String(app.configuration.protocol).toLowerCase();
|
|
189
|
+
if (configProtocol === 'https' || configProtocol === 'http' ||
|
|
190
|
+
configProtocol === 'tcp' || configProtocol === 'udp') {
|
|
191
|
+
protocol = configProtocol;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
id: app.id,
|
|
197
|
+
name: app.name,
|
|
198
|
+
workloadId: app.deviceIds[0] || 'unknown', // Use first device ID as workload ID
|
|
199
|
+
servingIp,
|
|
200
|
+
port,
|
|
201
|
+
protocol,
|
|
202
|
+
status: app.status === 'running' ? 'active' : 'inactive',
|
|
203
|
+
createdAt: app.createdAt,
|
|
204
|
+
description: app.description,
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
return applications;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.logger.error('Error getting applications', error);
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async getApplication(id) {
|
|
215
|
+
try {
|
|
216
|
+
// Try to get from API first
|
|
217
|
+
try {
|
|
218
|
+
const response = await this.apiClient.getApplication(id);
|
|
219
|
+
const appData = response.application;
|
|
220
|
+
// Extract port and protocol from configuration if needed
|
|
221
|
+
const port = appData.configuration?.port || 3000;
|
|
222
|
+
const protocol = (appData.configuration?.protocol || 'http');
|
|
223
|
+
const workloadId = appData.configuration?.workloadId || '';
|
|
224
|
+
return {
|
|
225
|
+
id: appData.id,
|
|
226
|
+
name: appData.name,
|
|
227
|
+
description: appData.description || '',
|
|
228
|
+
servingIp: this.generateServingIp(),
|
|
229
|
+
port: typeof port === 'number' ? port : 3000,
|
|
230
|
+
protocol: protocol,
|
|
231
|
+
status: appData.status === 'running' ? 'active' : 'inactive',
|
|
232
|
+
workloadId: workloadId || undefined,
|
|
233
|
+
createdAt: appData.createdAt || new Date().toISOString(),
|
|
234
|
+
url: appData.url,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
catch (apiError) {
|
|
238
|
+
// Fall back to local storage if API fails
|
|
239
|
+
const application = this.applications.find((app) => app.id === id);
|
|
240
|
+
if (application) {
|
|
241
|
+
return application;
|
|
242
|
+
}
|
|
243
|
+
throw new Error(`Application not found: ${id}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
this.logger.error('Error getting application', error);
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
async deleteApplication(id) {
|
|
252
|
+
try {
|
|
253
|
+
// Attempt auto re-login if tokens are missing but credentials are available
|
|
254
|
+
await this.authService.attemptAutoRelogin();
|
|
255
|
+
this.restoreTokensFromApiClient();
|
|
256
|
+
this.logger.info(`Deleting application: ${id}`);
|
|
257
|
+
await this.apiClient.deleteApplication(id);
|
|
258
|
+
this.logger.info('Application deleted successfully', { applicationId: id });
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
this.logger.error('Error deleting application', error);
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async createApplicationProgrammatically(params) {
|
|
267
|
+
try {
|
|
268
|
+
// Attempt auto re-login if tokens are missing but credentials are available
|
|
269
|
+
await this.authService.attemptAutoRelogin();
|
|
270
|
+
this.restoreTokensFromApiClient();
|
|
271
|
+
const config = this.configRepository.getConfig();
|
|
272
|
+
if (!config.organizationId) {
|
|
273
|
+
throw new Error('Not logged in. Please run "edgible login" first.');
|
|
274
|
+
}
|
|
275
|
+
const createRequest = {
|
|
276
|
+
name: params.name,
|
|
277
|
+
description: params.description,
|
|
278
|
+
organizationId: config.organizationId,
|
|
279
|
+
configuration: { port: params.port, protocol: params.protocol },
|
|
280
|
+
hostnames: params.hostnames,
|
|
281
|
+
deviceIds: params.deviceIds,
|
|
282
|
+
gatewayIds: params.gatewayIds,
|
|
283
|
+
subtype: params.subtype,
|
|
284
|
+
};
|
|
285
|
+
// Add useManagedGateway if specified
|
|
286
|
+
if (params.useManagedGateway !== undefined) {
|
|
287
|
+
createRequest.useManagedGateway = params.useManagedGateway;
|
|
288
|
+
}
|
|
289
|
+
const response = await this.apiClient.createApplication(createRequest);
|
|
290
|
+
return response.application;
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
this.logger.error('Failed to create application', error);
|
|
294
|
+
throw new Error(`Failed to create application: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.ApplicationServiceImpl = ApplicationServiceImpl;
|
|
299
|
+
//# sourceMappingURL=ApplicationService.js.map
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Authentication service
|
|
4
|
+
* Handles user and device authentication operations
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AuthServiceImpl = void 0;
|
|
8
|
+
const client_1 = require("../../client");
|
|
9
|
+
const passwordValidation_1 = require("../../utils/passwordValidation");
|
|
10
|
+
class AuthServiceImpl {
|
|
11
|
+
constructor(baseUrl, configRepository, logger) {
|
|
12
|
+
this.baseUrl = baseUrl;
|
|
13
|
+
this.configRepository = configRepository;
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
this.apiClient = (0, client_1.createApiClient)(baseUrl);
|
|
16
|
+
this.restoreTokensFromConfig();
|
|
17
|
+
}
|
|
18
|
+
restoreTokensFromConfig() {
|
|
19
|
+
const config = this.configRepository.getConfig();
|
|
20
|
+
if (config.accessToken) {
|
|
21
|
+
this.apiClient.setAccessToken(config.accessToken);
|
|
22
|
+
}
|
|
23
|
+
if (config.idToken) {
|
|
24
|
+
this.apiClient.setIdToken(config.idToken);
|
|
25
|
+
}
|
|
26
|
+
if (config.refreshToken) {
|
|
27
|
+
this.apiClient.setRefreshToken(config.refreshToken);
|
|
28
|
+
}
|
|
29
|
+
this.logger.debug('Token restoration', {
|
|
30
|
+
hasAccessToken: !!config.accessToken,
|
|
31
|
+
hasIdToken: !!config.idToken,
|
|
32
|
+
hasRefreshToken: !!config.refreshToken,
|
|
33
|
+
organizationId: config.organizationId,
|
|
34
|
+
deviceId: config.deviceId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async attemptAutoRelogin() {
|
|
38
|
+
const config = this.configRepository.getConfig();
|
|
39
|
+
// If no tokens but we have device credentials, attempt automatic re-login
|
|
40
|
+
if (!config.idToken && !config.accessToken && config.deviceId && config.devicePassword) {
|
|
41
|
+
this.logger.debug('No tokens available, attempting automatic device re-login');
|
|
42
|
+
try {
|
|
43
|
+
await this.loginDevice(config.deviceId, config.devicePassword);
|
|
44
|
+
this.logger.debug('Automatic re-login successful');
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
this.logger.warn('Automatic re-login failed', error instanceof Error ? error.message : String(error));
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
saveTokensToConfig() {
|
|
55
|
+
const accessToken = this.apiClient.getAccessToken();
|
|
56
|
+
const idToken = this.apiClient.getIdToken();
|
|
57
|
+
const refreshToken = this.apiClient.getRefreshToken();
|
|
58
|
+
this.logger.debug('Saving tokens', {
|
|
59
|
+
hasAccessToken: !!accessToken,
|
|
60
|
+
hasIdToken: !!idToken,
|
|
61
|
+
hasRefreshToken: !!refreshToken,
|
|
62
|
+
});
|
|
63
|
+
this.configRepository.updateConfig({
|
|
64
|
+
accessToken,
|
|
65
|
+
idToken,
|
|
66
|
+
refreshToken,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async loginUser(email, password) {
|
|
70
|
+
try {
|
|
71
|
+
const loginRequest = { email, password };
|
|
72
|
+
const response = await this.apiClient.login(loginRequest);
|
|
73
|
+
this.saveTokensToConfig();
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
this.logger.error('Error logging in user', error);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async createDeviceWithOrganization(deviceName, password, userEmail) {
|
|
82
|
+
try {
|
|
83
|
+
// Validate password meets Cognito requirements
|
|
84
|
+
const passwordValidation = (0, passwordValidation_1.validateCognitoPassword)(password);
|
|
85
|
+
if (!passwordValidation.isValid) {
|
|
86
|
+
throw new Error(`Password validation failed: ${passwordValidation.errors.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
const request = {
|
|
89
|
+
name: deviceName,
|
|
90
|
+
description: `CLI device: ${deviceName}`,
|
|
91
|
+
type: 'laptop',
|
|
92
|
+
organizationName: `${deviceName} Organization`,
|
|
93
|
+
organizationDescription: `Organization created for device ${deviceName}`,
|
|
94
|
+
userEmail: userEmail,
|
|
95
|
+
password: password,
|
|
96
|
+
};
|
|
97
|
+
const response = await this.apiClient.createDeviceWithOrphanedOrganization(request);
|
|
98
|
+
return response;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.logger.error('Error creating device with organization', error);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async checkAccount(email) {
|
|
106
|
+
try {
|
|
107
|
+
// Clear any existing tokens before checking account
|
|
108
|
+
this.apiClient.clearTokens();
|
|
109
|
+
try {
|
|
110
|
+
await this.apiClient.login({ email, password: 'dummy' });
|
|
111
|
+
this.apiClient.clearTokens();
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
this.apiClient.clearTokens();
|
|
116
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
117
|
+
if (errorMessage.includes('UserNotFoundException') || errorMessage.includes('NotAuthorizedException')) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
this.apiClient.clearTokens();
|
|
125
|
+
this.logger.error('Error checking account', error);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async loginDevice(deviceId, password) {
|
|
130
|
+
try {
|
|
131
|
+
const loginRequest = { email: deviceId, password };
|
|
132
|
+
const response = await this.apiClient.login(loginRequest);
|
|
133
|
+
this.saveTokensToConfig();
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.logger.error('Error logging in device', error);
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async verifyDeviceCredentials(deviceId, password) {
|
|
142
|
+
try {
|
|
143
|
+
// Save current user tokens to restore later
|
|
144
|
+
const currentAccessToken = this.apiClient.getAccessToken();
|
|
145
|
+
const currentIdToken = this.apiClient.getIdToken();
|
|
146
|
+
const currentRefreshToken = this.apiClient.getRefreshToken();
|
|
147
|
+
// Create a temporary API client for verification
|
|
148
|
+
const tempApiClient = (0, client_1.createApiClient)(this.baseUrl);
|
|
149
|
+
const loginRequest = { email: deviceId, password };
|
|
150
|
+
try {
|
|
151
|
+
await tempApiClient.login(loginRequest);
|
|
152
|
+
// Restore user tokens
|
|
153
|
+
if (currentAccessToken) {
|
|
154
|
+
this.apiClient.setAccessToken(currentAccessToken);
|
|
155
|
+
}
|
|
156
|
+
if (currentIdToken) {
|
|
157
|
+
this.apiClient.setIdToken(currentIdToken);
|
|
158
|
+
}
|
|
159
|
+
if (currentRefreshToken) {
|
|
160
|
+
this.apiClient.setRefreshToken(currentRefreshToken);
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Verification failed, but restore user tokens anyway
|
|
166
|
+
if (currentAccessToken) {
|
|
167
|
+
this.apiClient.setAccessToken(currentAccessToken);
|
|
168
|
+
}
|
|
169
|
+
if (currentIdToken) {
|
|
170
|
+
this.apiClient.setIdToken(currentIdToken);
|
|
171
|
+
}
|
|
172
|
+
if (currentRefreshToken) {
|
|
173
|
+
this.apiClient.setRefreshToken(currentRefreshToken);
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
this.logger.error('Error verifying device credentials', error);
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async refreshToken(refreshToken) {
|
|
184
|
+
try {
|
|
185
|
+
const response = await this.apiClient.refreshToken({ refreshToken });
|
|
186
|
+
this.saveTokensToConfig();
|
|
187
|
+
return response;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
this.logger.error('Error refreshing token', error);
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
getAccessToken() {
|
|
195
|
+
return this.apiClient.getAccessToken();
|
|
196
|
+
}
|
|
197
|
+
getIdToken() {
|
|
198
|
+
return this.apiClient.getIdToken();
|
|
199
|
+
}
|
|
200
|
+
getRefreshToken() {
|
|
201
|
+
return this.apiClient.getRefreshToken();
|
|
202
|
+
}
|
|
203
|
+
async getUserOrganizations(email) {
|
|
204
|
+
try {
|
|
205
|
+
return await this.apiClient.getUserOrganizations(email);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
this.logger.error('Error getting user organizations', error);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.AuthServiceImpl = AuthServiceImpl;
|
|
214
|
+
//# sourceMappingURL=AuthService.js.map
|