feat(api-docs): generate response examples from Go structs; fix SS2022 PSK regen (#4996)

Stop hand-writing OpenAPI response examples, which kept drifting from the real payloads (clients/traffic missing fields, inbounds/list exposing userId which is json:"-", the fictional inbound-443 tag instead of the real in-<port>-<transport> form).

tools/openapigen now emits frontend/src/generated/examples.ts: a per-struct example instance built from type defaults, validate oneof/min bounds, and example: struct tags, with nested-ref expansion and a cycle guard. build-openapi.mjs composes the {success,obj} envelope from it for any endpoint annotated with responseSchema (+ responseSchemaArray for lists); the hand-written response is dropped for those. Service DTOs InboundOption/ApiTokenView/ProbeResultUI are added to the walker.

#4996: client password regeneration now produces a valid Shadowsocks 2022 PSK (correct base64 length per cipher) when an SS2022 inbound is attached, in both the single and bulk client forms; backend surfaces ssMethod on /inbounds/options so the UI can pick the right length.

Also: Swagger UI persists the Authorization token across reloads (persistAuthorization).
This commit is contained in:
MHSanaei
2026-06-06 14:58:15 +02:00
parent 483952cfa0
commit 83799d71b0
22 changed files with 924 additions and 143 deletions
+11 -4
View File
@@ -183,15 +183,22 @@ export class RandomUtil {
}
static randomShadowsocksPassword(method: string = '2022-blake3-aes-256-gcm'): string {
let length = 32;
if (method === '2022-blake3-aes-128-gcm') {
length = 16;
}
const length = method === '2022-blake3-aes-128-gcm' ? 16 : 32;
const array = new Uint8Array(length);
window.crypto.getRandomValues(array);
return Base64.alternativeEncode(String.fromCharCode(...array));
}
static isShadowsocks2022Password(password: string, method: string): boolean {
if (!method || method.substring(0, 4) !== '2022') return true;
const expected = method === '2022-blake3-aes-128-gcm' ? 16 : 32;
try {
return window.atob(password).length === expected;
} catch {
return false;
}
}
static randomBase64(length: number = 16): string {
const array = new Uint8Array(length);
window.crypto.getRandomValues(array);