@xenon-device-management/xenon 1.7.2 → 1.7.3
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 -1
- package/lib/src/app/index.js +6 -0
- package/lib/src/app/routers/auth.js +30 -0
- package/lib/src/app/routers/capabilities.js +25 -0
- package/lib/src/app/routers/control.js +14 -0
- package/lib/src/app/routers/projects.js +55 -0
- package/lib/src/generated/client/edge.js +22 -4
- package/lib/src/generated/client/index-browser.js +19 -1
- package/lib/src/generated/client/index.d.ts +2376 -158
- package/lib/src/generated/client/index.js +22 -4
- package/lib/src/generated/client/package.json +1 -1
- package/lib/src/generated/client/schema.prisma +21 -0
- package/lib/src/generated/client/wasm.js +19 -1
- package/lib/src/middleware/authMiddleware.js +64 -3
- package/lib/src/prisma.js +1 -1
- package/lib/src/services/EventLogService.js +81 -0
- package/lib/src/services/ServerManager.js +36 -0
- package/lib/src/services/SocketServer.js +2 -0
- package/lib/src/services/artifacts/ArtifactStore.js +60 -0
- package/lib/src/services/recording/RecordingOrchestrator.js +4 -5
- package/lib/src/services/token/JwtKeyService.js +137 -0
- package/lib/src/services/token/StreamTicketService.js +61 -0
- package/lib/test/unit/ArtifactStore.spec.js +59 -0
- package/lib/test/unit/CapabilitiesRouter.spec.js +18 -0
- package/lib/test/unit/EventLogService.spec.js +67 -0
- package/lib/test/unit/JwtKeyService.spec.js +86 -0
- package/lib/test/unit/ProjectsRouter.spec.js +45 -0
- package/lib/test/unit/StreamTicketService.spec.js +95 -0
- package/lib/test/unit/TokenEndpoint.spec.js +68 -0
- package/lib/test/unit/authMiddleware.bearer.spec.js +102 -0
- package/lib/test/unit/authMiddleware.streamTicket.spec.js +217 -0
- package/lib/test/unit/recording-instrumentation.spec.js +8 -0
- package/lib/test/unit/recording-orchestrator.spec.js +14 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/prisma/migrations/20260717063103_event_log/migration.sql +15 -0
- package/prisma/migrations/20260717070124_project_entity/migration.sql +10 -0
- package/prisma/schema.prisma +21 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
require("reflect-metadata");
|
|
16
|
+
const chai_1 = require("chai");
|
|
17
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
18
|
+
const express_1 = __importDefault(require("express"));
|
|
19
|
+
const supertest_1 = __importDefault(require("supertest"));
|
|
20
|
+
const typedi_1 = require("typedi");
|
|
21
|
+
const fs_1 = __importDefault(require("fs"));
|
|
22
|
+
const os_1 = __importDefault(require("os"));
|
|
23
|
+
const path_1 = __importDefault(require("path"));
|
|
24
|
+
const JwtKeyService_1 = require("../../src/services/token/JwtKeyService");
|
|
25
|
+
const StreamTicketService_1 = require("../../src/services/token/StreamTicketService");
|
|
26
|
+
const authMiddleware_1 = require("../../src/middleware/authMiddleware");
|
|
27
|
+
const control_1 = __importDefault(require("../../src/app/routers/control"));
|
|
28
|
+
const device_store_1 = require("../../src/data-service/device-store");
|
|
29
|
+
const UserService_1 = require("../../src/services/UserService");
|
|
30
|
+
const ApiKeyService_1 = require("../../src/services/ApiKeyService");
|
|
31
|
+
const UserSessionService_1 = require("../../src/services/UserSessionService");
|
|
32
|
+
function fakeRes() {
|
|
33
|
+
const res = { statusCode: 200 };
|
|
34
|
+
res.status = (c) => {
|
|
35
|
+
res.statusCode = c;
|
|
36
|
+
return res;
|
|
37
|
+
};
|
|
38
|
+
res.json = (b) => {
|
|
39
|
+
res.body = b;
|
|
40
|
+
return res;
|
|
41
|
+
};
|
|
42
|
+
res.cookie = () => res;
|
|
43
|
+
return res;
|
|
44
|
+
}
|
|
45
|
+
describe('authMiddleware — stream-ticket branch', () => {
|
|
46
|
+
let dir;
|
|
47
|
+
let keySvc;
|
|
48
|
+
let ticketSvc;
|
|
49
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
dir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'xenon-authmw-ticket-'));
|
|
51
|
+
keySvc = new JwtKeyService_1.JwtKeyService();
|
|
52
|
+
yield keySvc.init(dir);
|
|
53
|
+
typedi_1.Container.set(JwtKeyService_1.JwtKeyService, keySvc);
|
|
54
|
+
ticketSvc = new StreamTicketService_1.StreamTicketService();
|
|
55
|
+
typedi_1.Container.set(StreamTicketService_1.StreamTicketService, ticketSvc);
|
|
56
|
+
typedi_1.Container.set(UserService_1.UserService, { findById: sinon_1.default.stub().resolves(null) });
|
|
57
|
+
typedi_1.Container.set(ApiKeyService_1.ApiKeyService, {
|
|
58
|
+
verifyPair: sinon_1.default.stub().resolves(null),
|
|
59
|
+
verify: sinon_1.default.stub().resolves(null),
|
|
60
|
+
});
|
|
61
|
+
typedi_1.Container.set(UserSessionService_1.UserSessionService, { resolve: sinon_1.default.stub().resolves(null) });
|
|
62
|
+
}));
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
sinon_1.default.restore();
|
|
65
|
+
typedi_1.Container.reset();
|
|
66
|
+
fs_1.default.rmSync(dir, { recursive: true, force: true });
|
|
67
|
+
});
|
|
68
|
+
// req.path here mirrors what authMiddleware actually sees at runtime:
|
|
69
|
+
// it's mounted directly on apiRouter (src/app/index.ts line 223) BEFORE
|
|
70
|
+
// ControlRouter.register(apiRouter) mounts '/control' onto that same
|
|
71
|
+
// apiRouter (control.ts: parentRouter.use('/control', router)), so the
|
|
72
|
+
// apiRouter-relative path for GET /xenon/api/control/UDID-1/stream is
|
|
73
|
+
// '/control/UDID-1/stream' — not the full external URL.
|
|
74
|
+
it('accepts a valid ticket for the matching udid on GET /control/:udid/stream', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
76
|
+
const req = {
|
|
77
|
+
method: 'GET',
|
|
78
|
+
path: '/control/UDID-1/stream',
|
|
79
|
+
query: { ticket },
|
|
80
|
+
headers: {},
|
|
81
|
+
};
|
|
82
|
+
const res = fakeRes();
|
|
83
|
+
const next = sinon_1.default.spy();
|
|
84
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, next);
|
|
85
|
+
(0, chai_1.expect)(next.calledOnce).to.equal(true);
|
|
86
|
+
(0, chai_1.expect)(req.auth.kind).to.equal('stream-ticket');
|
|
87
|
+
(0, chai_1.expect)(req.auth.userId).to.equal('actor-1');
|
|
88
|
+
}));
|
|
89
|
+
it('rejects a ticket minted for a different udid with 401 invalid ticket', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
91
|
+
const req = {
|
|
92
|
+
method: 'GET',
|
|
93
|
+
path: '/control/UDID-2/stream',
|
|
94
|
+
query: { ticket },
|
|
95
|
+
headers: {},
|
|
96
|
+
};
|
|
97
|
+
const res = fakeRes();
|
|
98
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
|
|
99
|
+
(0, chai_1.expect)(res.statusCode).to.equal(401);
|
|
100
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'invalid ticket' });
|
|
101
|
+
}));
|
|
102
|
+
it('rejects reuse of an already-redeemed ticket', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
104
|
+
yield ticketSvc.redeem(ticket, 'UDID-1');
|
|
105
|
+
const req = {
|
|
106
|
+
method: 'GET',
|
|
107
|
+
path: '/control/UDID-1/stream',
|
|
108
|
+
query: { ticket },
|
|
109
|
+
headers: {},
|
|
110
|
+
};
|
|
111
|
+
const res = fakeRes();
|
|
112
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
|
|
113
|
+
(0, chai_1.expect)(res.statusCode).to.equal(401);
|
|
114
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'invalid ticket' });
|
|
115
|
+
}));
|
|
116
|
+
it('does NOT match a sibling stream route (stream/status) even with a valid ticket', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
118
|
+
const req = {
|
|
119
|
+
method: 'GET',
|
|
120
|
+
path: '/control/UDID-1/stream/status',
|
|
121
|
+
query: { ticket },
|
|
122
|
+
headers: {},
|
|
123
|
+
};
|
|
124
|
+
const res = fakeRes();
|
|
125
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
|
|
126
|
+
// Falls through to the final unauthenticated 401, not the ticket branch.
|
|
127
|
+
(0, chai_1.expect)(res.statusCode).to.equal(401);
|
|
128
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
|
|
129
|
+
}));
|
|
130
|
+
it('does NOT match a POST to the stream route (ticket-mint or otherwise)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
131
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
132
|
+
const req = {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
path: '/control/UDID-1/stream',
|
|
135
|
+
query: { ticket },
|
|
136
|
+
headers: {},
|
|
137
|
+
};
|
|
138
|
+
const res = fakeRes();
|
|
139
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
|
|
140
|
+
(0, chai_1.expect)(res.statusCode).to.equal(401);
|
|
141
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
|
|
142
|
+
}));
|
|
143
|
+
it('ignores a non-string ticket query value (e.g. array from ?ticket=a&ticket=b)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
const req = {
|
|
145
|
+
method: 'GET',
|
|
146
|
+
path: '/control/UDID-1/stream',
|
|
147
|
+
query: { ticket: ['a', 'b'] },
|
|
148
|
+
headers: {},
|
|
149
|
+
};
|
|
150
|
+
const res = fakeRes();
|
|
151
|
+
yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
|
|
152
|
+
(0, chai_1.expect)(res.statusCode).to.equal(401);
|
|
153
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
|
|
154
|
+
}));
|
|
155
|
+
});
|
|
156
|
+
// Mount-order guard: the hand-built-req tests above hardcode
|
|
157
|
+
// req.path='/control/UDID-1/stream', so they'd keep passing even if a future
|
|
158
|
+
// change to how authMiddleware / ControlRouter are mounted stopped delivering
|
|
159
|
+
// that apiRouter-relative path to the middleware — silently reopening "does
|
|
160
|
+
// the ticket branch even fire?". This block wires the REAL chain the same way
|
|
161
|
+
// src/app/index.ts does (apiRouter.use(authMiddleware); ControlRouter mounts
|
|
162
|
+
// '/control' onto apiRouter) and drives an actual HTTP request through it, so
|
|
163
|
+
// a regression in the mount path is caught end-to-end. The device store is
|
|
164
|
+
// stubbed to report "no such device", so a request that clears auth lands on
|
|
165
|
+
// the route handler's 404 — distinct from authMiddleware's 401. Asserting
|
|
166
|
+
// "not 401 unauthenticated" therefore proves the ticket branch fired.
|
|
167
|
+
describe('authMiddleware — stream-ticket branch (real mount-order, supertest)', () => {
|
|
168
|
+
let dir;
|
|
169
|
+
let app;
|
|
170
|
+
let ticketSvc;
|
|
171
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
172
|
+
dir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'xenon-authmw-mount-'));
|
|
173
|
+
const keySvc = new JwtKeyService_1.JwtKeyService();
|
|
174
|
+
yield keySvc.init(dir);
|
|
175
|
+
typedi_1.Container.set(JwtKeyService_1.JwtKeyService, keySvc);
|
|
176
|
+
ticketSvc = new StreamTicketService_1.StreamTicketService();
|
|
177
|
+
typedi_1.Container.set(StreamTicketService_1.StreamTicketService, ticketSvc);
|
|
178
|
+
typedi_1.Container.set(UserService_1.UserService, { findById: sinon_1.default.stub().resolves(null) });
|
|
179
|
+
typedi_1.Container.set(ApiKeyService_1.ApiKeyService, {
|
|
180
|
+
verifyPair: sinon_1.default.stub().resolves(null),
|
|
181
|
+
verify: sinon_1.default.stub().resolves(null),
|
|
182
|
+
});
|
|
183
|
+
typedi_1.Container.set(UserSessionService_1.UserSessionService, { resolve: sinon_1.default.stub().resolves(null) });
|
|
184
|
+
// Clean 404 path: the GET /:udid/stream handler's first act is
|
|
185
|
+
// getDeviceInfo(udid) -> DeviceStoreFactory.getStore().findDevice(...).
|
|
186
|
+
// Return no device so the handler responds 404 'Device not found' the
|
|
187
|
+
// moment it runs — which only happens if auth (the ticket branch) passed.
|
|
188
|
+
sinon_1.default
|
|
189
|
+
.stub(device_store_1.DeviceStoreFactory, 'getStore')
|
|
190
|
+
.returns({ findDevice: sinon_1.default.stub().resolves(undefined) });
|
|
191
|
+
// Mount exactly like src/app/index.ts: authMiddleware directly on the
|
|
192
|
+
// apiRouter, THEN ControlRouter.register(apiRouter) mounts '/control'.
|
|
193
|
+
const apiRouter = express_1.default.Router();
|
|
194
|
+
apiRouter.use(authMiddleware_1.authMiddleware);
|
|
195
|
+
control_1.default.register(apiRouter);
|
|
196
|
+
app = (0, express_1.default)();
|
|
197
|
+
app.use('/xenon/api', apiRouter);
|
|
198
|
+
}));
|
|
199
|
+
afterEach(() => {
|
|
200
|
+
sinon_1.default.restore();
|
|
201
|
+
typedi_1.Container.reset();
|
|
202
|
+
fs_1.default.rmSync(dir, { recursive: true, force: true });
|
|
203
|
+
});
|
|
204
|
+
it('a valid ticket on GET /xenon/api/control/:udid/stream reaches the route (past 401)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
205
|
+
const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
|
|
206
|
+
const res = yield (0, supertest_1.default)(app).get('/xenon/api/control/UDID-1/stream').query({ ticket });
|
|
207
|
+
// The ticket branch fired: request cleared auth and hit the handler's
|
|
208
|
+
// device lookup (404), rather than being rejected at the middleware (401).
|
|
209
|
+
(0, chai_1.expect)(res.status).to.not.equal(401);
|
|
210
|
+
(0, chai_1.expect)(res.status).to.equal(404); // 'Device not found' from the stubbed store
|
|
211
|
+
}));
|
|
212
|
+
it('the SAME request without a ticket is rejected 401 (proves the guard is non-vacuous)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
213
|
+
const res = yield (0, supertest_1.default)(app).get('/xenon/api/control/UDID-1/stream');
|
|
214
|
+
(0, chai_1.expect)(res.status).to.equal(401);
|
|
215
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
@@ -15,8 +15,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
require("reflect-metadata");
|
|
16
16
|
const chai_1 = require("chai");
|
|
17
17
|
const sinon_1 = __importDefault(require("sinon"));
|
|
18
|
+
const os_1 = __importDefault(require("os"));
|
|
19
|
+
const typedi_1 = require("typedi");
|
|
18
20
|
const api_1 = require("@opentelemetry/api");
|
|
19
21
|
const attributes_1 = require("../../src/services/telemetry/attributes");
|
|
22
|
+
const ArtifactStore_1 = require("../../src/services/artifacts/ArtifactStore");
|
|
20
23
|
// Stub metrics + trace BEFORE the module loads so the module-level
|
|
21
24
|
// ensureOtelInstruments() picks up our mocks. Inline import after stubbing.
|
|
22
25
|
function makeMockMeter() {
|
|
@@ -63,12 +66,17 @@ describe('RecordingOrchestrator instrumentation', () => {
|
|
|
63
66
|
// Pre-stub once to get clean instrument creation in the SUT.
|
|
64
67
|
getMeterStub = sinon_1.default.stub(api_1.metrics, 'getMeter');
|
|
65
68
|
getTracerStub = sinon_1.default.stub(api_1.trace, 'getTracer');
|
|
69
|
+
// RecordingOrchestrator resolves ARTIFACT_STORE from the container at
|
|
70
|
+
// runtime (registered at boot in ServerManager); register it here so the
|
|
71
|
+
// path-construction helpers work under test.
|
|
72
|
+
typedi_1.Container.set(ArtifactStore_1.ARTIFACT_STORE, new ArtifactStore_1.FsArtifactStore(os_1.default.tmpdir()));
|
|
66
73
|
// Now import — module-level let bindings will populate against the stub.
|
|
67
74
|
RecordingOrchestratorMod = require('../../src/services/recording/RecordingOrchestrator');
|
|
68
75
|
});
|
|
69
76
|
after(() => {
|
|
70
77
|
getMeterStub.restore();
|
|
71
78
|
getTracerStub.restore();
|
|
79
|
+
typedi_1.Container.remove(ArtifactStore_1.ARTIFACT_STORE);
|
|
72
80
|
});
|
|
73
81
|
beforeEach(() => {
|
|
74
82
|
mockMeterCtx = makeMockMeter();
|
|
@@ -48,10 +48,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
48
48
|
require("reflect-metadata");
|
|
49
49
|
const chai_1 = require("chai");
|
|
50
50
|
const sinon_1 = __importDefault(require("sinon"));
|
|
51
|
+
const os_1 = __importDefault(require("os"));
|
|
52
|
+
const typedi_1 = require("typedi");
|
|
51
53
|
const RecordingOrchestrator_1 = require("../../src/services/recording/RecordingOrchestrator");
|
|
52
54
|
const concurrency_gate_1 = require("../../src/services/recording/concurrency-gate");
|
|
55
|
+
const ArtifactStore_1 = require("../../src/services/artifacts/ArtifactStore");
|
|
53
56
|
// Stub the device store factory (used to look up host).
|
|
54
57
|
const deviceStoreModule = __importStar(require("../../src/data-service/device-store"));
|
|
58
|
+
// compositeOutputPath / per-device filePath construction resolve through
|
|
59
|
+
// ArtifactStore now (Task 7) — register a store the same way ServerManager
|
|
60
|
+
// does at boot, so RecordingOrchestrator's Container.get(ARTIFACT_STORE)
|
|
61
|
+
// doesn't throw in this unit test context.
|
|
62
|
+
before(() => {
|
|
63
|
+
typedi_1.Container.set(ArtifactStore_1.ARTIFACT_STORE, new ArtifactStore_1.FsArtifactStore(os_1.default.tmpdir()));
|
|
64
|
+
});
|
|
65
|
+
// Don't leave the global container polluted for later spec files in the run.
|
|
66
|
+
after(() => {
|
|
67
|
+
typedi_1.Container.remove(ArtifactStore_1.ARTIFACT_STORE);
|
|
68
|
+
});
|
|
55
69
|
function makeOrch(overrides = {}) {
|
|
56
70
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
57
71
|
const busyPrecheck = (_a = overrides.busyPrecheck) !== null && _a !== void 0 ? _a : { findBusy: sinon_1.default.stub().resolves([]) };
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/index.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AutowaitService.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/TeamService.test.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/helpers.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/projects.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/index.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/helpers.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenon-device-management/xenon",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
|
|
5
5
|
"main": "./lib/src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"http-proxy-middleware": "^3.0.0-beta.1",
|
|
93
93
|
"https-proxy-agent": "7.0.2",
|
|
94
94
|
"ip": "^1.1.8",
|
|
95
|
+
"jose": "^5.10.0",
|
|
95
96
|
"jsonschema": "1.4.1",
|
|
96
97
|
"lodash": "^4.17.21",
|
|
97
98
|
"lokijs": "^1.5.12",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "EventLog" (
|
|
3
|
+
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
+
"type" TEXT NOT NULL,
|
|
5
|
+
"payload" TEXT NOT NULL,
|
|
6
|
+
"correlationId" TEXT,
|
|
7
|
+
"teamId" TEXT,
|
|
8
|
+
"occurredAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
-- CreateIndex
|
|
12
|
+
CREATE INDEX "EventLog_type_occurredAt_idx" ON "EventLog"("type", "occurredAt");
|
|
13
|
+
|
|
14
|
+
-- CreateIndex
|
|
15
|
+
CREATE INDEX "EventLog_occurredAt_idx" ON "EventLog"("occurredAt");
|
package/prisma/schema.prisma
CHANGED
|
@@ -437,3 +437,24 @@ model TeamMember {
|
|
|
437
437
|
@@id([teamId, userId])
|
|
438
438
|
@@index([userId])
|
|
439
439
|
}
|
|
440
|
+
|
|
441
|
+
model EventLog {
|
|
442
|
+
id String @id @default(cuid())
|
|
443
|
+
type String
|
|
444
|
+
payload String // JSON string — portable, no SQLite-isms
|
|
445
|
+
correlationId String?
|
|
446
|
+
teamId String?
|
|
447
|
+
occurredAt DateTime @default(now())
|
|
448
|
+
|
|
449
|
+
@@index([type, occurredAt])
|
|
450
|
+
@@index([occurredAt])
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
model Project {
|
|
454
|
+
id String @id @default(cuid())
|
|
455
|
+
name String
|
|
456
|
+
teamId String?
|
|
457
|
+
createdAt DateTime @default(now())
|
|
458
|
+
|
|
459
|
+
@@index([teamId])
|
|
460
|
+
}
|