mirror of
https://github.com/rustfs/console.git
synced 2026-08-29 03:52:28 +08:00
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import test from "node:test"
|
|
import assert from "node:assert/strict"
|
|
import { redactRequestOptionsForLog } from "../../lib/api-request-log"
|
|
|
|
const loadApiClient = () => import(new URL("../../lib/api-client.ts", import.meta.url).href)
|
|
|
|
test("ApiClient does not mutate request options and preserves existing query parameters", async () => {
|
|
const { ApiClient } = await loadApiClient()
|
|
const urls: string[] = []
|
|
const transport = {
|
|
fetch: async (input: string | Request) => {
|
|
urls.push(String(input))
|
|
return Response.json({ ok: true })
|
|
},
|
|
}
|
|
const client = new ApiClient(transport, { baseUrl: "https://console.test/api" })
|
|
const options = { params: { page: "2" }, headers: { "X-Request": "one" } }
|
|
|
|
await client.get("/objects?prefix=photos", options)
|
|
await client.get("/objects?prefix=photos", options)
|
|
|
|
assert.deepEqual(options, { params: { page: "2" }, headers: { "X-Request": "one" } })
|
|
assert.deepEqual(urls, [
|
|
"https://console.test/api/objects?prefix=photos&page=2",
|
|
"https://console.test/api/objects?prefix=photos&page=2",
|
|
])
|
|
})
|
|
|
|
test("ApiClient rejects 401 and 403 responses after invoking global handlers", async () => {
|
|
const { ApiClient } = await loadApiClient()
|
|
const handled: number[] = []
|
|
const errorHandler = {
|
|
handle401: async () => {
|
|
handled.push(401)
|
|
},
|
|
handle403: async () => {
|
|
handled.push(403)
|
|
},
|
|
handleServerError: async () => {},
|
|
handleByStatus: async () => {},
|
|
}
|
|
const statuses = [401, 403]
|
|
const client = new ApiClient(
|
|
{
|
|
fetch: async () => {
|
|
const status = statuses.shift() ?? 500
|
|
return Response.json({ message: `HTTP ${status}` }, { status })
|
|
},
|
|
},
|
|
{ errorHandler },
|
|
)
|
|
|
|
await assert.rejects(client.get("https://console.test/unauthorized"), { message: "HTTP 401", status: 401 })
|
|
await assert.rejects(client.get("https://console.test/forbidden"), { message: "HTTP 403", status: 403 })
|
|
assert.deepEqual(handled, [401, 403])
|
|
})
|
|
|
|
test("ApiClient preserves an explicitly resolved same-origin admin path", async () => {
|
|
const { ApiClient } = await loadApiClient()
|
|
const urls: string[] = []
|
|
const client = new ApiClient(
|
|
{
|
|
fetch: async (input: string | Request) => {
|
|
urls.push(String(input))
|
|
return Response.json({ ok: true })
|
|
},
|
|
},
|
|
{ baseUrl: "https://console.test/rustfs/admin/v3" },
|
|
)
|
|
|
|
await client.get(client.resolveUrl("/rustfs/admin/v4/cluster/snapshot"))
|
|
|
|
assert.deepEqual(urls, ["https://console.test/rustfs/admin/v4/cluster/snapshot"])
|
|
})
|
|
|
|
test("ApiClient redacts sensitive headers and request bodies from development logs", () => {
|
|
const redacted = redactRequestOptionsForLog({
|
|
headers: { Authorization: "Bearer header-secret", Cookie: "session=cookie-secret" },
|
|
body: JSON.stringify({
|
|
password: "body-secret",
|
|
secretKey: "tier-secret-key",
|
|
profile: { apiKey: "nested-secret" },
|
|
creds: '{"private_key":"gcs-private-key"}',
|
|
}),
|
|
})
|
|
|
|
const serialized = JSON.stringify(redacted)
|
|
assert.doesNotMatch(
|
|
serialized,
|
|
/body-secret|tier-secret-key|nested-secret|header-secret|cookie-secret|gcs-private-key/,
|
|
)
|
|
assert.match(serialized, /\[REDACTED\]/)
|
|
})
|