@kumori/aurora-backend-handler 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/.gitlab-ci.yml +57 -0
- package/README.md +352 -0
- package/api/account-api-service.ts +1092 -0
- package/api/deploy-service-helper.ts +1611 -0
- package/api/environment-api-service.ts +542 -0
- package/api/marketplace-api-service.ts +1031 -0
- package/api/organizations-api-service.ts +0 -0
- package/api/planProvider-api-service.ts +24 -0
- package/api/reporting-api-service.ts +35 -0
- package/api/resources-api-service.ts +821 -0
- package/api/service-api-service.ts +796 -0
- package/api/tenant-api-service.ts +1260 -0
- package/api/user-api-service.ts +1161 -0
- package/backend-handler.ts +1127 -0
- package/environment.ts +7 -0
- package/event-helper.ts +577 -0
- package/event-names.ts +152 -0
- package/helpers/account-helper.ts +331 -0
- package/helpers/environment-helper.ts +289 -0
- package/helpers/link-helper.ts +114 -0
- package/helpers/plan-helper.ts +104 -0
- package/helpers/registry-helper.ts +134 -0
- package/helpers/resource-helper.ts +387 -0
- package/helpers/revision-helper.ts +899 -0
- package/helpers/service-helper.ts +627 -0
- package/helpers/tenant-helper.ts +191 -0
- package/helpers/token-helper.ts +107 -0
- package/helpers/user-helper.ts +140 -0
- package/jest.config.ts +40 -0
- package/jest.setup.js +4 -0
- package/package.json +50 -0
- package/test/backend-handler.test.ts +792 -0
- package/test/deploy-service-helper.test.ts +518 -0
- package/test/event-helper.test.ts +152 -0
- package/tsconfig.json +26 -0
- package/utils/utils.ts +78 -0
- package/websocket-manager.ts +1833 -0
|
@@ -0,0 +1,1260 @@
|
|
|
1
|
+
import { Notification, Registry, Tenant, tenantRole } from "@hestekumori/aurora-interfaces";
|
|
2
|
+
import { eventHelper } from "../backend-handler";
|
|
3
|
+
import { environment } from "../environment";
|
|
4
|
+
import {
|
|
5
|
+
initializeGlobalWebSocketClient,
|
|
6
|
+
getWebSocketStatus,
|
|
7
|
+
makeGlobalWebSocketRequest,
|
|
8
|
+
} from "../websocket-manager";
|
|
9
|
+
|
|
10
|
+
type Security = string;
|
|
11
|
+
interface DregistryBody {
|
|
12
|
+
spec: {
|
|
13
|
+
labels?: { [key: string]: string };
|
|
14
|
+
docker_server: string;
|
|
15
|
+
docker_username: string;
|
|
16
|
+
docker_password: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Function to create a tenant using the global WebSocket connection
|
|
21
|
+
* @param tenant Tenant object with the data of the tenant
|
|
22
|
+
* @param security Authorization token
|
|
23
|
+
* @returns The response of the WebSocket API
|
|
24
|
+
*/
|
|
25
|
+
export const createTenant = async (tenant: Tenant, security: Security) => {
|
|
26
|
+
try {
|
|
27
|
+
await initializeGlobalWebSocketClient(security);
|
|
28
|
+
|
|
29
|
+
const tenantBody =
|
|
30
|
+
tenant.npmRegistry && tenant.npmRegistry.endpoint !== ""
|
|
31
|
+
? {
|
|
32
|
+
tenant: tenant.name,
|
|
33
|
+
provider: tenant.plan?.provider || "",
|
|
34
|
+
plan: tenant.plan?.name || "",
|
|
35
|
+
spec: {
|
|
36
|
+
registry: {
|
|
37
|
+
kind: "git",
|
|
38
|
+
endpoint: tenant.npmRegistry.endpoint,
|
|
39
|
+
domain: tenant.npmRegistry.domain,
|
|
40
|
+
credentials: tenant.npmRegistry.credentials,
|
|
41
|
+
public: tenant.npmRegistry.public,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
: {
|
|
46
|
+
tenant: tenant.name,
|
|
47
|
+
provider: tenant.plan?.provider || "",
|
|
48
|
+
plan: tenant.plan?.name || "",
|
|
49
|
+
spec: {
|
|
50
|
+
registry: undefined,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const response = await makeGlobalWebSocketRequest(
|
|
55
|
+
"tenant:create_tenant",
|
|
56
|
+
tenantBody,
|
|
57
|
+
30000,
|
|
58
|
+
"CREATE",
|
|
59
|
+
tenant.name
|
|
60
|
+
);
|
|
61
|
+
const updatedTenant = { ...tenant, status: "pending" };
|
|
62
|
+
eventHelper.tenant.publish.created(updatedTenant);
|
|
63
|
+
const tenantCreatedNotification: Notification = {
|
|
64
|
+
type: "success",
|
|
65
|
+
subtype: "tenant-created",
|
|
66
|
+
date: Date.now().toString(),
|
|
67
|
+
status: "unread",
|
|
68
|
+
callToAction: false,
|
|
69
|
+
data: {
|
|
70
|
+
tenant: tenant.name,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
eventHelper.notification.publish.creation(tenantCreatedNotification);
|
|
74
|
+
return response;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error("Error creating tenant:", {
|
|
77
|
+
error,
|
|
78
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
79
|
+
tenant: tenant.name,
|
|
80
|
+
webSocketStatus: getWebSocketStatus(),
|
|
81
|
+
});
|
|
82
|
+
let contentMessage = "Unknown error";
|
|
83
|
+
let errorContent = "Unknown error";
|
|
84
|
+
|
|
85
|
+
if (
|
|
86
|
+
typeof error === "object" &&
|
|
87
|
+
error !== null &&
|
|
88
|
+
"error" in error &&
|
|
89
|
+
typeof (error as any).error === "object" &&
|
|
90
|
+
(error as any).error !== null
|
|
91
|
+
) {
|
|
92
|
+
if ("code" in (error as any).error) {
|
|
93
|
+
contentMessage = (error as any).error.code;
|
|
94
|
+
}
|
|
95
|
+
if ("content" in (error as any).error) {
|
|
96
|
+
errorContent = (error as any).error.content;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const tenantCreationErrorNotification: Notification = {
|
|
100
|
+
type: "error",
|
|
101
|
+
subtype: "tenant-creation-error",
|
|
102
|
+
info_content: {
|
|
103
|
+
code: contentMessage,
|
|
104
|
+
message: errorContent,
|
|
105
|
+
},
|
|
106
|
+
date: Date.now().toString(),
|
|
107
|
+
status: "unread",
|
|
108
|
+
callToAction: false,
|
|
109
|
+
data: {
|
|
110
|
+
tenant: tenant.name,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
eventHelper.notification.publish.creation(tenantCreationErrorNotification);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const deleteTenant = async (tenant: Tenant, security: string) => {
|
|
119
|
+
try {
|
|
120
|
+
await initializeGlobalWebSocketClient(security);
|
|
121
|
+
|
|
122
|
+
const deleteBody = {
|
|
123
|
+
tenant: tenant.name,
|
|
124
|
+
force: true,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const response = await makeGlobalWebSocketRequest(
|
|
128
|
+
"tenant:delete_tenant",
|
|
129
|
+
deleteBody,
|
|
130
|
+
30000,
|
|
131
|
+
"DELETE",
|
|
132
|
+
tenant.name
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// const updatedTenant = { ...tenant, status: "pending" };
|
|
136
|
+
// eventHelper.tenant.publish.deleted(updatedTenant);
|
|
137
|
+
// const tenantDeletedNotification: Notification = {
|
|
138
|
+
// type: "success",
|
|
139
|
+
// subtype: "tenant-deleted",
|
|
140
|
+
// date: Date.now().toString(),
|
|
141
|
+
// status: "unread",
|
|
142
|
+
// callToAction: false,
|
|
143
|
+
// };
|
|
144
|
+
// eventHelper.notification.publish.creation(tenantDeletedNotification);
|
|
145
|
+
return response;
|
|
146
|
+
} catch (err) {
|
|
147
|
+
console.error("Error in tenant deletion WebSocket request:", err);
|
|
148
|
+
eventHelper.tenant.publish.deletionError(tenant);
|
|
149
|
+
let contentMessage = "Unknown error";
|
|
150
|
+
let errorContent = "Unknown error";
|
|
151
|
+
|
|
152
|
+
if (
|
|
153
|
+
typeof err === "object" &&
|
|
154
|
+
err !== null &&
|
|
155
|
+
"error" in err &&
|
|
156
|
+
typeof (err as any).error === "object" &&
|
|
157
|
+
(err as any).error !== null
|
|
158
|
+
) {
|
|
159
|
+
if ("code" in (err as any).error) {
|
|
160
|
+
contentMessage = (err as any).error.code;
|
|
161
|
+
}
|
|
162
|
+
if ("content" in (err as any).error) {
|
|
163
|
+
errorContent = (err as any).error.content;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const tenantDeletionErrorNotification: Notification = {
|
|
167
|
+
type: "error",
|
|
168
|
+
subtype: "tenant-deletion-error",
|
|
169
|
+
info_content: {
|
|
170
|
+
code: contentMessage,
|
|
171
|
+
message: errorContent,
|
|
172
|
+
},
|
|
173
|
+
date: Date.now().toString(),
|
|
174
|
+
status: "unread",
|
|
175
|
+
callToAction: false,
|
|
176
|
+
data: {
|
|
177
|
+
tenant: tenant.name,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
eventHelper.notification.publish.creation(tenantDeletionErrorNotification);
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const updateTenant = async (tenant: Tenant, security: string) => {
|
|
186
|
+
try {
|
|
187
|
+
await initializeGlobalWebSocketClient(security);
|
|
188
|
+
|
|
189
|
+
const hasNpmRegistry =
|
|
190
|
+
tenant.npmRegistry && tenant.npmRegistry.endpoint !== "";
|
|
191
|
+
const hasPlan = tenant.plan?.name;
|
|
192
|
+
|
|
193
|
+
const updateBody: Record<string, any> = {
|
|
194
|
+
tenant: tenant.name,
|
|
195
|
+
spec: {
|
|
196
|
+
registry: hasNpmRegistry
|
|
197
|
+
? {
|
|
198
|
+
kind: "git",
|
|
199
|
+
endpoint: tenant.npmRegistry!.endpoint,
|
|
200
|
+
domain: tenant.npmRegistry!.domain,
|
|
201
|
+
credentials: tenant.npmRegistry!.credentials,
|
|
202
|
+
public: tenant.npmRegistry!.public,
|
|
203
|
+
}
|
|
204
|
+
: undefined,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (hasPlan) {
|
|
209
|
+
updateBody.provider = tenant.plan!.provider || "";
|
|
210
|
+
updateBody.plan = tenant.plan!.name;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const response = await makeGlobalWebSocketRequest(
|
|
214
|
+
"tenant:update_tenant",
|
|
215
|
+
updateBody,
|
|
216
|
+
30000,
|
|
217
|
+
"UPDATE",
|
|
218
|
+
tenant.name
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const updatedTenant = { ...tenant, status: "pending" };
|
|
222
|
+
eventHelper.tenant.publish.updated(updatedTenant);
|
|
223
|
+
const tenantCreatedNotification: Notification = {
|
|
224
|
+
type: "success",
|
|
225
|
+
subtype: "tenant-updated",
|
|
226
|
+
date: Date.now().toString(),
|
|
227
|
+
status: "unread",
|
|
228
|
+
callToAction: false,
|
|
229
|
+
data: {
|
|
230
|
+
tenant: tenant.name,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
eventHelper.notification.publish.creation(tenantCreatedNotification);
|
|
234
|
+
return response;
|
|
235
|
+
} catch (err) {
|
|
236
|
+
console.error("Error in tenant update WebSocket request:", err);
|
|
237
|
+
eventHelper.tenant.publish.updateError(tenant);
|
|
238
|
+
let contentMessage = "Unknown error";
|
|
239
|
+
let errorContent = "Unknown error";
|
|
240
|
+
|
|
241
|
+
if (
|
|
242
|
+
typeof err === "object" &&
|
|
243
|
+
err !== null &&
|
|
244
|
+
"error" in err &&
|
|
245
|
+
typeof (err as any).error === "object" &&
|
|
246
|
+
(err as any).error !== null
|
|
247
|
+
) {
|
|
248
|
+
if ("code" in (err as any).error) {
|
|
249
|
+
contentMessage = (err as any).error.code;
|
|
250
|
+
}
|
|
251
|
+
if ("content" in (err as any).error) {
|
|
252
|
+
errorContent = (err as any).error.content;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const tenantUpdateErrorNotification: Notification = {
|
|
256
|
+
type: "error",
|
|
257
|
+
subtype: "tenant-update-error",
|
|
258
|
+
info_content: {
|
|
259
|
+
code: contentMessage,
|
|
260
|
+
message: errorContent,
|
|
261
|
+
},
|
|
262
|
+
date: Date.now().toString(),
|
|
263
|
+
status: "unread",
|
|
264
|
+
callToAction: false,
|
|
265
|
+
data: {
|
|
266
|
+
tenant: tenant.name,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
eventHelper.notification.publish.creation(tenantUpdateErrorNotification);
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Function to create a tenant
|
|
276
|
+
* @param tenant Tenant object with the data of the tenant
|
|
277
|
+
* @returns The response of the API.
|
|
278
|
+
*/
|
|
279
|
+
export const createTenantHTTP = async (tenant: Tenant) => {
|
|
280
|
+
const createTenantUrl = new URL(
|
|
281
|
+
`${environment.apiServer.baseUrl}/api/${environment.apiServer.apiVersion}/tenant/${tenant.name}`
|
|
282
|
+
);
|
|
283
|
+
if (tenant.plan && tenant.plan?.name !== "" && tenant.plan?.provider !== "") {
|
|
284
|
+
createTenantUrl.searchParams.append("plan", tenant.plan?.name || "");
|
|
285
|
+
createTenantUrl.searchParams.append(
|
|
286
|
+
"provider",
|
|
287
|
+
tenant.plan?.provider || ""
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
const tenantBody =
|
|
291
|
+
tenant.npmRegistry && tenant.npmRegistry.endpoint !== ""
|
|
292
|
+
? {
|
|
293
|
+
tenant: tenant.name,
|
|
294
|
+
provider: tenant.plan?.provider || "",
|
|
295
|
+
plan: tenant.plan?.name || "",
|
|
296
|
+
spec: {
|
|
297
|
+
registry: {
|
|
298
|
+
kind: "git",
|
|
299
|
+
endpoint: tenant.npmRegistry.endpoint,
|
|
300
|
+
domain: tenant.npmRegistry.domain,
|
|
301
|
+
credentials: tenant.npmRegistry.credentials,
|
|
302
|
+
public: tenant.npmRegistry.public,
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
}
|
|
306
|
+
: {
|
|
307
|
+
tenant: tenant.name,
|
|
308
|
+
spec: {
|
|
309
|
+
registry: undefined,
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
const response = await fetch(createTenantUrl, {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: {
|
|
315
|
+
"Content-Type": "application/json",
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify(tenantBody),
|
|
318
|
+
});
|
|
319
|
+
if (response.ok) {
|
|
320
|
+
const updatedTenant = { ...tenant, status: "pending" };
|
|
321
|
+
eventHelper.tenant.publish.created(updatedTenant);
|
|
322
|
+
const tenantCreatedNotification: Notification = {
|
|
323
|
+
type: "success",
|
|
324
|
+
subtype: "tenant-created",
|
|
325
|
+
date: Date.now().toString(),
|
|
326
|
+
status: "unread",
|
|
327
|
+
callToAction: false,
|
|
328
|
+
data: {
|
|
329
|
+
tenant: tenant.name,
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
eventHelper.notification.publish.creation(tenantCreatedNotification);
|
|
333
|
+
} else {
|
|
334
|
+
eventHelper.tenant.publish.creationError(tenant);
|
|
335
|
+
|
|
336
|
+
let errorCode = "Unknown error";
|
|
337
|
+
let errorMessage = "Unknown error";
|
|
338
|
+
|
|
339
|
+
try {
|
|
340
|
+
const errorBody = await response.json();
|
|
341
|
+
if (errorBody?.code) {
|
|
342
|
+
errorCode = errorBody.code;
|
|
343
|
+
}
|
|
344
|
+
if (errorBody?.content) {
|
|
345
|
+
errorMessage = errorBody.content;
|
|
346
|
+
} else {
|
|
347
|
+
errorMessage = JSON.stringify(errorBody, null, 2);
|
|
348
|
+
}
|
|
349
|
+
} catch (e) {
|
|
350
|
+
const text = await response.text();
|
|
351
|
+
errorMessage = text || "Unknown error";
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const tenantCreationErrorNotification: Notification = {
|
|
355
|
+
type: "error",
|
|
356
|
+
subtype: "tenant-creation-error",
|
|
357
|
+
info_content: {
|
|
358
|
+
code: errorCode,
|
|
359
|
+
message: errorMessage,
|
|
360
|
+
},
|
|
361
|
+
date: Date.now().toString(),
|
|
362
|
+
status: "unread",
|
|
363
|
+
callToAction: false,
|
|
364
|
+
data: {
|
|
365
|
+
tenant: tenant.name,
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
eventHelper.notification.publish.creation(tenantCreationErrorNotification);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
export const deleteTenantHTTP = async (tenant: Tenant) => {
|
|
374
|
+
const url = new URL(
|
|
375
|
+
`${environment.apiServer.baseUrl}/api/${environment.apiServer.apiVersion}/tenant/${tenant.name}`
|
|
376
|
+
);
|
|
377
|
+
url.searchParams.append("force", "true");
|
|
378
|
+
|
|
379
|
+
const response = await fetch(url.toString(), {
|
|
380
|
+
method: "DELETE",
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
if (response.ok) {
|
|
384
|
+
const tenantDeletedNotification: Notification = {
|
|
385
|
+
type: "success",
|
|
386
|
+
subtype: "tenant-deleting",
|
|
387
|
+
date: Date.now().toString(),
|
|
388
|
+
status: "unread",
|
|
389
|
+
callToAction: false,
|
|
390
|
+
data: {
|
|
391
|
+
tenant: tenant.name,
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
eventHelper.notification.publish.creation(tenantDeletedNotification);
|
|
395
|
+
} else {
|
|
396
|
+
eventHelper.tenant.publish.deletionError(tenant);
|
|
397
|
+
|
|
398
|
+
let errorCode = "Unknown error";
|
|
399
|
+
let errorMessage = "Unknown error";
|
|
400
|
+
try {
|
|
401
|
+
const errorBody = await response.json();
|
|
402
|
+
if (errorBody?.code) {
|
|
403
|
+
errorCode = errorBody.code;
|
|
404
|
+
}
|
|
405
|
+
if (errorBody?.content) {
|
|
406
|
+
errorMessage = errorBody.content;
|
|
407
|
+
}
|
|
408
|
+
} catch (e) {
|
|
409
|
+
const text = await response.text();
|
|
410
|
+
errorMessage = text || "Unknown error";
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const tenantDeletionErrorNotification: Notification = {
|
|
414
|
+
type: "error",
|
|
415
|
+
subtype: "tenant-deletion-error",
|
|
416
|
+
info_content: {
|
|
417
|
+
code: errorCode,
|
|
418
|
+
message: errorMessage,
|
|
419
|
+
},
|
|
420
|
+
date: Date.now().toString(),
|
|
421
|
+
status: "unread",
|
|
422
|
+
callToAction: false,
|
|
423
|
+
data: {
|
|
424
|
+
tenant: tenant.name,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
eventHelper.notification.publish.creation(tenantDeletionErrorNotification);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
export const updateTenantHTTP = async (tenant: Tenant) => {
|
|
432
|
+
const updateTenantUrl = new URL(
|
|
433
|
+
`${environment.apiServer.baseUrl}/api/${environment.apiServer.apiVersion}/tenant/${tenant.name}`
|
|
434
|
+
);
|
|
435
|
+
if (tenant.plan && tenant.plan?.name !== "" && tenant.plan?.provider !== "") {
|
|
436
|
+
updateTenantUrl.searchParams.append("plan", tenant.plan?.name || "");
|
|
437
|
+
updateTenantUrl.searchParams.append(
|
|
438
|
+
"provider",
|
|
439
|
+
tenant.plan?.provider || ""
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
const tenantBody =
|
|
443
|
+
tenant.npmRegistry && tenant.npmRegistry.endpoint !== ""
|
|
444
|
+
? {
|
|
445
|
+
tenant: tenant.name,
|
|
446
|
+
provider: tenant.plan?.provider || "",
|
|
447
|
+
plan: tenant.plan?.name || "",
|
|
448
|
+
spec: {
|
|
449
|
+
registry: {
|
|
450
|
+
kind: "git",
|
|
451
|
+
endpoint: tenant.npmRegistry.endpoint,
|
|
452
|
+
domain: tenant.npmRegistry.domain,
|
|
453
|
+
credentials: tenant.npmRegistry.credentials,
|
|
454
|
+
public: tenant.npmRegistry.public,
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
}
|
|
458
|
+
: {
|
|
459
|
+
tenant: tenant.name,
|
|
460
|
+
spec: {
|
|
461
|
+
registry: undefined,
|
|
462
|
+
},
|
|
463
|
+
};
|
|
464
|
+
const response = await fetch(updateTenantUrl, {
|
|
465
|
+
method: "PATCH",
|
|
466
|
+
headers: {
|
|
467
|
+
"Content-Type": "application/json",
|
|
468
|
+
},
|
|
469
|
+
body: JSON.stringify(tenantBody),
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
if (response.ok) {
|
|
473
|
+
const updatedTenant = { ...tenant, status: "pending" };
|
|
474
|
+
eventHelper.tenant.publish.updated(updatedTenant);
|
|
475
|
+
const tenantCreatedNotification: Notification = {
|
|
476
|
+
type: "success",
|
|
477
|
+
subtype: "tenant-updated",
|
|
478
|
+
date: Date.now().toString(),
|
|
479
|
+
status: "unread",
|
|
480
|
+
callToAction: false,
|
|
481
|
+
data: {
|
|
482
|
+
tenant: tenant.name,
|
|
483
|
+
},
|
|
484
|
+
};
|
|
485
|
+
eventHelper.notification.publish.creation(tenantCreatedNotification);
|
|
486
|
+
} else {
|
|
487
|
+
eventHelper.tenant.publish.updateError(tenant);
|
|
488
|
+
|
|
489
|
+
let errorCode = "Unknown error";
|
|
490
|
+
let errorMessage = "Unknown error";
|
|
491
|
+
try {
|
|
492
|
+
const errorBody = await response.json();
|
|
493
|
+
if (errorBody?.code) {
|
|
494
|
+
errorCode = errorBody.code;
|
|
495
|
+
}
|
|
496
|
+
if (errorBody?.content) {
|
|
497
|
+
errorMessage = errorBody.content;
|
|
498
|
+
}
|
|
499
|
+
} catch (e) {
|
|
500
|
+
const text = await response.text();
|
|
501
|
+
errorMessage = text || "Unknown error";
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const tenantUpdateErrorNotification: Notification = {
|
|
505
|
+
type: "error",
|
|
506
|
+
subtype: "tenant-update-error",
|
|
507
|
+
info_content: {
|
|
508
|
+
code: errorCode,
|
|
509
|
+
message: errorMessage,
|
|
510
|
+
},
|
|
511
|
+
date: Date.now().toString(),
|
|
512
|
+
status: "unread",
|
|
513
|
+
callToAction: false,
|
|
514
|
+
data: {
|
|
515
|
+
tenant: tenant.name,
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
eventHelper.notification.publish.creation(tenantUpdateErrorNotification);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
export const createRegistry = async (
|
|
523
|
+
tenant: Tenant,
|
|
524
|
+
security: Security,
|
|
525
|
+
registry: Registry
|
|
526
|
+
) => {
|
|
527
|
+
try {
|
|
528
|
+
await initializeGlobalWebSocketClient(security);
|
|
529
|
+
const dregistryBody: DregistryBody = {
|
|
530
|
+
spec: {
|
|
531
|
+
labels: { logo: registry.extra },
|
|
532
|
+
docker_server: registry.domain,
|
|
533
|
+
docker_username: registry.credentials,
|
|
534
|
+
docker_password: registry.password || "",
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
const queryParams = {
|
|
538
|
+
tenant: tenant.name,
|
|
539
|
+
dregistry: registry.name,
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
const response = await makeGlobalWebSocketRequest(
|
|
543
|
+
"dregistry:create_dregistry",
|
|
544
|
+
{
|
|
545
|
+
...dregistryBody,
|
|
546
|
+
...queryParams,
|
|
547
|
+
},
|
|
548
|
+
30000,
|
|
549
|
+
"CREATE",
|
|
550
|
+
`${tenant.name}/${registry.domain}`
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
const dregistryCreatedNotification: Notification = {
|
|
554
|
+
type: "success",
|
|
555
|
+
subtype: "registry-created",
|
|
556
|
+
date: Date.now().toString(),
|
|
557
|
+
status: "unread",
|
|
558
|
+
callToAction: false,
|
|
559
|
+
data: {
|
|
560
|
+
tenant: tenant.name,
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
eventHelper.notification.publish.creation(dregistryCreatedNotification);
|
|
564
|
+
return response;
|
|
565
|
+
} catch (error) {
|
|
566
|
+
console.error("Error creating dregistry:", {
|
|
567
|
+
error,
|
|
568
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
569
|
+
tenant: tenant.name,
|
|
570
|
+
registry: registry.domain,
|
|
571
|
+
webSocketStatus: getWebSocketStatus(),
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
let contentMessage = "Unknown error";
|
|
575
|
+
let errorContent = "Unknown error";
|
|
576
|
+
|
|
577
|
+
if (
|
|
578
|
+
typeof error === "object" &&
|
|
579
|
+
error !== null &&
|
|
580
|
+
"error" in error &&
|
|
581
|
+
typeof (error as any).error === "object" &&
|
|
582
|
+
(error as any).error !== null
|
|
583
|
+
) {
|
|
584
|
+
if ("code" in (error as any).error) {
|
|
585
|
+
contentMessage = (error as any).error.code;
|
|
586
|
+
}
|
|
587
|
+
if ("content" in (error as any).error) {
|
|
588
|
+
errorContent = (error as any).error.content;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const dregistryCreationErrorNotification: Notification = {
|
|
593
|
+
type: "error",
|
|
594
|
+
subtype: "registry-creation-error",
|
|
595
|
+
info_content: {
|
|
596
|
+
code: contentMessage,
|
|
597
|
+
message: errorContent,
|
|
598
|
+
},
|
|
599
|
+
date: Date.now().toString(),
|
|
600
|
+
status: "unread",
|
|
601
|
+
callToAction: false,
|
|
602
|
+
data: {
|
|
603
|
+
tenant: tenant.name,
|
|
604
|
+
},
|
|
605
|
+
};
|
|
606
|
+
eventHelper.notification.publish.creation(
|
|
607
|
+
dregistryCreationErrorNotification
|
|
608
|
+
);
|
|
609
|
+
throw error;
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Function to update a dregistry using the global WebSocket connection
|
|
615
|
+
* @param tenant Tenant object with registry information
|
|
616
|
+
* @param security Authorization token
|
|
617
|
+
* @param force Force update flag (default: false)
|
|
618
|
+
* @returns The response of the WebSocket API
|
|
619
|
+
*/
|
|
620
|
+
export const updateRegistry = async (
|
|
621
|
+
tenant: Tenant,
|
|
622
|
+
registry: Registry,
|
|
623
|
+
security: Security,
|
|
624
|
+
force: boolean = false
|
|
625
|
+
) => {
|
|
626
|
+
try {
|
|
627
|
+
await initializeGlobalWebSocketClient(security);
|
|
628
|
+
const dregistryBody: DregistryBody = {
|
|
629
|
+
spec: {
|
|
630
|
+
labels: { logo: registry.extra },
|
|
631
|
+
docker_server: registry.domain,
|
|
632
|
+
docker_username: registry.credentials,
|
|
633
|
+
docker_password: registry.password || "",
|
|
634
|
+
},
|
|
635
|
+
};
|
|
636
|
+
const queryParams = {
|
|
637
|
+
tenant: tenant.name,
|
|
638
|
+
dregistry: registry.name,
|
|
639
|
+
force: force,
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
const response = await makeGlobalWebSocketRequest(
|
|
643
|
+
"dregistry:update_dregistry",
|
|
644
|
+
{
|
|
645
|
+
...dregistryBody,
|
|
646
|
+
...queryParams,
|
|
647
|
+
},
|
|
648
|
+
30000,
|
|
649
|
+
"UPDATE",
|
|
650
|
+
`${tenant.name}/${registry.domain}`
|
|
651
|
+
);
|
|
652
|
+
const dregistryUpdatedNotification: Notification = {
|
|
653
|
+
type: "success",
|
|
654
|
+
subtype: "registry-updated",
|
|
655
|
+
date: Date.now().toString(),
|
|
656
|
+
status: "unread",
|
|
657
|
+
callToAction: false,
|
|
658
|
+
data: {
|
|
659
|
+
tenant: tenant.name,
|
|
660
|
+
},
|
|
661
|
+
};
|
|
662
|
+
eventHelper.notification.publish.creation(dregistryUpdatedNotification);
|
|
663
|
+
|
|
664
|
+
return response;
|
|
665
|
+
} catch (error) {
|
|
666
|
+
console.error("Error updating dregistry:", {
|
|
667
|
+
error,
|
|
668
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
669
|
+
tenant: tenant.name,
|
|
670
|
+
registry: registry.domain,
|
|
671
|
+
force,
|
|
672
|
+
webSocketStatus: getWebSocketStatus(),
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
let contentMessage = "Unknown error";
|
|
676
|
+
let errorContent = "Unknown error";
|
|
677
|
+
|
|
678
|
+
if (
|
|
679
|
+
typeof error === "object" &&
|
|
680
|
+
error !== null &&
|
|
681
|
+
"error" in error &&
|
|
682
|
+
typeof (error as any).error === "object" &&
|
|
683
|
+
(error as any).error !== null
|
|
684
|
+
) {
|
|
685
|
+
if ("code" in (error as any).error) {
|
|
686
|
+
contentMessage = (error as any).error.code;
|
|
687
|
+
}
|
|
688
|
+
if ("content" in (error as any).error) {
|
|
689
|
+
errorContent = (error as any).error.content;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
const dregistryUpdateErrorNotification: Notification = {
|
|
694
|
+
type: "error",
|
|
695
|
+
subtype: "registry-update-error",
|
|
696
|
+
info_content: {
|
|
697
|
+
code: contentMessage,
|
|
698
|
+
message: errorContent,
|
|
699
|
+
},
|
|
700
|
+
date: Date.now().toString(),
|
|
701
|
+
status: "unread",
|
|
702
|
+
callToAction: false,
|
|
703
|
+
data: {
|
|
704
|
+
tenant: tenant.name,
|
|
705
|
+
},
|
|
706
|
+
};
|
|
707
|
+
eventHelper.notification.publish.creation(dregistryUpdateErrorNotification);
|
|
708
|
+
throw error;
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
export const deleteRegistry = async (
|
|
713
|
+
tenant: Tenant,
|
|
714
|
+
registry: Registry,
|
|
715
|
+
security: Security,
|
|
716
|
+
force: boolean = false
|
|
717
|
+
) => {
|
|
718
|
+
try {
|
|
719
|
+
await initializeGlobalWebSocketClient(security);
|
|
720
|
+
|
|
721
|
+
const queryParams = {
|
|
722
|
+
tenant: tenant.name,
|
|
723
|
+
dregistry: registry.name,
|
|
724
|
+
force: force,
|
|
725
|
+
};
|
|
726
|
+
|
|
727
|
+
const response = await makeGlobalWebSocketRequest(
|
|
728
|
+
"dregistry:delete_dregistry",
|
|
729
|
+
queryParams,
|
|
730
|
+
30000,
|
|
731
|
+
"DELETE",
|
|
732
|
+
`${tenant.name}/${registry.domain}`
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
const dregistryDeletedNotification: Notification = {
|
|
736
|
+
type: "success",
|
|
737
|
+
subtype: "registry-deleted",
|
|
738
|
+
date: Date.now().toString(),
|
|
739
|
+
status: "unread",
|
|
740
|
+
callToAction: false,
|
|
741
|
+
data: {
|
|
742
|
+
tenant: tenant.name,
|
|
743
|
+
},
|
|
744
|
+
};
|
|
745
|
+
eventHelper.notification.publish.creation(dregistryDeletedNotification);
|
|
746
|
+
return response;
|
|
747
|
+
} catch (error) {
|
|
748
|
+
console.error("Error deleting dregistry:", {
|
|
749
|
+
error,
|
|
750
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
751
|
+
tenant: tenant.name,
|
|
752
|
+
registry: registry.domain,
|
|
753
|
+
force,
|
|
754
|
+
webSocketStatus: getWebSocketStatus(),
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
let contentMessage = "Unknown error";
|
|
758
|
+
let errorContent = "Unknown error";
|
|
759
|
+
|
|
760
|
+
if (
|
|
761
|
+
typeof error === "object" &&
|
|
762
|
+
error !== null &&
|
|
763
|
+
"error" in error &&
|
|
764
|
+
typeof (error as any).error === "object" &&
|
|
765
|
+
(error as any).error !== null
|
|
766
|
+
) {
|
|
767
|
+
if ("code" in (error as any).error) {
|
|
768
|
+
contentMessage = (error as any).error.code;
|
|
769
|
+
}
|
|
770
|
+
if ("content" in (error as any).error) {
|
|
771
|
+
errorContent = (error as any).error.content;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const dregistryDeletionErrorNotification: Notification = {
|
|
776
|
+
type: "error",
|
|
777
|
+
subtype: "registry-deletion-error",
|
|
778
|
+
info_content: {
|
|
779
|
+
code: contentMessage,
|
|
780
|
+
message: errorContent,
|
|
781
|
+
},
|
|
782
|
+
date: Date.now().toString(),
|
|
783
|
+
status: "unread",
|
|
784
|
+
callToAction: false,
|
|
785
|
+
data: {
|
|
786
|
+
tenant: tenant.name,
|
|
787
|
+
},
|
|
788
|
+
};
|
|
789
|
+
eventHelper.notification.publish.creation(
|
|
790
|
+
dregistryDeletionErrorNotification
|
|
791
|
+
);
|
|
792
|
+
throw error;
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
export const inviteUser = async (
|
|
797
|
+
tenant: string,
|
|
798
|
+
email: string,
|
|
799
|
+
role: tenantRole,
|
|
800
|
+
security: string
|
|
801
|
+
) => {
|
|
802
|
+
try {
|
|
803
|
+
await initializeGlobalWebSocketClient(security);
|
|
804
|
+
|
|
805
|
+
const queryParams = {
|
|
806
|
+
tenant: tenant,
|
|
807
|
+
user: email,
|
|
808
|
+
role: role,
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
const response = await makeGlobalWebSocketRequest(
|
|
812
|
+
"tenant:propose_user",
|
|
813
|
+
queryParams,
|
|
814
|
+
30000,
|
|
815
|
+
"CREATE",
|
|
816
|
+
`${tenant}/${email}`
|
|
817
|
+
);
|
|
818
|
+
const tenantInvitedNotification: Notification = {
|
|
819
|
+
type: "success",
|
|
820
|
+
subtype: "tenant-user-invited",
|
|
821
|
+
date: Date.now().toString(),
|
|
822
|
+
status: "unread",
|
|
823
|
+
callToAction: false,
|
|
824
|
+
data: {
|
|
825
|
+
tenant: tenant,
|
|
826
|
+
email: email,
|
|
827
|
+
role,
|
|
828
|
+
tenantRole,
|
|
829
|
+
},
|
|
830
|
+
};
|
|
831
|
+
eventHelper.notification.publish.creation(tenantInvitedNotification);
|
|
832
|
+
return response;
|
|
833
|
+
} catch (error) {
|
|
834
|
+
console.error("Error inviting user:", {
|
|
835
|
+
error,
|
|
836
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
837
|
+
tenant: tenant,
|
|
838
|
+
email: email,
|
|
839
|
+
role: role,
|
|
840
|
+
webSocketStatus: getWebSocketStatus(),
|
|
841
|
+
});
|
|
842
|
+
let contentMessage = "Unknown error";
|
|
843
|
+
let errorContent = "Unknown error";
|
|
844
|
+
|
|
845
|
+
if (
|
|
846
|
+
typeof error === "object" &&
|
|
847
|
+
error !== null &&
|
|
848
|
+
"error" in error &&
|
|
849
|
+
typeof (error as any).error === "object" &&
|
|
850
|
+
(error as any).error !== null
|
|
851
|
+
) {
|
|
852
|
+
if ("code" in (error as any).error) {
|
|
853
|
+
contentMessage = (error as any).error.code;
|
|
854
|
+
}
|
|
855
|
+
if ("content" in (error as any).error) {
|
|
856
|
+
errorContent = (error as any).error.content;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
const tenantInviteErrorNotification: Notification = {
|
|
860
|
+
type: "error",
|
|
861
|
+
subtype: "tenant-user-invite-error",
|
|
862
|
+
info_content: {
|
|
863
|
+
code: contentMessage,
|
|
864
|
+
message: errorContent,
|
|
865
|
+
},
|
|
866
|
+
date: Date.now().toString(),
|
|
867
|
+
status: "unread",
|
|
868
|
+
callToAction: false,
|
|
869
|
+
data: {
|
|
870
|
+
tenant: tenant,
|
|
871
|
+
email: email,
|
|
872
|
+
role,
|
|
873
|
+
tenantRole,
|
|
874
|
+
},
|
|
875
|
+
};
|
|
876
|
+
eventHelper.notification.publish.creation(tenantInviteErrorNotification);
|
|
877
|
+
throw error;
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
export const removeUser = async (
|
|
882
|
+
tenant: string,
|
|
883
|
+
userId: string,
|
|
884
|
+
security: string
|
|
885
|
+
) => {
|
|
886
|
+
try {
|
|
887
|
+
await initializeGlobalWebSocketClient(security);
|
|
888
|
+
const queryParams = {
|
|
889
|
+
tenant: tenant,
|
|
890
|
+
user: userId,
|
|
891
|
+
};
|
|
892
|
+
const response = await makeGlobalWebSocketRequest(
|
|
893
|
+
"tenant:exclude_user",
|
|
894
|
+
queryParams,
|
|
895
|
+
30000,
|
|
896
|
+
"DELETE",
|
|
897
|
+
`${tenant}/${userId}`
|
|
898
|
+
);
|
|
899
|
+
const tenantUserRemovedNotification: Notification = {
|
|
900
|
+
type: "success",
|
|
901
|
+
subtype: "tenant-user-removed",
|
|
902
|
+
date: Date.now().toString(),
|
|
903
|
+
status: "unread",
|
|
904
|
+
callToAction: false,
|
|
905
|
+
data: {
|
|
906
|
+
tenant: tenant,
|
|
907
|
+
user: userId,
|
|
908
|
+
},
|
|
909
|
+
};
|
|
910
|
+
eventHelper.notification.publish.creation(tenantUserRemovedNotification);
|
|
911
|
+
return response;
|
|
912
|
+
} catch (error) {
|
|
913
|
+
console.error("Error removing user from tenant:", {
|
|
914
|
+
error,
|
|
915
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
916
|
+
tenant: tenant,
|
|
917
|
+
userId: userId,
|
|
918
|
+
webSocketStatus: getWebSocketStatus(),
|
|
919
|
+
});
|
|
920
|
+
let contentMessage = "Unknown error";
|
|
921
|
+
let errorContent = "Unknown error";
|
|
922
|
+
|
|
923
|
+
if (
|
|
924
|
+
typeof error === "object" &&
|
|
925
|
+
error !== null &&
|
|
926
|
+
"error" in error &&
|
|
927
|
+
typeof (error as any).error === "object" &&
|
|
928
|
+
(error as any).error !== null
|
|
929
|
+
) {
|
|
930
|
+
if ("code" in (error as any).error) {
|
|
931
|
+
contentMessage = (error as any).error.code;
|
|
932
|
+
}
|
|
933
|
+
if ("content" in (error as any).error) {
|
|
934
|
+
errorContent = (error as any).error.content;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
const tenantUserRemovedErrorNotification: Notification = {
|
|
938
|
+
type: "error",
|
|
939
|
+
subtype: "tenant-user-removed-error",
|
|
940
|
+
info_content: {
|
|
941
|
+
code: contentMessage,
|
|
942
|
+
message: errorContent,
|
|
943
|
+
},
|
|
944
|
+
date: Date.now().toString(),
|
|
945
|
+
status: "unread",
|
|
946
|
+
callToAction: false,
|
|
947
|
+
data: {
|
|
948
|
+
tenant: tenant,
|
|
949
|
+
user: userId,
|
|
950
|
+
},
|
|
951
|
+
};
|
|
952
|
+
eventHelper.notification.publish.creation(
|
|
953
|
+
tenantUserRemovedErrorNotification
|
|
954
|
+
);
|
|
955
|
+
throw error;
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
export const updateUserRole = async (
|
|
960
|
+
tenant: string,
|
|
961
|
+
userId: string,
|
|
962
|
+
role: tenantRole,
|
|
963
|
+
security: string
|
|
964
|
+
) => {
|
|
965
|
+
try {
|
|
966
|
+
await initializeGlobalWebSocketClient(security);
|
|
967
|
+
const queryParams = {
|
|
968
|
+
tenant: tenant,
|
|
969
|
+
user: userId,
|
|
970
|
+
role: role,
|
|
971
|
+
};
|
|
972
|
+
const response = await makeGlobalWebSocketRequest(
|
|
973
|
+
"tenant:modify_user_role",
|
|
974
|
+
queryParams,
|
|
975
|
+
30000,
|
|
976
|
+
"PATCH",
|
|
977
|
+
`${tenant}/${userId}`
|
|
978
|
+
);
|
|
979
|
+
const tenantUserUpdatedNotification: Notification = {
|
|
980
|
+
type: "success",
|
|
981
|
+
subtype: "user-role-updated",
|
|
982
|
+
date: Date.now().toString(),
|
|
983
|
+
status: "unread",
|
|
984
|
+
callToAction: false,
|
|
985
|
+
data: {
|
|
986
|
+
tenant: tenant,
|
|
987
|
+
user: userId,
|
|
988
|
+
role: role,
|
|
989
|
+
},
|
|
990
|
+
};
|
|
991
|
+
eventHelper.notification.publish.creation(tenantUserUpdatedNotification);
|
|
992
|
+
return response;
|
|
993
|
+
} catch (error) {
|
|
994
|
+
console.error("Error updating user in tenant:", {
|
|
995
|
+
error,
|
|
996
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
997
|
+
tenant: tenant,
|
|
998
|
+
userId: userId,
|
|
999
|
+
role: role,
|
|
1000
|
+
webSocketStatus: getWebSocketStatus(),
|
|
1001
|
+
});
|
|
1002
|
+
let contentMessage = "Unknown error";
|
|
1003
|
+
let errorContent = "Unknown error";
|
|
1004
|
+
|
|
1005
|
+
if (
|
|
1006
|
+
typeof error === "object" &&
|
|
1007
|
+
error !== null &&
|
|
1008
|
+
"error" in error &&
|
|
1009
|
+
typeof (error as any).error === "object" &&
|
|
1010
|
+
(error as any).error !== null
|
|
1011
|
+
) {
|
|
1012
|
+
if ("code" in (error as any).error) {
|
|
1013
|
+
contentMessage = (error as any).error.code;
|
|
1014
|
+
}
|
|
1015
|
+
if ("content" in (error as any).error) {
|
|
1016
|
+
errorContent = (error as any).error.content;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
const tenantUserUpdatedErrorNotification: Notification = {
|
|
1020
|
+
type: "error",
|
|
1021
|
+
subtype: "user-role-updated-error",
|
|
1022
|
+
info_content: {
|
|
1023
|
+
code: contentMessage,
|
|
1024
|
+
message: errorContent,
|
|
1025
|
+
},
|
|
1026
|
+
date: Date.now().toString(),
|
|
1027
|
+
status: "unread",
|
|
1028
|
+
callToAction: false,
|
|
1029
|
+
data: {
|
|
1030
|
+
tenant: tenant,
|
|
1031
|
+
user: userId,
|
|
1032
|
+
role: role,
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
1035
|
+
eventHelper.notification.publish.creation(
|
|
1036
|
+
tenantUserUpdatedErrorNotification
|
|
1037
|
+
);
|
|
1038
|
+
throw error;
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
export const acceptInvite = async (tenant: string, security: string) => {
|
|
1043
|
+
try {
|
|
1044
|
+
await initializeGlobalWebSocketClient(security);
|
|
1045
|
+
const queryParams = { tenant: tenant };
|
|
1046
|
+
const response = await makeGlobalWebSocketRequest(
|
|
1047
|
+
"tenant:accept_proposal_user",
|
|
1048
|
+
queryParams,
|
|
1049
|
+
30000,
|
|
1050
|
+
"PUT",
|
|
1051
|
+
`${tenant}/accept`
|
|
1052
|
+
);
|
|
1053
|
+
const tenantInviteAcceptedNotification: Notification = {
|
|
1054
|
+
type: "success",
|
|
1055
|
+
subtype: "tenant-invite-accepted",
|
|
1056
|
+
date: Date.now().toString(),
|
|
1057
|
+
status: "unread",
|
|
1058
|
+
callToAction: false,
|
|
1059
|
+
data: {
|
|
1060
|
+
tenant: tenant,
|
|
1061
|
+
},
|
|
1062
|
+
};
|
|
1063
|
+
eventHelper.notification.publish.creation(tenantInviteAcceptedNotification);
|
|
1064
|
+
return response;
|
|
1065
|
+
} catch (error) {
|
|
1066
|
+
console.error("Error accepting tenant invite:", {
|
|
1067
|
+
error,
|
|
1068
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
1069
|
+
tenant: tenant,
|
|
1070
|
+
webSocketStatus: getWebSocketStatus(),
|
|
1071
|
+
});
|
|
1072
|
+
let contentMessage = "Unknown error";
|
|
1073
|
+
let errorContent = "Unknown error";
|
|
1074
|
+
|
|
1075
|
+
if (
|
|
1076
|
+
typeof error === "object" &&
|
|
1077
|
+
error !== null &&
|
|
1078
|
+
"error" in error &&
|
|
1079
|
+
typeof (error as any).error === "object" &&
|
|
1080
|
+
(error as any).error !== null
|
|
1081
|
+
) {
|
|
1082
|
+
if ("code" in (error as any).error) {
|
|
1083
|
+
contentMessage = (error as any).error.code;
|
|
1084
|
+
}
|
|
1085
|
+
if ("content" in (error as any).error) {
|
|
1086
|
+
errorContent = (error as any).error.content;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
const tenantInviteAcceptedErrorNotification: Notification = {
|
|
1090
|
+
type: "error",
|
|
1091
|
+
subtype: "tenant-invite-accepted-error",
|
|
1092
|
+
info_content: {
|
|
1093
|
+
code: contentMessage,
|
|
1094
|
+
message: errorContent,
|
|
1095
|
+
},
|
|
1096
|
+
date: Date.now().toString(),
|
|
1097
|
+
status: "unread",
|
|
1098
|
+
callToAction: false,
|
|
1099
|
+
data: {
|
|
1100
|
+
tenant: tenant,
|
|
1101
|
+
},
|
|
1102
|
+
};
|
|
1103
|
+
eventHelper.notification.publish.creation(
|
|
1104
|
+
tenantInviteAcceptedErrorNotification
|
|
1105
|
+
);
|
|
1106
|
+
throw error;
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
export const rejectInvite = async (tenant: string, security: string) => {
|
|
1111
|
+
try {
|
|
1112
|
+
await initializeGlobalWebSocketClient(security);
|
|
1113
|
+
const queryParams = { tenant: tenant };
|
|
1114
|
+
const response = await makeGlobalWebSocketRequest(
|
|
1115
|
+
"tenant:reject_proposal_user",
|
|
1116
|
+
queryParams,
|
|
1117
|
+
30000,
|
|
1118
|
+
"DELETE",
|
|
1119
|
+
`${tenant}/reject`
|
|
1120
|
+
);
|
|
1121
|
+
const tenantInviteRejectedNotification: Notification = {
|
|
1122
|
+
type: "success",
|
|
1123
|
+
subtype: "tenant-invite-rejected",
|
|
1124
|
+
date: Date.now().toString(),
|
|
1125
|
+
status: "unread",
|
|
1126
|
+
callToAction: false,
|
|
1127
|
+
data: {
|
|
1128
|
+
tenant: tenant,
|
|
1129
|
+
},
|
|
1130
|
+
};
|
|
1131
|
+
eventHelper.notification.publish.creation(tenantInviteRejectedNotification);
|
|
1132
|
+
return response;
|
|
1133
|
+
} catch (error) {
|
|
1134
|
+
console.error("Error rejecting tenant invite:", {
|
|
1135
|
+
error,
|
|
1136
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
1137
|
+
tenant: tenant,
|
|
1138
|
+
webSocketStatus: getWebSocketStatus(),
|
|
1139
|
+
});
|
|
1140
|
+
let contentMessage = "Unknown error";
|
|
1141
|
+
let errorContent = "Unknown error";
|
|
1142
|
+
|
|
1143
|
+
if (
|
|
1144
|
+
typeof error === "object" &&
|
|
1145
|
+
error !== null &&
|
|
1146
|
+
"error" in error &&
|
|
1147
|
+
typeof (error as any).error === "object" &&
|
|
1148
|
+
(error as any).error !== null
|
|
1149
|
+
) {
|
|
1150
|
+
if ("code" in (error as any).error) {
|
|
1151
|
+
contentMessage = (error as any).error.code;
|
|
1152
|
+
}
|
|
1153
|
+
if ("content" in (error as any).error) {
|
|
1154
|
+
errorContent = (error as any).error.content;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
const tenantInviteRejectedErrorNotification: Notification = {
|
|
1158
|
+
type: "error",
|
|
1159
|
+
subtype: "tenant-invite-rejected-error",
|
|
1160
|
+
info_content: {
|
|
1161
|
+
code: contentMessage,
|
|
1162
|
+
message: errorContent,
|
|
1163
|
+
},
|
|
1164
|
+
date: Date.now().toString(),
|
|
1165
|
+
status: "unread",
|
|
1166
|
+
callToAction: false,
|
|
1167
|
+
data: {
|
|
1168
|
+
tenant: tenant,
|
|
1169
|
+
},
|
|
1170
|
+
};
|
|
1171
|
+
eventHelper.notification.publish.creation(
|
|
1172
|
+
tenantInviteRejectedErrorNotification
|
|
1173
|
+
);
|
|
1174
|
+
throw error;
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
export const createToken = async (
|
|
1178
|
+
tenantName: string,
|
|
1179
|
+
tokenDescription: string,
|
|
1180
|
+
tokenExpiration: string,
|
|
1181
|
+
security: string
|
|
1182
|
+
) => {
|
|
1183
|
+
try {
|
|
1184
|
+
await initializeGlobalWebSocketClient(security);
|
|
1185
|
+
const createTokenBody = {
|
|
1186
|
+
spec: {
|
|
1187
|
+
scopes: {
|
|
1188
|
+
tenant: { [tenantName]: { allow: ["*:*:*"] } },
|
|
1189
|
+
planprovider: { "*": { allow: ["*:*:*"] } },
|
|
1190
|
+
user: { "*": { allow: ["*:*:*"] } },
|
|
1191
|
+
idprovider: { "*": { allow: ["*:*:*"] } },
|
|
1192
|
+
},
|
|
1193
|
+
expiration: tokenExpiration,
|
|
1194
|
+
description: tokenDescription,
|
|
1195
|
+
labels: {
|
|
1196
|
+
tenant: tenantName,
|
|
1197
|
+
},
|
|
1198
|
+
},
|
|
1199
|
+
};
|
|
1200
|
+
const response = await makeGlobalWebSocketRequest(
|
|
1201
|
+
"token:create_token",
|
|
1202
|
+
createTokenBody,
|
|
1203
|
+
30000,
|
|
1204
|
+
"CREATE",
|
|
1205
|
+
`${tenantName}/tokens`,
|
|
1206
|
+
"token"
|
|
1207
|
+
);
|
|
1208
|
+
|
|
1209
|
+
const tenantTokenCreatedNotification: Notification = {
|
|
1210
|
+
type: "success",
|
|
1211
|
+
subtype: "token-created",
|
|
1212
|
+
date: Date.now().toString(),
|
|
1213
|
+
status: "unread",
|
|
1214
|
+
callToAction: false,
|
|
1215
|
+
data: {
|
|
1216
|
+
tenant: tenantName,
|
|
1217
|
+
tokenName: tokenDescription,
|
|
1218
|
+
},
|
|
1219
|
+
};
|
|
1220
|
+
eventHelper.notification.publish.creation(tenantTokenCreatedNotification);
|
|
1221
|
+
|
|
1222
|
+
return response;
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
console.error("Error creating tenant token:", {
|
|
1225
|
+
error,
|
|
1226
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
1227
|
+
tenant: tenantName,
|
|
1228
|
+
webSocketStatus: getWebSocketStatus(),
|
|
1229
|
+
});
|
|
1230
|
+
throw error;
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
export const deleteToken = async (
|
|
1234
|
+
tenantName: string,
|
|
1235
|
+
tokenID: string,
|
|
1236
|
+
security: string
|
|
1237
|
+
) => {
|
|
1238
|
+
try {
|
|
1239
|
+
await initializeGlobalWebSocketClient(security);
|
|
1240
|
+
const queryParams = {
|
|
1241
|
+
token_jti: tokenID,
|
|
1242
|
+
};
|
|
1243
|
+
const response = await makeGlobalWebSocketRequest(
|
|
1244
|
+
"token:revoke_token",
|
|
1245
|
+
queryParams,
|
|
1246
|
+
30000,
|
|
1247
|
+
"DELETE",
|
|
1248
|
+
`${tenantName}/tokens/${tokenID}`
|
|
1249
|
+
);
|
|
1250
|
+
return response;
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
console.error("Error deleting tenant token:", {
|
|
1253
|
+
error,
|
|
1254
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error",
|
|
1255
|
+
tenant: tenantName,
|
|
1256
|
+
webSocketStatus: getWebSocketStatus(),
|
|
1257
|
+
});
|
|
1258
|
+
throw error;
|
|
1259
|
+
}
|
|
1260
|
+
};
|