@urateam/dashboard 0.1.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/dist/__tests__/layout.test.d.ts +2 -0
- package/dist/__tests__/layout.test.d.ts.map +1 -0
- package/dist/__tests__/layout.test.js +138 -0
- package/dist/__tests__/layout.test.js.map +1 -0
- package/dist/__tests__/security.repro.test.d.ts +16 -0
- package/dist/__tests__/security.repro.test.d.ts.map +1 -0
- package/dist/__tests__/security.repro.test.js +249 -0
- package/dist/__tests__/security.repro.test.js.map +1 -0
- package/dist/__tests__/server.test.d.ts +2 -0
- package/dist/__tests__/server.test.d.ts.map +1 -0
- package/dist/__tests__/server.test.js +268 -0
- package/dist/__tests__/server.test.js.map +1 -0
- package/dist/__tests__/ui-refresh.test.d.ts +2 -0
- package/dist/__tests__/ui-refresh.test.d.ts.map +1 -0
- package/dist/__tests__/ui-refresh.test.js +860 -0
- package/dist/__tests__/ui-refresh.test.js.map +1 -0
- package/dist/routes/config.d.ts +4 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +12 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/coordination.d.ts +4 -0
- package/dist/routes/coordination.d.ts.map +1 -0
- package/dist/routes/coordination.js +22 -0
- package/dist/routes/coordination.js.map +1 -0
- package/dist/routes/errors.d.ts +4 -0
- package/dist/routes/errors.d.ts.map +1 -0
- package/dist/routes/errors.js +36 -0
- package/dist/routes/errors.js.map +1 -0
- package/dist/routes/runs.d.ts +4 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +72 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/tokens.d.ts +4 -0
- package/dist/routes/tokens.d.ts.map +1 -0
- package/dist/routes/tokens.js +47 -0
- package/dist/routes/tokens.js.map +1 -0
- package/dist/server.d.ts +19 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/dist/views/config.d.ts +3 -0
- package/dist/views/config.d.ts.map +1 -0
- package/dist/views/config.js +47 -0
- package/dist/views/config.js.map +1 -0
- package/dist/views/coordination.d.ts +3 -0
- package/dist/views/coordination.d.ts.map +1 -0
- package/dist/views/coordination.js +63 -0
- package/dist/views/coordination.js.map +1 -0
- package/dist/views/errors.d.ts +14 -0
- package/dist/views/errors.d.ts.map +1 -0
- package/dist/views/errors.js +52 -0
- package/dist/views/errors.js.map +1 -0
- package/dist/views/layout.d.ts +21 -0
- package/dist/views/layout.d.ts.map +1 -0
- package/dist/views/layout.js +82 -0
- package/dist/views/layout.js.map +1 -0
- package/dist/views/run-detail.d.ts +35 -0
- package/dist/views/run-detail.d.ts.map +1 -0
- package/dist/views/run-detail.js +129 -0
- package/dist/views/run-detail.js.map +1 -0
- package/dist/views/run-feed.d.ts +14 -0
- package/dist/views/run-feed.d.ts.map +1 -0
- package/dist/views/run-feed.js +80 -0
- package/dist/views/run-feed.js.map +1 -0
- package/dist/views/tokens.d.ts +13 -0
- package/dist/views/tokens.d.ts.map +1 -0
- package/dist/views/tokens.js +66 -0
- package/dist/views/tokens.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/layout.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { layout, escapeHtml, getBasePath } from "../views/layout.js";
|
|
3
|
+
describe("layout", () => {
|
|
4
|
+
const originalEnv = process.env.DASHBOARD_BASE_PATH;
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
delete process.env.DASHBOARD_BASE_PATH;
|
|
7
|
+
if (originalEnv) {
|
|
8
|
+
process.env.DASHBOARD_BASE_PATH = originalEnv;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
describe("basePath computation", () => {
|
|
12
|
+
it("should use DASHBOARD_BASE_PATH environment variable", () => {
|
|
13
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam";
|
|
14
|
+
expect(getBasePath()).toBe("/ateam");
|
|
15
|
+
});
|
|
16
|
+
it("should strip trailing slashes from DASHBOARD_BASE_PATH", () => {
|
|
17
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam/";
|
|
18
|
+
expect(getBasePath()).toBe("/ateam");
|
|
19
|
+
});
|
|
20
|
+
it("should strip multiple trailing slashes", () => {
|
|
21
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam///";
|
|
22
|
+
expect(getBasePath()).toBe("/ateam");
|
|
23
|
+
});
|
|
24
|
+
it("should be empty string when DASHBOARD_BASE_PATH is not set", () => {
|
|
25
|
+
delete process.env.DASHBOARD_BASE_PATH;
|
|
26
|
+
expect(getBasePath()).toBe("");
|
|
27
|
+
});
|
|
28
|
+
it("should be empty string when DASHBOARD_BASE_PATH is only slashes", () => {
|
|
29
|
+
process.env.DASHBOARD_BASE_PATH = "///";
|
|
30
|
+
expect(getBasePath()).toBe("");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("HTML generation", () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
// Mock a simple basePath for consistent tests
|
|
36
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam";
|
|
37
|
+
});
|
|
38
|
+
it("should generate valid HTML structure", () => {
|
|
39
|
+
const html = layout("Test Page", "<p>Content</p>");
|
|
40
|
+
expect(html).toContain("<!DOCTYPE html>");
|
|
41
|
+
expect(html).toContain("<html lang=\"en\">");
|
|
42
|
+
expect(html).toContain("</html>");
|
|
43
|
+
});
|
|
44
|
+
it("should include page title with escaped content", () => {
|
|
45
|
+
const html = layout("Test & Title", "content");
|
|
46
|
+
expect(html).toContain("<title>Test & Title - urateam</title>");
|
|
47
|
+
});
|
|
48
|
+
it("should include static CSS link with basePath", () => {
|
|
49
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam";
|
|
50
|
+
const html = layout("Test", "");
|
|
51
|
+
expect(html).toContain("<link rel=\"stylesheet\" href=\"/ateam/static/style.css\">");
|
|
52
|
+
});
|
|
53
|
+
it("should include HTMX script", () => {
|
|
54
|
+
const html = layout("Test", "");
|
|
55
|
+
expect(html).toContain('<script src="https://unpkg.com/htmx.org@2.0.0"></script>');
|
|
56
|
+
});
|
|
57
|
+
it("should include navigation links with basePath", () => {
|
|
58
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam";
|
|
59
|
+
const html = layout("Test", "");
|
|
60
|
+
expect(html).toContain('<a href="/ateam/">Runs</a>');
|
|
61
|
+
expect(html).toContain('<a href="/ateam/tokens">Tokens</a>');
|
|
62
|
+
expect(html).toContain('<a href="/ateam/errors">Errors</a>');
|
|
63
|
+
expect(html).toContain('<a href="/ateam/config">Config</a>');
|
|
64
|
+
expect(html).toContain('<a href="/ateam/coordination">Coordination</a>');
|
|
65
|
+
});
|
|
66
|
+
it("should include navigation links without basePath when not set", () => {
|
|
67
|
+
delete process.env.DASHBOARD_BASE_PATH;
|
|
68
|
+
const html = layout("Test", "");
|
|
69
|
+
expect(html).toContain('<a href="/">Runs</a>');
|
|
70
|
+
expect(html).toContain('<a href="/tokens">Tokens</a>');
|
|
71
|
+
expect(html).toContain('<a href="/errors">Errors</a>');
|
|
72
|
+
expect(html).toContain('<a href="/config">Config</a>');
|
|
73
|
+
expect(html).toContain('<a href="/coordination">Coordination</a>');
|
|
74
|
+
});
|
|
75
|
+
it("should include page content", () => {
|
|
76
|
+
const content = "<p>Test content here</p>";
|
|
77
|
+
const html = layout("Test", content);
|
|
78
|
+
expect(html).toContain(content);
|
|
79
|
+
});
|
|
80
|
+
it("should include viewport meta tag for responsive design", () => {
|
|
81
|
+
const html = layout("Test", "");
|
|
82
|
+
expect(html).toContain('<meta name="viewport" content="width=device-width, initial-scale=1">');
|
|
83
|
+
});
|
|
84
|
+
it("should escape special characters in page title", () => {
|
|
85
|
+
const html = layout("<script>alert('xss')</script>", "");
|
|
86
|
+
expect(html).toContain("<script>");
|
|
87
|
+
expect(html).not.toContain("<script>alert");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe("escapeHtml function", () => {
|
|
91
|
+
it("should escape ampersands", () => {
|
|
92
|
+
expect(escapeHtml("A & B")).toBe("A & B");
|
|
93
|
+
});
|
|
94
|
+
it("should escape less-than signs", () => {
|
|
95
|
+
expect(escapeHtml("A < B")).toBe("A < B");
|
|
96
|
+
});
|
|
97
|
+
it("should escape greater-than signs", () => {
|
|
98
|
+
expect(escapeHtml("A > B")).toBe("A > B");
|
|
99
|
+
});
|
|
100
|
+
it("should escape double quotes", () => {
|
|
101
|
+
expect(escapeHtml('Say "Hello"')).toBe("Say "Hello"");
|
|
102
|
+
});
|
|
103
|
+
it("should escape single quotes", () => {
|
|
104
|
+
expect(escapeHtml("It's fine")).toBe("It's fine");
|
|
105
|
+
});
|
|
106
|
+
it("should escape multiple special characters", () => {
|
|
107
|
+
expect(escapeHtml('<script>alert("xss")</script>')).toBe('<script>alert("xss")</script>');
|
|
108
|
+
});
|
|
109
|
+
it("should handle empty string", () => {
|
|
110
|
+
expect(escapeHtml("")).toBe("");
|
|
111
|
+
});
|
|
112
|
+
it("should handle string without special characters", () => {
|
|
113
|
+
expect(escapeHtml("Hello World")).toBe("Hello World");
|
|
114
|
+
});
|
|
115
|
+
it("should escape in the correct order (ampersand first)", () => {
|
|
116
|
+
// If we don't escape ampersand first, we might double-escape
|
|
117
|
+
expect(escapeHtml("<")).toBe("&lt;");
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe("CSS and asset loading", () => {
|
|
121
|
+
it("should use relative path for CSS when basePath is empty", () => {
|
|
122
|
+
delete process.env.DASHBOARD_BASE_PATH;
|
|
123
|
+
const html = layout("Test", "");
|
|
124
|
+
expect(html).toContain('href="/static/style.css"');
|
|
125
|
+
});
|
|
126
|
+
it("should use correct path for CSS with basePath /ateam", () => {
|
|
127
|
+
process.env.DASHBOARD_BASE_PATH = "/ateam";
|
|
128
|
+
const html = layout("Test", "");
|
|
129
|
+
expect(html).toContain('href="/ateam/static/style.css"');
|
|
130
|
+
});
|
|
131
|
+
it("should use correct path for CSS with custom basePath", () => {
|
|
132
|
+
process.env.DASHBOARD_BASE_PATH = "/myapp";
|
|
133
|
+
const html = layout("Test", "");
|
|
134
|
+
expect(html).toContain('href="/myapp/static/style.css"');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=layout.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.test.js","sourceRoot":"","sources":["../../src/__tests__/layout.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BEC-103 Security Tests — Dashboard Security Hardening
|
|
3
|
+
*
|
|
4
|
+
* Tests verify the hardened security behaviour introduced in BEC-103:
|
|
5
|
+
* - Security headers on all responses (including auth-blocked responses)
|
|
6
|
+
* - Basic auth required (503 when not configured)
|
|
7
|
+
* - CSRF protection on state-changing requests (POST/PUT/DELETE/PATCH only)
|
|
8
|
+
* - Rate limiting to prevent brute-force attacks
|
|
9
|
+
* - Credential redaction in config view
|
|
10
|
+
* - CSP meta tag in layout HTML
|
|
11
|
+
*
|
|
12
|
+
* Run with:
|
|
13
|
+
* cd packages/dashboard && npx vitest run src/__tests__/security.repro.test.ts
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=security.repro.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.repro.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/security.repro.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BEC-103 Security Tests — Dashboard Security Hardening
|
|
3
|
+
*
|
|
4
|
+
* Tests verify the hardened security behaviour introduced in BEC-103:
|
|
5
|
+
* - Security headers on all responses (including auth-blocked responses)
|
|
6
|
+
* - Basic auth required (503 when not configured)
|
|
7
|
+
* - CSRF protection on state-changing requests (POST/PUT/DELETE/PATCH only)
|
|
8
|
+
* - Rate limiting to prevent brute-force attacks
|
|
9
|
+
* - Credential redaction in config view
|
|
10
|
+
* - CSP meta tag in layout HTML
|
|
11
|
+
*
|
|
12
|
+
* Run with:
|
|
13
|
+
* cd packages/dashboard && npx vitest run src/__tests__/security.repro.test.ts
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
16
|
+
import { createDashboard } from "../server.js";
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Minimal mock DB — every chainable call resolves to []
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function createMockDb() {
|
|
21
|
+
const handler = {
|
|
22
|
+
get(_target, prop) {
|
|
23
|
+
if (prop === "then") {
|
|
24
|
+
return (resolve) => resolve([]);
|
|
25
|
+
}
|
|
26
|
+
return (..._args) => new Proxy(() => { }, handler);
|
|
27
|
+
},
|
|
28
|
+
apply() {
|
|
29
|
+
return new Proxy(() => { }, handler);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
return new Proxy(() => { }, handler);
|
|
33
|
+
}
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Helpers
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
const ROUTES = ["/", "/tokens", "/errors", "/config", "/coordination"];
|
|
38
|
+
/** Build a Basic auth header value. */
|
|
39
|
+
function basicAuthHeader(username, password) {
|
|
40
|
+
return "Basic " + Buffer.from(`${username}:${password}`).toString("base64");
|
|
41
|
+
}
|
|
42
|
+
const VALID_AUTH = { username: "admin", password: "s3cr3t" };
|
|
43
|
+
const VALID_AUTH_HEADER = basicAuthHeader(VALID_AUTH.username, VALID_AUTH.password);
|
|
44
|
+
function makeApp(authEnabled = false) {
|
|
45
|
+
const cfg = {
|
|
46
|
+
db: createMockDb(),
|
|
47
|
+
pipelineConfigs: {},
|
|
48
|
+
repoConfigs: {},
|
|
49
|
+
};
|
|
50
|
+
if (authEnabled) {
|
|
51
|
+
cfg.auth = VALID_AUTH;
|
|
52
|
+
}
|
|
53
|
+
return createDashboard(cfg);
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// 1. Security Headers
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
describe("BEC-103: security headers present on all responses", () => {
|
|
59
|
+
let app;
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
// Use app without auth — headers must be present even on 503 auth-error responses
|
|
62
|
+
app = makeApp();
|
|
63
|
+
});
|
|
64
|
+
it.each(ROUTES)("GET %s — X-Content-Type-Options: nosniff header is present", async (route) => {
|
|
65
|
+
const res = await app.request(route);
|
|
66
|
+
expect(res.headers.get("x-content-type-options")).toBe("nosniff");
|
|
67
|
+
});
|
|
68
|
+
it.each(ROUTES)("GET %s — X-Frame-Options: DENY header is present", async (route) => {
|
|
69
|
+
const res = await app.request(route);
|
|
70
|
+
expect(res.headers.get("x-frame-options")).toBe("DENY");
|
|
71
|
+
});
|
|
72
|
+
it.each(ROUTES)("GET %s — Content-Security-Policy header is present", async (route) => {
|
|
73
|
+
const res = await app.request(route);
|
|
74
|
+
const csp = res.headers.get("content-security-policy");
|
|
75
|
+
expect(csp).not.toBeNull();
|
|
76
|
+
// Must restrict scripts to 'self' and https://unpkg.com only
|
|
77
|
+
expect(csp).toContain("default-src 'self'");
|
|
78
|
+
expect(csp).toContain("script-src 'self' https://unpkg.com");
|
|
79
|
+
});
|
|
80
|
+
it.each(ROUTES)("GET %s — X-XSS-Protection: 0 header is present", async (route) => {
|
|
81
|
+
const res = await app.request(route);
|
|
82
|
+
expect(res.headers.get("x-xss-protection")).toBe("0");
|
|
83
|
+
});
|
|
84
|
+
it.each(ROUTES)("GET %s — Referrer-Policy header is present", async (route) => {
|
|
85
|
+
const res = await app.request(route);
|
|
86
|
+
expect(res.headers.get("referrer-policy")).toBe("strict-origin-when-cross-origin");
|
|
87
|
+
});
|
|
88
|
+
it.each(ROUTES)("GET %s — Permissions-Policy header is present", async (route) => {
|
|
89
|
+
const res = await app.request(route);
|
|
90
|
+
const pp = res.headers.get("permissions-policy");
|
|
91
|
+
expect(pp).not.toBeNull();
|
|
92
|
+
expect(pp).toContain("camera=()");
|
|
93
|
+
expect(pp).toContain("microphone=()");
|
|
94
|
+
expect(pp).toContain("geolocation=()");
|
|
95
|
+
});
|
|
96
|
+
it.each(ROUTES)("GET %s — Strict-Transport-Security header is present", async (route) => {
|
|
97
|
+
const res = await app.request(route);
|
|
98
|
+
const hsts = res.headers.get("strict-transport-security");
|
|
99
|
+
expect(hsts).not.toBeNull();
|
|
100
|
+
expect(hsts).toContain("max-age=");
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// 2. Authentication is required, not optional
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
describe("BEC-103 fix: basic auth is required, not optional", () => {
|
|
107
|
+
it("dashboard returns 503 when no credentials are configured", async () => {
|
|
108
|
+
const app = makeApp(false); // no auth configured
|
|
109
|
+
const res = await app.request("/");
|
|
110
|
+
// Fixed: server blocks all access and prompts to configure auth
|
|
111
|
+
expect(res.status).toBe(503);
|
|
112
|
+
const body = await res.text();
|
|
113
|
+
expect(body).toContain("DASHBOARD_USER");
|
|
114
|
+
});
|
|
115
|
+
it("unauthenticated request to config route returns 503 (not config data)", async () => {
|
|
116
|
+
const appWithConfig = createDashboard({
|
|
117
|
+
db: createMockDb(),
|
|
118
|
+
pipelineConfigs: {
|
|
119
|
+
"auto-implement": {
|
|
120
|
+
name: "Auto Implement",
|
|
121
|
+
stages: ["triage", "implement"],
|
|
122
|
+
model: "claude-opus-4-6",
|
|
123
|
+
maxTokens: 100000,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
repoConfigs: {
|
|
127
|
+
"my-repo": {
|
|
128
|
+
url: "https://github-token:ghp_SECRET@github.com/org/repo.git",
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
// no auth configured — should block all access
|
|
132
|
+
});
|
|
133
|
+
const res = await appWithConfig.request("/config");
|
|
134
|
+
// Fixed: auth required — no config data exposed to unauthenticated requests
|
|
135
|
+
expect(res.status).toBe(503);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// 3. CSRF protection for state-changing requests
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
describe("BEC-103: CSRF / HX-Request validation on state-changing requests", () => {
|
|
142
|
+
it("GET /runs/feed is accessible without HX-Request header (GET is safe by design)", async () => {
|
|
143
|
+
const app = makeApp(true);
|
|
144
|
+
// GET requests don't need CSRF protection — only POST/PUT/DELETE/PATCH do
|
|
145
|
+
const res = await app.request("/runs/feed", {
|
|
146
|
+
headers: { Authorization: VALID_AUTH_HEADER },
|
|
147
|
+
});
|
|
148
|
+
expect(res.status).toBe(200);
|
|
149
|
+
});
|
|
150
|
+
it("GET /coordination/feed accessible from any origin (GET requests are safe)", async () => {
|
|
151
|
+
const app = makeApp(true);
|
|
152
|
+
// Origin check only applies to state-changing requests (POST/PUT/DELETE/PATCH)
|
|
153
|
+
const res = await app.request("/coordination/feed", {
|
|
154
|
+
headers: {
|
|
155
|
+
Authorization: VALID_AUTH_HEADER,
|
|
156
|
+
Origin: "https://evil.example.com",
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
// GET requests are safe — no origin block on read-only endpoints
|
|
160
|
+
expect(res.status).toBe(200);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
// 4. Rate limiting prevents brute-force
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
describe("BEC-103: rate limiting prevents brute-force attacks", () => {
|
|
167
|
+
it("rapid unauthenticated requests eventually trigger 429", async () => {
|
|
168
|
+
const app = makeApp(true); // auth enabled — brute-force surface
|
|
169
|
+
let tooManyRequests = false;
|
|
170
|
+
for (let i = 0; i < 20; i++) {
|
|
171
|
+
const res = await app.request("/", {
|
|
172
|
+
headers: { Authorization: "Basic " + btoa("admin:wrong") },
|
|
173
|
+
});
|
|
174
|
+
if (res.status === 429) {
|
|
175
|
+
tooManyRequests = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Rate limiting kicks in after RATE_LIMIT_MAX requests per window
|
|
180
|
+
expect(tooManyRequests).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// 5. Config view credentials are redacted (fixed: was a vulnerability)
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
describe("BEC-103 fix: config view redacts sensitive credentials", () => {
|
|
187
|
+
it("repo URL containing embedded credentials is redacted in config view", async () => {
|
|
188
|
+
// Credentials embedded in repo URLs must be stripped before display.
|
|
189
|
+
const sensitiveUrl = "https://x-access-token:ghp_SUPERSECRET123@github.com/org/repo.git";
|
|
190
|
+
const appWithSecret = createDashboard({
|
|
191
|
+
db: createMockDb(),
|
|
192
|
+
pipelineConfigs: {},
|
|
193
|
+
repoConfigs: {
|
|
194
|
+
"secret-repo": { url: sensitiveUrl },
|
|
195
|
+
},
|
|
196
|
+
auth: VALID_AUTH, // auth required to reach config route
|
|
197
|
+
});
|
|
198
|
+
const res = await appWithSecret.request("/config", {
|
|
199
|
+
headers: { Authorization: VALID_AUTH_HEADER },
|
|
200
|
+
});
|
|
201
|
+
expect(res.status).toBe(200);
|
|
202
|
+
const html = await res.text();
|
|
203
|
+
// After fix: embedded token must NOT appear in the rendered HTML
|
|
204
|
+
expect(html).not.toContain("ghp_SUPERSECRET123");
|
|
205
|
+
// Redaction marker should be visible instead
|
|
206
|
+
expect(html).toContain("[redacted]");
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// 6. Error information leakage
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
describe("BEC-103: error responses do not expose internal paths", () => {
|
|
213
|
+
it("404 for unknown run does not expose internal stack trace", async () => {
|
|
214
|
+
const app = makeApp(true);
|
|
215
|
+
const res = await app.request("/runs/nonexistent-run-id-12345", {
|
|
216
|
+
headers: { Authorization: VALID_AUTH_HEADER },
|
|
217
|
+
});
|
|
218
|
+
// Check that internal file paths are not exposed in error responses
|
|
219
|
+
const body = await res.text();
|
|
220
|
+
const internalPathPatterns = [
|
|
221
|
+
/\/var\/agent-runs/,
|
|
222
|
+
/node_modules/,
|
|
223
|
+
/\.ts:\d+:\d+/, // TypeScript stack trace lines
|
|
224
|
+
/at Object\.\<anonymous\>/, // JS stack frames
|
|
225
|
+
];
|
|
226
|
+
for (const pattern of internalPathPatterns) {
|
|
227
|
+
expect(pattern.test(body)).toBe(false);
|
|
228
|
+
}
|
|
229
|
+
expect(res.status).toBe(404);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
// 7. CSP meta tag in layout HTML
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
describe("BEC-103 fix: layout HTML includes CSP meta tag", () => {
|
|
236
|
+
it("layout HTML includes a Content-Security-Policy meta tag", async () => {
|
|
237
|
+
const app = makeApp(true);
|
|
238
|
+
const res = await app.request("/", {
|
|
239
|
+
headers: { Authorization: VALID_AUTH_HEADER },
|
|
240
|
+
});
|
|
241
|
+
expect(res.status).toBe(200);
|
|
242
|
+
const html = await res.text();
|
|
243
|
+
// CSP meta tag is present in the rendered HTML
|
|
244
|
+
expect(html.includes('http-equiv="Content-Security-Policy"')).toBe(true);
|
|
245
|
+
expect(html).toContain("default-src 'self'");
|
|
246
|
+
expect(html).toContain("script-src 'self' https://unpkg.com");
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
//# sourceMappingURL=security.repro.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.repro.test.js","sourceRoot":"","sources":["../../src/__tests__/security.repro.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAwB,MAAM,cAAc,CAAC;AAGrE,8EAA8E;AAC9E,wDAAwD;AACxD,8EAA8E;AAC9E,SAAS,YAAY;IACnB,MAAM,OAAO,GAAsB;QACjC,GAAG,CAAC,OAAO,EAAE,IAAI;YACf,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,OAAyB,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,OAAO,CAAC,GAAG,KAAY,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3D,CAAC;QACD,KAAK;YACH,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;IACF,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,CAAkB,CAAC;AACvD,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAEvE,uCAAuC;AACvC,SAAS,eAAe,CAAC,QAAgB,EAAE,QAAgB;IACzD,OAAO,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC7D,MAAM,iBAAiB,GAAG,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;AAEpF,SAAS,OAAO,CAAC,WAAW,GAAG,KAAK;IAClC,MAAM,GAAG,GAAoB;QAC3B,EAAE,EAAE,YAAY,EAAE;QAClB,eAAe,EAAE,EAAE;QACnB,WAAW,EAAE,EAAE;KAChB,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;IACxB,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAC9E,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,IAAI,GAAuC,CAAC;IAE5C,UAAU,CAAC,GAAG,EAAE;QACd,kFAAkF;QAClF,GAAG,GAAG,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,4DAA4D,EAC5D,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,kDAAkD,EAClD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,oDAAoD,EACpD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,6DAA6D;QAC7D,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;IAC/D,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,gDAAgD,EAChD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxD,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,4CAA4C,EAC5C,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAC7C,iCAAiC,CAClC,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,+CAA+C,EAC/C,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACzC,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CACb,sDAAsD,EACtD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAC9E,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB;QACjD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,gEAAgE;QAChE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,aAAa,GAAG,eAAe,CAAC;YACpC,EAAE,EAAE,YAAY,EAAE;YAClB,eAAe,EAAE;gBACf,gBAAgB,EAAE;oBAChB,IAAI,EAAE,gBAAgB;oBACtB,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;oBAC/B,KAAK,EAAE,iBAAiB;oBACxB,SAAS,EAAE,MAAM;iBACX;aACT;YACD,WAAW,EAAE;gBACX,SAAS,EAAE;oBACT,GAAG,EAAE,yDAAyD;iBACxD;aACT;YACD,+CAA+C;SAChD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACnD,4EAA4E;QAC5E,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAC9E,QAAQ,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAChF,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,0EAA0E;QAC1E,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE;YAC1C,OAAO,EAAE,EAAE,aAAa,EAAE,iBAAiB,EAAE;SAC9C,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,+EAA+E;QAC/E,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE;YAClD,OAAO,EAAE;gBACP,aAAa,EAAE,iBAAiB;gBAChC,MAAM,EAAE,0BAA0B;aACnC;SACF,CAAC,CAAC;QACH,iEAAiE;QACjE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,wCAAwC;AACxC,8EAA8E;AAC9E,QAAQ,CAAC,qDAAqD,EAAE,GAAG,EAAE;IACnE,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,qCAAqC;QAChE,IAAI,eAAe,GAAG,KAAK,CAAC;QAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;gBACjC,OAAO,EAAE,EAAE,aAAa,EAAE,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE;aAC3D,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,eAAe,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAC9E,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACtE,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,qEAAqE;QACrE,MAAM,YAAY,GAChB,mEAAmE,CAAC;QAEtE,MAAM,aAAa,GAAG,eAAe,CAAC;YACpC,EAAE,EAAE,YAAY,EAAE;YAClB,eAAe,EAAE,EAAE;YACnB,WAAW,EAAE;gBACX,aAAa,EAAE,EAAE,GAAG,EAAE,YAAY,EAAS;aAC5C;YACD,IAAI,EAAE,UAAU,EAAE,sCAAsC;SACzD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE;YACjD,OAAO,EAAE,EAAE,aAAa,EAAE,iBAAiB,EAAE;SAC9C,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAE9B,iEAAiE;QACjE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACjD,6CAA6C;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAC9E,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACrE,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE;YAC9D,OAAO,EAAE,EAAE,aAAa,EAAE,iBAAiB,EAAE;SAC9C,CAAC,CAAC;QACH,oEAAoE;QACpE,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,oBAAoB,GAAG;YAC3B,mBAAmB;YACnB,cAAc;YACd,cAAc,EAAE,+BAA+B;YAC/C,0BAA0B,EAAE,kBAAkB;SAC/C,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,oBAAoB,EAAE,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAC9E,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;YACjC,OAAO,EAAE,EAAE,aAAa,EAAE,iBAAiB,EAAE;SAC9C,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAE9B,+CAA+C;QAC/C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":""}
|