Skip to content

Commit 5004919

Browse files
committed
feat: code rabbit fixes part1
1 parent ceb558a commit 5004919

5 files changed

Lines changed: 40168 additions & 4 deletions

File tree

infrastructure/eid-wallet/src/routes/(app)/ePassport/+page.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@
180180
}
181181
182182
if (!result.session?.sessionId) {
183-
kycError = "Verification did not return a session ID.";
184183
resetKyc();
184+
kycError = "Verification did not return a session ID.";
185185
return;
186186
}
187187
@@ -219,9 +219,9 @@
219219
kycStep = "result";
220220
} catch (err) {
221221
console.error("[KYC] Failed to fetch decision:", err);
222+
resetKyc();
222223
kycError =
223224
"Failed to retrieve verification result. Please try again.";
224-
resetKyc();
225225
setTimeout(() => {
226226
kycError = null;
227227
}, 6000);

infrastructure/evault-core/src/controllers/RecoveryController.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Request, Response } from "express";
22
import { default as Axios } from "axios";
33
import FormData from "form-data";
4+
import { validate as uuidValidate } from "uuid";
45
import type { VerificationService } from "../services/VerificationService";
56

67
const diditClient = Axios.create({ baseURL: "https://verification.didit.me" });
@@ -74,6 +75,11 @@ export class RecoveryController {
7475
if (!diditSessionId) {
7576
return res.status(400).json({ error: "diditSessionId is required" });
7677
}
78+
if (!uuidValidate(diditSessionId)) {
79+
return res.status(400).json({
80+
error: "diditSessionId must be a valid UUID",
81+
});
82+
}
7783

7884
const apiKey = process.env.DIDIT_API_KEY;
7985
if (!apiKey) {
@@ -87,7 +93,7 @@ export class RecoveryController {
8793

8894
try {
8995
const { data: decision } = await diditClient.get(
90-
`/v3/session/${diditSessionId}/decision/`,
96+
`/v3/session/${encodeURIComponent(diditSessionId)}/decision/`,
9197
{ headers: { "x-api-key": apiKey } },
9298
);
9399

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import "reflect-metadata";
2+
import express from "express";
3+
import { AddressInfo } from "node:net";
4+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
5+
import { RecoveryController } from "./RecoveryController";
6+
import { VerificationController } from "./VerificationController";
7+
8+
describe("Session ID validation in controllers", () => {
9+
const previousEnv = {
10+
PROVISIONER_SHARED_SECRET: process.env.PROVISIONER_SHARED_SECRET,
11+
DIDIT_API_KEY: process.env.DIDIT_API_KEY,
12+
PUBLIC_EVAULT_SERVER_URI: process.env.PUBLIC_EVAULT_SERVER_URI,
13+
};
14+
15+
beforeAll(() => {
16+
process.env.PROVISIONER_SHARED_SECRET = "test-shared-secret";
17+
process.env.DIDIT_API_KEY = "test-api-key";
18+
process.env.PUBLIC_EVAULT_SERVER_URI = "https://evault.example.com";
19+
});
20+
21+
afterAll(() => {
22+
process.env.PROVISIONER_SHARED_SECRET = previousEnv.PROVISIONER_SHARED_SECRET;
23+
process.env.DIDIT_API_KEY = previousEnv.DIDIT_API_KEY;
24+
process.env.PUBLIC_EVAULT_SERVER_URI = previousEnv.PUBLIC_EVAULT_SERVER_URI;
25+
});
26+
27+
it("rejects invalid diditSessionId in /recovery/face-search", async () => {
28+
const app = express();
29+
app.use(express.json());
30+
31+
const verificationServiceStub = {
32+
create: async () => ({}),
33+
findByIdAndUpdate: async () => null,
34+
findOne: async () => null,
35+
} as any;
36+
37+
new RecoveryController(verificationServiceStub).registerRoutes(app);
38+
39+
const server = app.listen(0);
40+
const baseUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
41+
42+
try {
43+
const response = await fetch(`${baseUrl}/recovery/face-search`, {
44+
method: "POST",
45+
headers: { "Content-Type": "application/json" },
46+
body: JSON.stringify({ diditSessionId: "../etc/passwd" }),
47+
});
48+
const body = await response.json();
49+
50+
expect(response.status).toBe(400);
51+
expect(body.error).toContain("valid UUID");
52+
} finally {
53+
await new Promise<void>((resolve, reject) => {
54+
server.close((error) => {
55+
if (error) reject(error);
56+
else resolve();
57+
});
58+
});
59+
}
60+
});
61+
62+
it("rejects invalid sessionId in /verification/decision/:sessionId", async () => {
63+
const app = express();
64+
app.use(express.json());
65+
66+
const verificationServiceStub = {
67+
findById: async () => null,
68+
findOne: async () => null,
69+
create: async () => ({}),
70+
findByIdAndUpdate: async () => null,
71+
} as any;
72+
73+
new VerificationController(verificationServiceStub).registerRoutes(app);
74+
75+
const server = app.listen(0);
76+
const baseUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
77+
78+
try {
79+
const response = await fetch(
80+
`${baseUrl}/verification/decision/not-a-uuid`,
81+
{
82+
method: "GET",
83+
headers: {
84+
"x-shared-secret": "test-shared-secret",
85+
},
86+
},
87+
);
88+
const body = await response.json();
89+
90+
expect(response.status).toBe(400);
91+
expect(body.error).toContain("valid UUID");
92+
} finally {
93+
await new Promise<void>((resolve, reject) => {
94+
server.close((error) => {
95+
if (error) reject(error);
96+
else resolve();
97+
});
98+
});
99+
}
100+
});
101+
});

infrastructure/evault-core/src/controllers/VerificationController.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Request, Response } from "express";
22
import { default as Axios } from "axios";
3+
import { validate as uuidValidate } from "uuid";
34
import { VerificationService } from "../services/VerificationService";
45
import type { ProvisioningService } from "../services/ProvisioningService";
56

@@ -123,13 +124,18 @@ export class VerificationController {
123124
app.get("/verification/decision/:sessionId", async (req: Request, res: Response) => {
124125
if (!requireSharedSecret(req, res)) return;
125126
const { sessionId } = req.params;
127+
if (!uuidValidate(sessionId)) {
128+
return res.status(400).json({
129+
error: "sessionId must be a valid UUID",
130+
});
131+
}
126132
const apiKey = process.env.DIDIT_API_KEY;
127133
if (!apiKey) {
128134
return res.status(500).json({ error: "DIDIT_API_KEY not configured" });
129135
}
130136
try {
131137
const { data } = await diditClient.get(
132-
`/v3/session/${sessionId}/decision/`,
138+
`/v3/session/${encodeURIComponent(sessionId)}/decision/`,
133139
{ headers: { "x-api-key": apiKey } },
134140
);
135141
return res.json(data);

0 commit comments

Comments
 (0)