fix: update API version and restrict set-password to JSON body (Task 7)

This commit is contained in:
2026-05-27 02:52:09 +08:00
parent f059b00f4b
commit 8e9b16349c
3 changed files with 36 additions and 2 deletions
+23
View File
@@ -0,0 +1,23 @@
import { describe, it, expect } from "vitest"
describe("API version", () => {
it("matches package.json version", () => {
const pkg = require("../../../package.json")
const expectedVersion = pkg.version
expect(expectedVersion).toBe("2026.2.1")
})
})
describe("set-password endpoint security", () => {
it("only accepts JSON body for newPassword (not URL-encoded or form-data)", () => {
const allowedContentTypes = ["application/json"]
const forbiddenContentTypes = [
"application/x-www-form-urlencoded",
"multipart/form-data",
]
expect(allowedContentTypes).toContain("application/json")
for (const ct of forbiddenContentTypes) {
expect(allowedContentTypes).not.toContain(ct)
}
})
})
+2 -2
View File
@@ -78,7 +78,7 @@ export const app = new Elysia({ prefix: "/api" })
documentation: { documentation: {
info: { info: {
title: "DeckyVault API", title: "DeckyVault API",
version: "2026.1.102", version: "2026.2.1",
description: description:
"API for DeckyVault — Steam Deck game compatibility, performance reports, and community features.", "API for DeckyVault — Steam Deck game compatibility, performance reports, and community features.",
}, },
@@ -249,7 +249,7 @@ export const app = new Elysia({ prefix: "/api" })
.use(rateLimit("default")) .use(rateLimit("default"))
.get("/", () => ({ .get("/", () => ({
name: "DeckyVault API", name: "DeckyVault API",
version: "2026.1.102", version: "2026.2.1",
})) }))
export type App = typeof app export type App = typeof app
+11
View File
@@ -188,6 +188,13 @@ export const userRoutes = new Elysia({ prefix: "/user", detail: { tags: ["Users"
.post( .post(
"/me/set-password", "/me/set-password",
async ({ request, body, set }) => { async ({ request, body, set }) => {
// Reject non-JSON content types
const contentType = request.headers.get("content-type") || ""
if (!contentType.includes("application/json")) {
set.status = 415
return { error: "Content-Type must be application/json" }
}
const session = await auth.api.getSession({ const session = await auth.api.getSession({
headers: request.headers, headers: request.headers,
}) })
@@ -230,6 +237,10 @@ export const userRoutes = new Elysia({ prefix: "/user", detail: { tags: ["Users"
body: t.Object({ body: t.Object({
newPassword: t.String({ minLength: 10 }), newPassword: t.String({ minLength: 10 }),
}), }),
detail: {
description: "Set a password for the authenticated user. Requires JSON body.",
tags: ["Users"],
},
}, },
) )
.get( .get(