feat: add Keycloak authentication
This commit is contained in:
@@ -22,14 +22,53 @@ const browserHttpUrl = z
|
||||
}
|
||||
});
|
||||
|
||||
const runtimeConfigSchema = z.object({
|
||||
TJWATER_MAPBOX_ACCESS_TOKEN: z.string().default(""),
|
||||
TJWATER_MAP_URL: browserHttpUrl.default("https://geoserver.waternetwork.cn/geoserver"),
|
||||
TJWATER_GEOSERVER_WORKSPACE: z.string().trim().min(1).default("tjwater"),
|
||||
TJWATER_AGENT_API_BASE_URL: browserHttpUrl.default("http://127.0.0.1:8787"),
|
||||
TJWATER_ENABLE_DEV_PANEL: runtimeBoolean(false),
|
||||
TJWATER_ENABLE_MSW: runtimeBoolean(false)
|
||||
});
|
||||
const keycloakIssuer = z
|
||||
.string()
|
||||
.trim()
|
||||
.default("")
|
||||
.superRefine((value, context) => {
|
||||
if (!value) return;
|
||||
const parsed = browserHttpUrl.safeParse(value);
|
||||
if (!parsed.success) {
|
||||
context.addIssue({ code: z.ZodIssueCode.custom, message: "Keycloak issuer 必须是安全的 HTTP(S) 地址" });
|
||||
return;
|
||||
}
|
||||
const url = new URL(value);
|
||||
if (url.search || !/\/realms\/[^/]+\/?$/.test(url.pathname)) {
|
||||
context.addIssue({ code: z.ZodIssueCode.custom, message: "Keycloak issuer 必须指向具体 Realm" });
|
||||
}
|
||||
})
|
||||
.transform((value) => value.replace(/\/+$/, ""));
|
||||
|
||||
const runtimeConfigSchema = z
|
||||
.object({
|
||||
TJWATER_AUTH_MODE: z.enum(["required", "disabled"]).default("required"),
|
||||
TJWATER_KEYCLOAK_ISSUER: keycloakIssuer,
|
||||
TJWATER_KEYCLOAK_CLIENT_ID: z.string().trim().default("next-tjwater"),
|
||||
TJWATER_MAPBOX_ACCESS_TOKEN: z.string().default(""),
|
||||
TJWATER_MAP_URL: browserHttpUrl.default("https://geoserver.waternetwork.cn/geoserver"),
|
||||
TJWATER_GEOSERVER_WORKSPACE: z.string().trim().min(1).default("tjwater"),
|
||||
TJWATER_AGENT_API_BASE_URL: browserHttpUrl.default("http://127.0.0.1:8787"),
|
||||
TJWATER_ENABLE_DEV_PANEL: runtimeBoolean(false),
|
||||
TJWATER_ENABLE_MSW: runtimeBoolean(false)
|
||||
})
|
||||
.superRefine((config, context) => {
|
||||
if (config.TJWATER_AUTH_MODE !== "required") return;
|
||||
if (!config.TJWATER_KEYCLOAK_ISSUER) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["TJWATER_KEYCLOAK_ISSUER"],
|
||||
message: "启用认证时必须配置 Keycloak issuer"
|
||||
});
|
||||
}
|
||||
if (!config.TJWATER_KEYCLOAK_CLIENT_ID) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["TJWATER_KEYCLOAK_CLIENT_ID"],
|
||||
message: "启用认证时必须配置 Keycloak client ID"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
declare global {
|
||||
var __TJWATER_CONFIG__: unknown;
|
||||
|
||||
Reference in New Issue
Block a user