@urateam/dashboard 0.1.4 → 0.1.5

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.
Files changed (115) hide show
  1. package/dist/__tests__/audit.test.d.ts +2 -0
  2. package/dist/__tests__/audit.test.d.ts.map +1 -0
  3. package/dist/__tests__/audit.test.js +219 -0
  4. package/dist/__tests__/audit.test.js.map +1 -0
  5. package/dist/__tests__/auth-routes.test.d.ts +2 -0
  6. package/dist/__tests__/auth-routes.test.d.ts.map +1 -0
  7. package/dist/__tests__/auth-routes.test.js +116 -0
  8. package/dist/__tests__/auth-routes.test.js.map +1 -0
  9. package/dist/__tests__/bootstrap-integration.test.d.ts +2 -0
  10. package/dist/__tests__/bootstrap-integration.test.d.ts.map +1 -0
  11. package/dist/__tests__/bootstrap-integration.test.js +75 -0
  12. package/dist/__tests__/bootstrap-integration.test.js.map +1 -0
  13. package/dist/__tests__/cost-chart.test.d.ts +2 -0
  14. package/dist/__tests__/cost-chart.test.d.ts.map +1 -0
  15. package/dist/__tests__/cost-chart.test.js +51 -0
  16. package/dist/__tests__/cost-chart.test.js.map +1 -0
  17. package/dist/__tests__/cost.test.d.ts +2 -0
  18. package/dist/__tests__/cost.test.d.ts.map +1 -0
  19. package/dist/__tests__/cost.test.js +197 -0
  20. package/dist/__tests__/cost.test.js.map +1 -0
  21. package/dist/__tests__/helpers/license.d.ts +8 -0
  22. package/dist/__tests__/helpers/license.d.ts.map +1 -0
  23. package/dist/__tests__/helpers/license.js +71 -0
  24. package/dist/__tests__/helpers/license.js.map +1 -0
  25. package/dist/__tests__/rbac-middleware.test.d.ts +2 -0
  26. package/dist/__tests__/rbac-middleware.test.d.ts.map +1 -0
  27. package/dist/__tests__/rbac-middleware.test.js +59 -0
  28. package/dist/__tests__/rbac-middleware.test.js.map +1 -0
  29. package/dist/__tests__/retry-route.test.d.ts +2 -0
  30. package/dist/__tests__/retry-route.test.d.ts.map +1 -0
  31. package/dist/__tests__/retry-route.test.js +115 -0
  32. package/dist/__tests__/retry-route.test.js.map +1 -0
  33. package/dist/__tests__/sso-integration.test.d.ts +2 -0
  34. package/dist/__tests__/sso-integration.test.d.ts.map +1 -0
  35. package/dist/__tests__/sso-integration.test.js +91 -0
  36. package/dist/__tests__/sso-integration.test.js.map +1 -0
  37. package/dist/__tests__/sso-middleware.test.d.ts +2 -0
  38. package/dist/__tests__/sso-middleware.test.d.ts.map +1 -0
  39. package/dist/__tests__/sso-middleware.test.js +66 -0
  40. package/dist/__tests__/sso-middleware.test.js.map +1 -0
  41. package/dist/__tests__/users-routes.test.d.ts +2 -0
  42. package/dist/__tests__/users-routes.test.d.ts.map +1 -0
  43. package/dist/__tests__/users-routes.test.js +127 -0
  44. package/dist/__tests__/users-routes.test.js.map +1 -0
  45. package/dist/middleware/rbac.d.ts +4 -0
  46. package/dist/middleware/rbac.d.ts.map +1 -0
  47. package/dist/middleware/rbac.js +21 -0
  48. package/dist/middleware/rbac.js.map +1 -0
  49. package/dist/middleware/sso.d.ts +9 -0
  50. package/dist/middleware/sso.d.ts.map +1 -0
  51. package/dist/middleware/sso.js +47 -0
  52. package/dist/middleware/sso.js.map +1 -0
  53. package/dist/routes/audit.d.ts +4 -0
  54. package/dist/routes/audit.d.ts.map +1 -0
  55. package/dist/routes/audit.js +123 -0
  56. package/dist/routes/audit.js.map +1 -0
  57. package/dist/routes/auth.d.ts +10 -0
  58. package/dist/routes/auth.d.ts.map +1 -0
  59. package/dist/routes/auth.js +105 -0
  60. package/dist/routes/auth.js.map +1 -0
  61. package/dist/routes/config.d.ts.map +1 -1
  62. package/dist/routes/config.js +4 -2
  63. package/dist/routes/config.js.map +1 -1
  64. package/dist/routes/coordination.d.ts.map +1 -1
  65. package/dist/routes/coordination.js +5 -3
  66. package/dist/routes/coordination.js.map +1 -1
  67. package/dist/routes/cost.d.ts +10 -0
  68. package/dist/routes/cost.d.ts.map +1 -0
  69. package/dist/routes/cost.js +104 -0
  70. package/dist/routes/cost.js.map +1 -0
  71. package/dist/routes/errors.d.ts.map +1 -1
  72. package/dist/routes/errors.js +4 -2
  73. package/dist/routes/errors.js.map +1 -1
  74. package/dist/routes/runs.d.ts +9 -1
  75. package/dist/routes/runs.d.ts.map +1 -1
  76. package/dist/routes/runs.js +82 -9
  77. package/dist/routes/runs.js.map +1 -1
  78. package/dist/routes/tokens.d.ts.map +1 -1
  79. package/dist/routes/tokens.js +4 -2
  80. package/dist/routes/tokens.js.map +1 -1
  81. package/dist/routes/users.d.ts +8 -0
  82. package/dist/routes/users.d.ts.map +1 -0
  83. package/dist/routes/users.js +64 -0
  84. package/dist/routes/users.js.map +1 -0
  85. package/dist/server.d.ts +13 -1
  86. package/dist/server.d.ts.map +1 -1
  87. package/dist/server.js +65 -7
  88. package/dist/server.js.map +1 -1
  89. package/dist/static/style.css +648 -0
  90. package/dist/views/audit.d.ts +29 -0
  91. package/dist/views/audit.d.ts.map +1 -0
  92. package/dist/views/audit.js +144 -0
  93. package/dist/views/audit.js.map +1 -0
  94. package/dist/views/cost.d.ts +28 -0
  95. package/dist/views/cost.d.ts.map +1 -0
  96. package/dist/views/cost.js +173 -0
  97. package/dist/views/cost.js.map +1 -0
  98. package/dist/views/forbidden.d.ts +7 -0
  99. package/dist/views/forbidden.d.ts.map +1 -0
  100. package/dist/views/forbidden.js +18 -0
  101. package/dist/views/forbidden.js.map +1 -0
  102. package/dist/views/layout.d.ts +11 -1
  103. package/dist/views/layout.d.ts.map +1 -1
  104. package/dist/views/layout.js +12 -18
  105. package/dist/views/layout.js.map +1 -1
  106. package/dist/views/run-detail.d.ts +1 -1
  107. package/dist/views/run-detail.d.ts.map +1 -1
  108. package/dist/views/run-detail.js +6 -1
  109. package/dist/views/run-detail.js.map +1 -1
  110. package/dist/views/users.d.ts +16 -0
  111. package/dist/views/users.d.ts.map +1 -0
  112. package/dist/views/users.js +44 -0
  113. package/dist/views/users.js.map +1 -0
  114. package/package.json +7 -5
  115. package/LICENSE +0 -27
@@ -0,0 +1,197 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { generateKeyPairSync, sign } from "node:crypto";
3
+ import { createDashboard } from "../server.js";
4
+ import { createDb } from "@urateam/core";
5
+ import { pipelineRuns, stageRuns } from "@urateam/core/dist/db/schema.js";
6
+ import { _resetLicenseCache } from "@urateam/core/dist/license.js";
7
+ // ---------------- license test helper (inlined from audit.test.ts) ----------------
8
+ function b64url(buf) {
9
+ return buf
10
+ .toString("base64")
11
+ .replace(/\+/g, "-")
12
+ .replace(/\//g, "_")
13
+ .replace(/=+$/, "");
14
+ }
15
+ function makeJwt(privateKey, payload) {
16
+ const header = { alg: "EdDSA", typ: "JWT" };
17
+ const headerB64 = b64url(Buffer.from(JSON.stringify(header)));
18
+ const payloadB64 = b64url(Buffer.from(JSON.stringify(payload)));
19
+ const signingInput = `${headerB64}.${payloadB64}`;
20
+ const sig = sign(null, Buffer.from(signingInput), privateKey);
21
+ return `${signingInput}.${b64url(sig)}`;
22
+ }
23
+ let savedPublicKey;
24
+ let savedEnv;
25
+ async function installEnterpriseLicense() {
26
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519");
27
+ const publicKeyB64 = Buffer.from(publicKey.export({ format: "der", type: "spki" })).toString("base64");
28
+ const mod = await import("@urateam/core/dist/license-public-key.js");
29
+ if (savedPublicKey === undefined) {
30
+ savedPublicKey = mod
31
+ .LICENSE_PUBLIC_KEY_DER_B64;
32
+ }
33
+ Object.defineProperty(mod, "LICENSE_PUBLIC_KEY_DER_B64", {
34
+ value: publicKeyB64,
35
+ writable: true,
36
+ configurable: true,
37
+ });
38
+ const now = Math.floor(Date.now() / 1000);
39
+ const jwt = makeJwt(privateKey, {
40
+ iss: "urateams.com",
41
+ sub: "cust_test",
42
+ tier: "enterprise",
43
+ seats: 25,
44
+ iat: now,
45
+ exp: now + 86_400,
46
+ });
47
+ if (savedEnv === undefined)
48
+ savedEnv = process.env.URATEAM_LICENSE_KEY;
49
+ process.env.URATEAM_LICENSE_KEY = jwt;
50
+ _resetLicenseCache();
51
+ }
52
+ async function restoreLicense() {
53
+ if (savedPublicKey !== undefined) {
54
+ const mod = await import("@urateam/core/dist/license-public-key.js");
55
+ Object.defineProperty(mod, "LICENSE_PUBLIC_KEY_DER_B64", {
56
+ value: savedPublicKey,
57
+ writable: true,
58
+ configurable: true,
59
+ });
60
+ savedPublicKey = undefined;
61
+ }
62
+ if (savedEnv === undefined) {
63
+ delete process.env.URATEAM_LICENSE_KEY;
64
+ }
65
+ else {
66
+ process.env.URATEAM_LICENSE_KEY = savedEnv;
67
+ savedEnv = undefined;
68
+ }
69
+ _resetLicenseCache();
70
+ }
71
+ function basicAuthHeader(u, p) {
72
+ return "Basic " + Buffer.from(`${u}:${p}`).toString("base64");
73
+ }
74
+ const AUTH = { Authorization: basicAuthHeader("admin", "secret") };
75
+ const testCosts = {
76
+ modelPricing: {
77
+ "claude-sonnet-4-6": { inputPerMillion: 3, outputPerMillion: 15 },
78
+ },
79
+ hourlyEngRate: 50,
80
+ timeSavedPerPrDefault: 4,
81
+ };
82
+ const testPipelineConfigs = {
83
+ "quick-fix": { profile: { model: "claude-sonnet-4-6" } },
84
+ };
85
+ async function seedCompletedRun(db) {
86
+ const now = new Date();
87
+ const started = new Date(now.getTime() - 60_000);
88
+ await db.insert(pipelineRuns).values({
89
+ id: "run-cost-1",
90
+ issueId: "BEC-1",
91
+ issueTitle: "seed",
92
+ pipelineKey: "quick-fix",
93
+ repoUrl: "https://github.com/acme/api",
94
+ status: "completed",
95
+ startedAt: started,
96
+ completedAt: now,
97
+ linearTeamId: "T1",
98
+ });
99
+ await db.insert(stageRuns).values({
100
+ id: "stage-cost-1",
101
+ pipelineRunId: "run-cost-1",
102
+ stage: "implement",
103
+ status: "completed",
104
+ startedAt: started,
105
+ completedAt: now,
106
+ inputTokens: 100_000,
107
+ outputTokens: 50_000,
108
+ });
109
+ }
110
+ // ---------------- tests ----------------
111
+ describe("cost route — unlicensed", () => {
112
+ beforeEach(async () => {
113
+ await restoreLicense();
114
+ });
115
+ it("returns 404 for GET /cost when feature is not licensed", async () => {
116
+ const db = await createDb({ connectionString: ":memory:" });
117
+ const app = createDashboard({
118
+ db,
119
+ pipelineConfigs: testPipelineConfigs,
120
+ repoConfigs: {},
121
+ costs: testCosts,
122
+ auth: { username: "admin", password: "secret" },
123
+ });
124
+ const res = await app.request("/cost", { headers: AUTH });
125
+ expect(res.status).toBe(404);
126
+ });
127
+ it("returns 404 for GET /cost/page when feature is not licensed", async () => {
128
+ const db = await createDb({ connectionString: ":memory:" });
129
+ const app = createDashboard({
130
+ db,
131
+ pipelineConfigs: testPipelineConfigs,
132
+ repoConfigs: {},
133
+ costs: testCosts,
134
+ auth: { username: "admin", password: "secret" },
135
+ });
136
+ const res = await app.request("/cost/page", { headers: AUTH });
137
+ expect(res.status).toBe(404);
138
+ });
139
+ it("returns 404 for GET /cost/export.csv when feature is not licensed", async () => {
140
+ const db = await createDb({ connectionString: ":memory:" });
141
+ const app = createDashboard({
142
+ db,
143
+ pipelineConfigs: testPipelineConfigs,
144
+ repoConfigs: {},
145
+ costs: testCosts,
146
+ auth: { username: "admin", password: "secret" },
147
+ });
148
+ const res = await app.request("/cost/export.csv", { headers: AUTH });
149
+ expect(res.status).toBe(404);
150
+ });
151
+ });
152
+ describe("cost route — licensed (enterprise)", () => {
153
+ beforeEach(async () => {
154
+ await installEnterpriseLicense();
155
+ });
156
+ afterEach(async () => {
157
+ await restoreLicense();
158
+ });
159
+ it("GET /cost returns 200 and renders summary with seeded run", async () => {
160
+ const db = await createDb({ connectionString: ":memory:" });
161
+ await seedCompletedRun(db);
162
+ const app = createDashboard({
163
+ db,
164
+ pipelineConfigs: testPipelineConfigs,
165
+ repoConfigs: {},
166
+ costs: testCosts,
167
+ auth: { username: "admin", password: "secret" },
168
+ });
169
+ const res = await app.request("/cost", { headers: AUTH });
170
+ expect(res.status).toBe(200);
171
+ const html = await res.text();
172
+ expect(html).toContain("PRs merged");
173
+ expect(html).toContain("quick-fix");
174
+ expect(html).toMatch(/\$\d/);
175
+ expect(html).toContain("Cost");
176
+ });
177
+ it("GET /cost/export.csv returns 200 text/csv with header row and disposition", async () => {
178
+ const db = await createDb({ connectionString: ":memory:" });
179
+ await seedCompletedRun(db);
180
+ const app = createDashboard({
181
+ db,
182
+ pipelineConfigs: testPipelineConfigs,
183
+ repoConfigs: {},
184
+ costs: testCosts,
185
+ auth: { username: "admin", password: "secret" },
186
+ });
187
+ const res = await app.request("/cost/export.csv", { headers: AUTH });
188
+ expect(res.status).toBe(200);
189
+ expect(res.headers.get("content-type") ?? "").toContain("text/csv");
190
+ const disposition = res.headers.get("content-disposition") ?? "";
191
+ expect(disposition).toMatch(/attachment; filename="cost-\d{4}-\d{2}-\d{2}-\d{4}-\d{2}-\d{2}\.csv"/);
192
+ const body = await res.text();
193
+ expect(body).toContain("completed_at,run_id,issue_id,pipeline_key,linear_team_id,repo_url,input_tokens,output_tokens,dollars,time_saved_hours");
194
+ expect(body).toContain("run-cost-1");
195
+ });
196
+ });
197
+ //# sourceMappingURL=cost.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.test.js","sourceRoot":"","sources":["../../src/__tests__/cost.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Install a test license at the requested tier, replacing the embedded
3
+ * public key with a generated one so the JWT verifies. Used by dashboard
4
+ * tests for enterprise-tier features (audit-log, sso).
5
+ */
6
+ export declare function installTestProLicense(tier?: "pro" | "enterprise"): Promise<void>;
7
+ export declare function restoreLicense(): Promise<void>;
8
+ //# sourceMappingURL=license.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/license.ts"],"names":[],"mappings":"AAuBA;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,GAAE,KAAK,GAAG,YAA2B,GACxC,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBpD"}
@@ -0,0 +1,71 @@
1
+ import { generateKeyPairSync, sign } from "node:crypto";
2
+ import { _resetLicenseCache } from "@urateam/core/dist/license.js";
3
+ function b64url(buf) {
4
+ return buf
5
+ .toString("base64")
6
+ .replace(/\+/g, "-")
7
+ .replace(/\//g, "_")
8
+ .replace(/=+$/, "");
9
+ }
10
+ function makeJwt(privateKey, payload) {
11
+ const header = { alg: "EdDSA", typ: "JWT" };
12
+ const headerB64 = b64url(Buffer.from(JSON.stringify(header)));
13
+ const payloadB64 = b64url(Buffer.from(JSON.stringify(payload)));
14
+ const signingInput = `${headerB64}.${payloadB64}`;
15
+ const sig = sign(null, Buffer.from(signingInput), privateKey);
16
+ return `${signingInput}.${b64url(sig)}`;
17
+ }
18
+ let savedPublicKey;
19
+ let savedEnv;
20
+ /**
21
+ * Install a test license at the requested tier, replacing the embedded
22
+ * public key with a generated one so the JWT verifies. Used by dashboard
23
+ * tests for enterprise-tier features (audit-log, sso).
24
+ */
25
+ export async function installTestProLicense(tier = "enterprise") {
26
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519");
27
+ const publicKeyB64 = Buffer.from(publicKey.export({ format: "der", type: "spki" })).toString("base64");
28
+ const mod = await import("@urateam/core/dist/license-public-key.js");
29
+ if (savedPublicKey === undefined) {
30
+ savedPublicKey = mod
31
+ .LICENSE_PUBLIC_KEY_DER_B64;
32
+ }
33
+ Object.defineProperty(mod, "LICENSE_PUBLIC_KEY_DER_B64", {
34
+ value: publicKeyB64,
35
+ writable: true,
36
+ configurable: true,
37
+ });
38
+ const now = Math.floor(Date.now() / 1000);
39
+ const jwt = makeJwt(privateKey, {
40
+ iss: "urateams.com",
41
+ sub: "cust_test",
42
+ tier,
43
+ seats: 25,
44
+ iat: now,
45
+ exp: now + 86_400,
46
+ });
47
+ if (savedEnv === undefined)
48
+ savedEnv = process.env.URATEAM_LICENSE_KEY;
49
+ process.env.URATEAM_LICENSE_KEY = jwt;
50
+ _resetLicenseCache();
51
+ }
52
+ export async function restoreLicense() {
53
+ if (savedPublicKey !== undefined) {
54
+ const mod = await import("@urateam/core/dist/license-public-key.js");
55
+ Object.defineProperty(mod, "LICENSE_PUBLIC_KEY_DER_B64", {
56
+ value: savedPublicKey,
57
+ writable: true,
58
+ configurable: true,
59
+ });
60
+ savedPublicKey = undefined;
61
+ }
62
+ if (savedEnv === undefined) {
63
+ delete process.env.URATEAM_LICENSE_KEY;
64
+ }
65
+ else {
66
+ process.env.URATEAM_LICENSE_KEY = savedEnv;
67
+ savedEnv = undefined;
68
+ }
69
+ _resetLicenseCache();
70
+ }
71
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../../../src/__tests__/helpers/license.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAkB,IAAI,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO,GAAG;SACP,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,OAAO,CAAC,UAAqB,EAAE,OAAe;IACrD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;IAC9D,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,IAAI,cAAkC,CAAC;AACvC,IAAI,QAA4B,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA6B,YAAY;IAEzC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAC9B,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAClD,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,0CAA0C,CAAC,CAAC;IACrE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,cAAc,GAAI,GAA8C;aAC7D,0BAA0B,CAAC;IAChC,CAAC;IACD,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE;QACvD,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE;QAC9B,GAAG,EAAE,cAAc;QACnB,GAAG,EAAE,WAAW;QAChB,IAAI;QACJ,KAAK,EAAE,EAAE;QACT,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,MAAM;KAClB,CAAC,CAAC;IAEH,IAAI,QAAQ,KAAK,SAAS;QAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,GAAG,CAAC;IACtC,kBAAkB,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,0CAA0C,CAAC,CAAC;QACrE,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE;YACvD,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,cAAc,GAAG,SAAS,CAAC;IAC7B,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,QAAQ,CAAC;QAC3C,QAAQ,GAAG,SAAS,CAAC;IACvB,CAAC;IACD,kBAAkB,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rbac-middleware.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac-middleware.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/rbac-middleware.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { Hono } from "hono";
3
+ import { requirePermission } from "../middleware/rbac.js";
4
+ import { installTestProLicense, restoreLicense } from "./helpers/license.js";
5
+ afterEach(async () => {
6
+ await restoreLicense();
7
+ });
8
+ function appWithRoute(permission, role) {
9
+ const app = new Hono();
10
+ app.use("*", async (c, next) => {
11
+ if (role)
12
+ c.set("user", {
13
+ id: "u_1",
14
+ role,
15
+ email: "u@b.com",
16
+ });
17
+ await next();
18
+ });
19
+ app.get("/test",
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ requirePermission(permission), (c) => c.text("ok"));
22
+ return app;
23
+ }
24
+ describe("requirePermission", () => {
25
+ it("unlicensed → no-op, all roles pass", async () => {
26
+ const app = appWithRoute("config.view", "viewer");
27
+ expect((await app.request("/test")).status).toBe(200);
28
+ });
29
+ describe("licensed", () => {
30
+ beforeEach(async () => {
31
+ await installTestProLicense("enterprise");
32
+ });
33
+ it("admin passes runs.view", async () => {
34
+ const res = await appWithRoute("runs.view", "admin").request("/test");
35
+ expect(res.status).toBe(200);
36
+ });
37
+ it("viewer passes runs.view", async () => {
38
+ const res = await appWithRoute("runs.view", "viewer").request("/test");
39
+ expect(res.status).toBe(200);
40
+ });
41
+ it("viewer gets 403 on audit.view", async () => {
42
+ const res = await appWithRoute("audit.view", "viewer").request("/test");
43
+ expect(res.status).toBe(403);
44
+ });
45
+ it("operator gets 403 on config.view", async () => {
46
+ const res = await appWithRoute("config.view", "operator").request("/test");
47
+ expect(res.status).toBe(403);
48
+ });
49
+ it("admin passes config.view", async () => {
50
+ const res = await appWithRoute("config.view", "admin").request("/test");
51
+ expect(res.status).toBe(200);
52
+ });
53
+ it("no session → 401", async () => {
54
+ const res = await appWithRoute("runs.view", undefined).request("/test");
55
+ expect(res.status).toBe(401);
56
+ });
57
+ });
58
+ });
59
+ //# sourceMappingURL=rbac-middleware.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac-middleware.test.js","sourceRoot":"","sources":["../../src/__tests__/rbac-middleware.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retry-route.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-route.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/retry-route.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
+ import { Hono } from "hono";
3
+ import { eq } from "drizzle-orm";
4
+ import { createDb } from "@urateam/core";
5
+ import { pipelineRuns, auditEvents } from "@urateam/core/dist/db/schema.js";
6
+ import { createRunsRouter } from "../routes/runs.js";
7
+ import { installTestProLicense, restoreLicense } from "./helpers/license.js";
8
+ let db;
9
+ beforeEach(async () => {
10
+ db = await createDb({ connectionString: ":memory:" });
11
+ await db.insert(pipelineRuns).values({
12
+ id: "run_1",
13
+ issueId: "BEC-42",
14
+ issueTitle: "fix bug",
15
+ pipelineKey: "auto-implement",
16
+ repoUrl: "https://github.com/acme/api",
17
+ status: "failed",
18
+ startedAt: new Date(),
19
+ completedAt: new Date(),
20
+ errorMessage: "boom",
21
+ });
22
+ });
23
+ afterEach(async () => {
24
+ await restoreLicense();
25
+ });
26
+ function appWith(role, runner = { resume: vi.fn(), start: vi.fn() }) {
27
+ const app = new Hono();
28
+ app.use("*", async (c, next) => {
29
+ if (role) {
30
+ c.set("user", {
31
+ id: "u_1",
32
+ email: "u@b.com",
33
+ role,
34
+ });
35
+ }
36
+ await next();
37
+ });
38
+ app.route("/", createRunsRouter({ db, runner, basePath: "" }));
39
+ return app;
40
+ }
41
+ describe("POST /runs/:id/retry", () => {
42
+ it("unlicensed → 404 even for valid retry requests", async () => {
43
+ // Do NOT install enterprise license
44
+ const runner = { resume: vi.fn(), start: vi.fn() };
45
+ const app = appWith("operator", runner); // operator role set but feature off
46
+ const res = await app.request("/runs/run_1/retry", { method: "POST" });
47
+ expect(res.status).toBe(404);
48
+ expect(runner.resume).not.toHaveBeenCalled();
49
+ });
50
+ describe("licensed", () => {
51
+ beforeEach(async () => {
52
+ await installTestProLicense("enterprise");
53
+ });
54
+ it("viewer → 403", async () => {
55
+ const res = await appWith("viewer").request("/runs/run_1/retry", {
56
+ method: "POST",
57
+ });
58
+ expect(res.status).toBe(403);
59
+ });
60
+ it("operator → 302 redirect, runner.resume called, audit event written", async () => {
61
+ // Give the run a resumePayload so runner.resume is called (not start).
62
+ await db
63
+ .update(pipelineRuns)
64
+ .set({ resumePayload: JSON.stringify({ stageIndex: 1 }) })
65
+ .where(eq(pipelineRuns.id, "run_1"));
66
+ const runner = {
67
+ resume: vi.fn().mockResolvedValue(undefined),
68
+ start: vi.fn(),
69
+ };
70
+ const app = appWith("operator", runner);
71
+ const res = await app.request("/runs/run_1/retry", { method: "POST" });
72
+ expect(res.status).toBe(302);
73
+ expect(runner.resume).toHaveBeenCalledWith("run_1");
74
+ // Give fire-and-forget logAuditEvent a chance to flush
75
+ await new Promise((r) => setTimeout(r, 50));
76
+ const events = await db.select().from(auditEvents);
77
+ const retry = events.find((e) => {
78
+ const p = typeof e.payload === "string" ? JSON.parse(e.payload) : e.payload;
79
+ return (e.eventType === "dashboard.manual_action" && p.action === "retry_run");
80
+ });
81
+ expect(retry).toBeDefined();
82
+ });
83
+ it("admin → 302, runner.resume called (with resumePayload)", async () => {
84
+ await db
85
+ .update(pipelineRuns)
86
+ .set({ resumePayload: JSON.stringify({ stageIndex: 1 }) })
87
+ .where(eq(pipelineRuns.id, "run_1"));
88
+ const runner = {
89
+ resume: vi.fn().mockResolvedValue(undefined),
90
+ start: vi.fn(),
91
+ };
92
+ const app = appWith("admin", runner);
93
+ const res = await app.request("/runs/run_1/retry", { method: "POST" });
94
+ expect(res.status).toBe(302);
95
+ expect(runner.resume).toHaveBeenCalled();
96
+ });
97
+ it("operator retrying a completed run → 409", async () => {
98
+ await db
99
+ .update(pipelineRuns)
100
+ .set({ status: "completed" })
101
+ .where(eq(pipelineRuns.id, "run_1"));
102
+ const res = await appWith("operator").request("/runs/run_1/retry", {
103
+ method: "POST",
104
+ });
105
+ expect(res.status).toBe(409);
106
+ });
107
+ it("operator retrying a non-existent run → 404", async () => {
108
+ const res = await appWith("operator").request("/runs/nope/retry", {
109
+ method: "POST",
110
+ });
111
+ expect(res.status).toBe(404);
112
+ });
113
+ });
114
+ });
115
+ //# sourceMappingURL=retry-route.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-route.test.js","sourceRoot":"","sources":["../../src/__tests__/retry-route.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sso-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sso-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { createDb } from "@urateam/core";
3
+ import { installTestProLicense, restoreLicense } from "./helpers/license.js";
4
+ import { createDashboard } from "../server.js";
5
+ let db;
6
+ const ssoConfig = {
7
+ enabled: true,
8
+ workosApiKey: "sk_test",
9
+ workosClientId: "client_test",
10
+ redirectUri: "https://x/auth/callback",
11
+ sessionDurationHours: 24,
12
+ cookieName: "urateam_session",
13
+ cookieSecure: false,
14
+ stateSigningSecret: "0123456789abcdef0123456789abcdef",
15
+ };
16
+ const stubWorkos = {
17
+ async getAuthorizationUrl(args) {
18
+ return `https://workos.example/auth?state=${args.state}&client=${args.clientId}`;
19
+ },
20
+ async authenticateWithCode(_args) {
21
+ return {
22
+ user: {
23
+ id: "wu_test",
24
+ email: "alice@acme.com",
25
+ firstName: "Alice",
26
+ lastName: "X",
27
+ },
28
+ };
29
+ },
30
+ };
31
+ beforeEach(async () => {
32
+ db = await createDb({ connectionString: ":memory:" });
33
+ });
34
+ afterEach(async () => {
35
+ await restoreLicense();
36
+ });
37
+ describe("server with SSO", () => {
38
+ it("redirects /runs to /auth/login when SSO is licensed and enabled with no cookie", async () => {
39
+ await installTestProLicense("enterprise");
40
+ const app = createDashboard({
41
+ db,
42
+ pipelineConfigs: {},
43
+ repoConfigs: {},
44
+ sso: ssoConfig,
45
+ workos: stubWorkos,
46
+ });
47
+ const res = await app.request("/runs");
48
+ expect(res.status).toBe(302);
49
+ expect(res.headers.get("location")).toContain("/auth/login");
50
+ });
51
+ it("falls back to basic auth when SSO is not licensed even if enabled", async () => {
52
+ await restoreLicense();
53
+ const app = createDashboard({
54
+ db,
55
+ pipelineConfigs: {},
56
+ repoConfigs: {},
57
+ sso: ssoConfig,
58
+ workos: stubWorkos,
59
+ auth: { username: "u", password: "p" },
60
+ });
61
+ const res = await app.request("/runs");
62
+ expect(res.status).toBe(401); // basic auth challenge
63
+ });
64
+ it("uses basic auth when SSO is licensed but disabled", async () => {
65
+ await installTestProLicense("enterprise");
66
+ const app = createDashboard({
67
+ db,
68
+ pipelineConfigs: {},
69
+ repoConfigs: {},
70
+ sso: { ...ssoConfig, enabled: false },
71
+ workos: stubWorkos,
72
+ auth: { username: "u", password: "p" },
73
+ });
74
+ const res = await app.request("/runs");
75
+ expect(res.status).toBe(401);
76
+ });
77
+ it("serves /auth/login (302 to WorkOS) without basic auth when SSO active", async () => {
78
+ await installTestProLicense("enterprise");
79
+ const app = createDashboard({
80
+ db,
81
+ pipelineConfigs: {},
82
+ repoConfigs: {},
83
+ sso: ssoConfig,
84
+ workos: stubWorkos,
85
+ });
86
+ const res = await app.request("/auth/login?next=/runs");
87
+ expect(res.status).toBe(302);
88
+ expect(res.headers.get("location")).toContain("workos.example");
89
+ });
90
+ });
91
+ //# sourceMappingURL=sso-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/sso-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sso-middleware.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso-middleware.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sso-middleware.test.ts"],"names":[],"mappings":""}