@xenon-device-management/xenon 2.12.0 → 2.13.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/lib/package.json +2 -2
- package/lib/public/assets/{AnnotationOverlay-Crkn72_3.js → AnnotationOverlay-CzbFYtPI.js} +1 -1
- package/lib/public/assets/{ApiKeyGate-BThVlj_j.js → ApiKeyGate-CA5KFHHJ.js} +1 -1
- package/lib/public/assets/{BugReportButton-Dwa0GnBh.js → BugReportButton-D-DSGg8C.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-Ccc-pOls.js → DeviceMosaicView-paDEFU4B.js} +1 -1
- package/lib/public/assets/{EmptyState-BeuTrlN_.js → EmptyState-BE_5f8Vw.js} +1 -1
- package/lib/public/assets/{FieldGroup-DBIaNxl1.js → FieldGroup-DqMf7Rf3.js} +1 -1
- package/lib/public/assets/{FilterMenu-BgSAS6iT.js → FilterMenu-BQY75Su3.js} +1 -1
- package/lib/public/assets/{Menu-GCbP6gYN.js → Menu-BiW3os9u.js} +1 -1
- package/lib/public/assets/{Modal-ByESeBRC.js → Modal-DfawTxih.js} +1 -1
- package/lib/public/assets/{RecordingPage-Bwyf3WMl.js → RecordingPage-BvemyRiy.js} +1 -1
- package/lib/public/assets/{RecordingsPage-7kM1rB3i.js → RecordingsPage-CXfw7wpd.js} +1 -1
- package/lib/public/assets/{SegmentedControl-B8tTU8kD.js → SegmentedControl-B7m9kpom.js} +1 -1
- package/lib/public/assets/{SettingCard-Clg_Ijbc.js → SettingCard-Cw6lDD0l.js} +1 -1
- package/lib/public/assets/{Table-CIaR0QWV.js → Table-DlEuFgv-.js} +1 -1
- package/lib/public/assets/{activity-Bengh9SD.js → activity-CnLvNwae.js} +1 -1
- package/lib/public/assets/{ai-settings-G9SymiPH.js → ai-settings-D7Te8o-a.js} +1 -1
- package/lib/public/assets/{api-keys-CrGlbfn-.js → api-keys-DphSVzBr.js} +1 -1
- package/lib/public/assets/{apps-DIbcGVlU.js → apps-vUfu15lX.js} +1 -1
- package/lib/public/assets/{arrow-left-BtJIXXMY.js → arrow-left-CLQWAiCY.js} +1 -1
- package/lib/public/assets/{arrow-right-zm-NagQh.js → arrow-right-K6A5e_Ee.js} +1 -1
- package/lib/public/assets/{arrow-up-right-DdU8YEYp.js → arrow-up-right-DUA_lq6f.js} +1 -1
- package/lib/public/assets/{auth-shell-CHmBFmOz.js → auth-shell-BYRHcZd6.js} +2 -2
- package/lib/public/assets/{builds-page-JkzWKRpU.js → builds-page-C0fTvIG8.js} +1 -1
- package/lib/public/assets/{button-CqhPBGRj.js → button-BxnHCCsX.js} +1 -1
- package/lib/public/assets/{calendar-C7eYYJTo.js → calendar-CqVsn28A.js} +1 -1
- package/lib/public/assets/{check-DpbIM4E0.js → check-R6V3bot0.js} +1 -1
- package/lib/public/assets/{chevron-right-Dl4X1PRz.js → chevron-right-BA2Fntu-.js} +1 -1
- package/lib/public/assets/{circle-check-Du3sjbfV.js → circle-check-D4EzyGzs.js} +1 -1
- package/lib/public/assets/{circle-x-BSSqhpXi.js → circle-x-Cf6AF2B2.js} +1 -1
- package/lib/public/assets/{clock-DMT60v1C.js → clock-EZfet0sS.js} +1 -1
- package/lib/public/assets/{copy-BKNyOehd.js → copy-Bc6P8v9V.js} +1 -1
- package/lib/public/assets/{device-explorer-CoPR8DW3.js → device-explorer-BFXpRq6d.js} +1 -1
- package/lib/public/assets/{download-BM6Xn22t.js → download-Bd8OGLzi.js} +1 -1
- package/lib/public/assets/{forgot-password-B8WqMqBT.js → forgot-password-CoE7Ugtx.js} +1 -1
- package/lib/public/assets/{index-DauQh6ie.js → index-BiL0Enl_.js} +1 -1
- package/lib/public/assets/{index-ClrpAMAT.js → index-CHOr4JCs.js} +2 -2
- package/lib/public/assets/{input-CyKdLnEx.js → input-CJ8z3IO5.js} +1 -1
- package/lib/public/assets/{line-chart-EIBXwYGo.js → line-chart-CPK0ObjV.js} +1 -1
- package/lib/public/assets/{list-checks-fWsgD9bI.js → list-checks-mXGHUVbB.js} +1 -1
- package/lib/public/assets/{lock-CVCe56TH.js → lock-BSXM1xvq.js} +1 -1
- package/lib/public/assets/{login-BJ8a7yVD.js → login-Ct2iW066.js} +1 -1
- package/lib/public/assets/{maintenance-settings-DcRmTLS6.js → maintenance-settings-DaOs00P6.js} +1 -1
- package/lib/public/assets/{monitor-Bw1YQZnL.js → monitor-D8WQK8md.js} +1 -1
- package/lib/public/assets/{mouse-pointer-2-C01jbqkO.js → mouse-pointer-2-Cw2tWzDX.js} +1 -1
- package/lib/public/assets/{network-CBGUjJDJ.js → network-Ba_uFxWo.js} +1 -1
- package/lib/public/assets/{overview-Cxe8aQ7C.js → overview-CxrZ7_6k.js} +1 -1
- package/lib/public/assets/{page-header-B92DKLiq.js → page-header-Cm1XL49f.js} +1 -1
- package/lib/public/assets/{play-Ck0L-0_m.js → play-C0CuKLXj.js} +1 -1
- package/lib/public/assets/{plus-Dq3tCy2N.js → plus-CIIvR_6Z.js} +1 -1
- package/lib/public/assets/{profile-page--dkDiKbr.js → profile-page-BZ_e-Bgw.js} +1 -1
- package/lib/public/assets/{recording-group-store-5BYIFFN9.js → recording-group-store-BWeeNs2_.js} +1 -1
- package/lib/public/assets/{reset-password-KYWlfjia.js → reset-password-lfNz8Rm1.js} +1 -1
- package/lib/public/assets/{runbook-page-mnsxgS1d.js → runbook-page-Cnec3VSx.js} +1 -1
- package/lib/public/assets/{select-BBOIZTYm.js → select-CZuCnold.js} +1 -1
- package/lib/public/assets/{selector-detail-redirect-CcI2j_Su.js → selector-detail-redirect-BG3pxFLw.js} +1 -1
- package/lib/public/assets/{selector-health-page-BdJb_x5L.js → selector-health-page-DsyL58tb.js} +1 -1
- package/lib/public/assets/{session-detail-page-BjLaJy8z.js → session-detail-page-ZZyGM413.js} +1 -1
- package/lib/public/assets/{settings-B6cpMhsx.js → settings-DGZ7B_AR.js} +1 -1
- package/lib/public/assets/{stat-tile-BU9e4s36.js → stat-tile-DFhv8JoI.js} +1 -1
- package/lib/public/assets/{tablet-hgbEwrWq.js → tablet-68J5f6zh.js} +1 -1
- package/lib/public/assets/{teams-uiiG4hZM.js → teams-eHSyEpbD.js} +1 -1
- package/lib/public/assets/{trash-2-NK_Iazmg.js → trash-2-CcSsv4fS.js} +1 -1
- package/lib/public/assets/{upload-BUX8TNFi.js → upload-BYf26K71.js} +1 -1
- package/lib/public/assets/{use-builds-data-DZszmFyl.js → use-builds-data-CHW-MhaP.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-BK4B9kRC.js → use-password-reset-mode-DozShXkk.js} +1 -1
- package/lib/public/assets/{users-BU4XBbMT.js → users-BpYnpOl2.js} +1 -1
- package/lib/public/assets/{users-BDh1xjad.js → users-CcSQRoK9.js} +1 -1
- package/lib/public/assets/{video-off-BOjNwT4R.js → video-off-dFKgps73.js} +1 -1
- package/lib/public/assets/{webhook-settings-BMzyUcx5.js → webhook-settings-DD1XjiOD.js} +1 -1
- package/lib/public/assets/{zap-DTWwVMUg.js → zap-COC2tZaH.js} +1 -1
- package/lib/public/index.html +1 -1
- package/lib/src/app/apiErrors.js +118 -0
- package/lib/src/app/index.js +6 -1
- package/lib/src/app/openapi/control.yaml +3129 -0
- package/lib/src/app/openapi/grid.yaml +2295 -0
- package/lib/src/app/openapi/identity.yaml +2168 -0
- package/lib/src/app/openapi/platform.yaml +2885 -0
- package/lib/src/app/openapi/sessions.yaml +3784 -0
- package/lib/src/app/routers/bug-report.js +4 -1
- package/lib/src/app/routers/config.js +6 -107
- package/lib/src/app/routers/control.js +117 -59
- package/lib/src/app/routers/dashboard.js +13 -7
- package/lib/src/app/routers/grid.js +54 -14
- package/lib/src/app/routers/profile.js +27 -13
- package/lib/src/app/routers/recordings.js +11 -5
- package/lib/src/app/routers/reservation.js +63 -15
- package/lib/src/app/routers/users.js +4 -0
- package/lib/src/app/routers/webhook.js +17 -8
- package/lib/src/app/swagger.js +259 -177
- package/lib/src/data-service/device-service.js +4 -1
- package/lib/src/data-service/deviceFieldOwners.js +1 -0
- package/lib/src/device-managers/AndroidDeviceManager.js +5 -2
- package/lib/src/device-managers/ios/WDAClient.js +32 -32
- package/lib/src/generated/client/edge.js +4 -3
- package/lib/src/generated/client/index-browser.js +1 -0
- package/lib/src/generated/client/index.d.ts +38 -0
- package/lib/src/generated/client/index.js +4 -3
- package/lib/src/generated/client/package.json +1 -1
- package/lib/src/generated/client/schema.prisma +2 -0
- package/lib/src/generated/client/wasm.js +1 -0
- package/lib/src/middleware/csrfMiddleware.js +13 -5
- package/lib/src/middleware/rateLimitMiddleware.js +19 -5
- package/lib/src/middleware/roleGuard.js +20 -0
- package/lib/src/services/AIService.js +13 -3
- package/lib/src/services/NotificationService.js +28 -28
- package/lib/src/services/bug-report/BugReportService.js +8 -2
- package/lib/src/services/lease/LeaseService.js +71 -20
- package/lib/src/services/omni-vision/OmniVisionService.js +14 -5
- package/lib/src/services/recording/RecordingOrchestrator.js +16 -2
- package/lib/test/helpers/expressRoutes.js +41 -0
- package/lib/test/integration/team-visibility-control.spec.js +2 -2
- package/lib/test/unit/access-scopes.spec.js +227 -0
- package/lib/test/unit/api-error-handling.spec.js +179 -0
- package/lib/test/unit/bug-report/route.spec.js +29 -0
- package/lib/test/unit/bug-report/service.spec.js +30 -0
- package/lib/test/unit/control-honest-answers.spec.js +134 -0
- package/lib/test/unit/device-allocation-routes.spec.js +232 -0
- package/lib/test/unit/healing-state-endpoints.spec.js +8 -5
- package/lib/test/unit/install-repository-app-team.spec.js +4 -1
- package/lib/test/unit/lease/LeaseService.spec.js +5 -4
- package/lib/test/unit/lease/lease-device-match.spec.js +161 -0
- package/lib/test/unit/lease/lease-session-ownership.spec.js +10 -9
- package/lib/test/unit/omni-vision-failures.spec.js +81 -0
- package/lib/test/unit/openapi-coverage.spec.js +114 -0
- package/lib/test/unit/profile-router.test.js +42 -0
- package/lib/test/unit/rateLimitMiddleware.test.js +49 -0
- package/lib/test/unit/recording-orchestrator.spec.js +80 -0
- package/lib/test/unit/recordings-library-routes.spec.js +37 -0
- package/lib/test/unit/reservation-team-visibility.spec.js +4 -3
- package/lib/test/unit/reset-link.test.js +2 -1
- package/lib/test/unit/stream-ticket-identity.spec.js +1 -1
- package/lib/test/unit/users-router.test.js +14 -1
- package/lib/test/unit/wda-client-failures.spec.js +90 -0
- package/lib/test/unit/webhook-delivery.spec.js +142 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/prisma/migrations/20261004120000_reservation_holder/migration.sql +2 -0
- package/prisma/schema.prisma +2 -0
- package/lib/src/app/swagger-docs.js +0 -1701
|
@@ -69,7 +69,10 @@ router.post('/sessions/:sessionId/bug-report', (req, res) => __awaiter(void 0, v
|
|
|
69
69
|
const svc = typedi_1.Container.get(BugReportService_1.BugReportService);
|
|
70
70
|
let bundle;
|
|
71
71
|
try {
|
|
72
|
-
|
|
72
|
+
// The network capture only for an admin, as /interceptor serves it.
|
|
73
|
+
// Through 2.12 any member who could see the session got it here.
|
|
74
|
+
const includeNetwork = (auth === null || auth === void 0 ? void 0 : auth.role) === 'ADMIN' || (auth === null || auth === void 0 ? void 0 : auth.role) === 'SUPER_ADMIN';
|
|
75
|
+
bundle = yield svc.assemble({ sessionId, mode, windowSec, includeNetwork });
|
|
73
76
|
}
|
|
74
77
|
catch (err) {
|
|
75
78
|
if (/not found/i.test(err.message)) {
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -43,40 +10,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
43
10
|
};
|
|
44
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
12
|
const express_1 = require("express");
|
|
46
|
-
const config_service_1 = require("../../data-service/config-service");
|
|
47
|
-
const typedi_1 = require("typedi");
|
|
48
|
-
const logger_1 = __importStar(require("../../logger"));
|
|
49
13
|
const AIService_1 = require("../../services/AIService");
|
|
50
14
|
const scopeGuard_1 = require("../../middleware/scopeGuard");
|
|
51
15
|
const roleGuard_1 = require("../../middleware/roleGuard");
|
|
52
16
|
class ConfigRouter {
|
|
53
|
-
static register(router
|
|
17
|
+
static register(router) {
|
|
54
18
|
const configRouter = (0, express_1.Router)();
|
|
55
|
-
//
|
|
56
|
-
// (
|
|
19
|
+
// GET and POST /config, and /config/reset-metrics, are the dashboard
|
|
20
|
+
// router's (dashboard.ts), which is registered first. This router's own
|
|
21
|
+
// GET and POST were never reached, and are gone. What is left: testing an
|
|
22
|
+
// AI provider, SUPER_ADMIN with the admin scope.
|
|
57
23
|
configRouter.use((0, roleGuard_1.roleGuard)('ADMIN'));
|
|
58
|
-
// All mutations under /config require admin scope (global plugin
|
|
59
|
-
// config + AI provider test probes). GET passthrough for read scope.
|
|
60
24
|
configRouter.use((0, scopeGuard_1.mutationScopeGuard)(['admin']));
|
|
61
|
-
function
|
|
62
|
-
const masked = Object.assign({}, args);
|
|
63
|
-
// Boolean flags for secret status
|
|
64
|
-
masked.geminiSet = !!(process.env.XENON_GEMINI_API_KEY || process.env.GEMINI_API_KEY);
|
|
65
|
-
masked.openaiSet = !!(process.env.XENON_OPENAI_API_KEY || process.env.OPENAI_API_KEY);
|
|
66
|
-
masked.anthropicSet = !!(process.env.XENON_ANTHROPIC_API_KEY || process.env.ANTHROPIC_API_KEY);
|
|
67
|
-
// Remove actual keys from the response completely
|
|
68
|
-
delete masked.geminiApiKey;
|
|
69
|
-
delete masked.openaiApiKey;
|
|
70
|
-
delete masked.anthropicApiKey;
|
|
71
|
-
if (masked.databaseUrl) {
|
|
72
|
-
masked.databaseUrl = '********';
|
|
73
|
-
}
|
|
74
|
-
return masked;
|
|
75
|
-
}
|
|
76
|
-
configRouter.get('/', (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
res.json(getMaskedConfig(pluginArgs));
|
|
78
|
-
}));
|
|
79
|
-
configRouter.post('/test-ai', (0, roleGuard_1.roleGuard)('SUPER_ADMIN'), (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
configRouter.post('/test-ai', (0, roleGuard_1.superAdminGuard)('Only a super admin can test an AI provider.'), (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
80
26
|
const testConfig = req.unredactedBody || req.body;
|
|
81
27
|
try {
|
|
82
28
|
const result = yield AIService_1.AI_SERVICE.testConnection(testConfig);
|
|
@@ -86,54 +32,7 @@ class ConfigRouter {
|
|
|
86
32
|
res.status(500).json({ success: false, message: err.message });
|
|
87
33
|
}
|
|
88
34
|
}));
|
|
89
|
-
configRouter.post('/', (0, roleGuard_1.roleGuard)('SUPER_ADMIN'), (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
90
|
-
const newConfig = (req.unredactedBody || req.body);
|
|
91
|
-
if (!newConfig || Object.keys(newConfig).length === 0) {
|
|
92
|
-
return res.status(400).json({ error: 'No configuration provided' });
|
|
93
|
-
}
|
|
94
|
-
// Environment-Only Enforcement: Ignore any keys sent via UI
|
|
95
|
-
delete newConfig.geminiApiKey;
|
|
96
|
-
delete newConfig.openaiApiKey;
|
|
97
|
-
delete newConfig.anthropicApiKey;
|
|
98
|
-
// Handle Database URL mask preservation
|
|
99
|
-
if (newConfig.databaseUrl && newConfig.databaseUrl.includes('****')) {
|
|
100
|
-
delete newConfig.databaseUrl;
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
logger_1.default.debug(`Updating configuration with payload: ${JSON.stringify((0, logger_1.redactSecrets)(newConfig))}`);
|
|
104
|
-
// 1. Persist (also updates global config singleton and env vars)
|
|
105
|
-
yield typedi_1.Container.get(config_service_1.ConfigService).updateConfig(newConfig);
|
|
106
|
-
// 2. Update Runtime Object (for Appium Plugin lifecycle)
|
|
107
|
-
Object.assign(pluginArgs, newConfig);
|
|
108
|
-
logger_1.default.info('Configuration updated via API');
|
|
109
|
-
res.json({
|
|
110
|
-
success: true,
|
|
111
|
-
config: getMaskedConfig(pluginArgs),
|
|
112
|
-
restartRequired: checkRestartRequired(newConfig),
|
|
113
|
-
message: 'Configuration updated. Some changes may require a server restart to take full effect.',
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
logger_1.default.error(`Failed to update config: ${err.message}`, err);
|
|
118
|
-
res
|
|
119
|
-
.status(500)
|
|
120
|
-
.json({ success: false, error: `Failed to update configuration: ${err.message}` });
|
|
121
|
-
}
|
|
122
|
-
}));
|
|
123
35
|
router.use('/config', configRouter);
|
|
124
36
|
}
|
|
125
37
|
}
|
|
126
38
|
exports.default = ConfigRouter;
|
|
127
|
-
function checkRestartRequired(newConfig) {
|
|
128
|
-
// List of keys that definitely require restart
|
|
129
|
-
const RESTART_KEYS = [
|
|
130
|
-
'hub',
|
|
131
|
-
'platform',
|
|
132
|
-
'bindHostOrIp',
|
|
133
|
-
'proxy',
|
|
134
|
-
'cloud',
|
|
135
|
-
'iosDeviceType',
|
|
136
|
-
'androidDeviceType',
|
|
137
|
-
];
|
|
138
|
-
return Object.keys(newConfig).some((key) => RESTART_KEYS.includes(key));
|
|
139
|
-
}
|