Merge branch 'ji' into master
按钮管理「登录参数」两套实现冲突解决——两分支各自独立给跳转按钮加了登录态追加能力, 二者正交、保留两套,互不影响: - master: login_params (JSON 列 login_params_json,从 userInfo 解析,类似轻应用登录参数) - ji: append_auth + auth_token_param + auth_name_param (token 登录时追加 token1+用户名) 迁移 revision 碰撞修复(两分支都用了 20260625_01):重编号为线性链 20260620_02 → 20260625_01 (login_params) → 20260625_02 (auth_params) → 20260625_03 (users_approved) 并同步 column_additions_mysql.sql 注释里的 migration 编号。 前后端 task_buttons(model/sql/memory/router/前端 type·api·admin 页)均保留两套字段; 两份 CLAUDE.md 文档合并为同时记录两种机制。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
58357547c9
44 files changed
+1207
-46
No files matched your search
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 登录白名单「总开关」API 客户端 + React Query hooks。
|
||||
*
|
||||
* 后端:`GET|PUT /api/system-settings/login-whitelist`(admin only)。
|
||||
* 开关本身存系统设置 JSON,即时生效、免重启;逐用户的放行标记走
|
||||
* `core/auth`(`UserListItem.approved` + `setUserApproval`)。
|
||||
*/
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiFetch } from "@/core/api/fetch-client";
|
||||
import { getBackendBaseURL } from "@/core/config";
|
||||
import { OptType, writeYLog } from "@/core/log/y-log";
|
||||
|
||||
const BASE = () => `${getBackendBaseURL()}/api/system-settings/login-whitelist`;
|
||||
|
||||
async function readJson<T>(res: Response, ctx: string): Promise<T> {
|
||||
if (!res.ok) {
|
||||
const data = await res.json().catch(() => null as unknown);
|
||||
const detail =
|
||||
data && typeof data === "object" && "detail" in data
|
||||
? String((data as { detail: unknown }).detail)
|
||||
: `${ctx} failed (${res.status})`;
|
||||
throw new Error(detail);
|
||||
}
|
||||
return (await res.json()) as T;
|
||||
}
|
||||
|
||||
export async function getLoginWhitelistEnabled(): Promise<boolean> {
|
||||
const res = await apiFetch(BASE(), { method: "GET" });
|
||||
const data = await readJson<{ enabled: boolean }>(res, "load login whitelist");
|
||||
return Boolean(data.enabled);
|
||||
}
|
||||
|
||||
export async function setLoginWhitelistEnabled(enabled: boolean): Promise<boolean> {
|
||||
const res = await apiFetch(BASE(), {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ enabled }),
|
||||
});
|
||||
const data = await readJson<{ enabled: boolean }>(res, "save login whitelist");
|
||||
writeYLog({
|
||||
optType: enabled ? OptType.enabled : OptType.disabled,
|
||||
optDetail: `CM助手-全量-白名单管理-${enabled ? "启用" : "停用"}登录白名单`,
|
||||
url: "/api/system-settings/login-whitelist",
|
||||
reqParam: { enabled },
|
||||
});
|
||||
return Boolean(data.enabled);
|
||||
}
|
||||
|
||||
export const LOGIN_WHITELIST_KEY = "login-whitelist-enabled";
|
||||
|
||||
export function useLoginWhitelistEnabled() {
|
||||
return useQuery({
|
||||
queryKey: [LOGIN_WHITELIST_KEY],
|
||||
queryFn: getLoginWhitelistEnabled,
|
||||
refetchOnWindowFocus: false,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
export function useSetLoginWhitelistEnabled() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: setLoginWhitelistEnabled,
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: [LOGIN_WHITELIST_KEY] }),
|
||||
});
|
||||
}
|
||||
@@ -39,6 +39,9 @@ interface ServerButton {
|
||||
id_kind: string;
|
||||
open_mode: string;
|
||||
login_params: ServerLoginParam[];
|
||||
append_auth: boolean;
|
||||
auth_token_param: string;
|
||||
auth_name_param: string;
|
||||
enabled: boolean;
|
||||
sort_order: number;
|
||||
}
|
||||
@@ -63,6 +66,9 @@ function toButton(s: ServerButton): TaskButton {
|
||||
idKind: (s.id_kind as TaskButtonIdKind) ?? "task",
|
||||
openMode: (s.open_mode as TaskButtonOpenMode) ?? "blank",
|
||||
loginParams: (s.login_params ?? []).map(toLoginParam),
|
||||
appendAuth: s.append_auth ?? false,
|
||||
authTokenParam: s.auth_token_param || "token",
|
||||
authNameParam: s.auth_name_param || "username",
|
||||
enabled: s.enabled ?? true,
|
||||
sortOrder: s.sort_order ?? 0,
|
||||
};
|
||||
@@ -84,6 +90,9 @@ function toBody(b: TaskButton): ServerButton {
|
||||
source: p.source,
|
||||
custom_value: p.customValue,
|
||||
})),
|
||||
append_auth: b.appendAuth,
|
||||
auth_token_param: b.authTokenParam,
|
||||
auth_name_param: b.authNameParam,
|
||||
enabled: b.enabled,
|
||||
sort_order: b.sortOrder,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user