mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-14 16:46:07 +00:00
fix(settings): require re-2FA confirmation for sensitive setting changes (#5610)
* fix(settings): require server-side 2fa for sensitive changes * fix(lint): group third-party imports separately from local (goimports) golangci-lint goimports flagged setting.go and setting_security_test.go because xlzd/gotp and gorm.io/gorm were mixed into the github.com/mhsanaei/3x-ui local-prefix group. Move them into the third-party group so the local imports stand alone.
This commit is contained in:
@@ -7,6 +7,8 @@ import { AllSetting } from '@/models/setting';
|
||||
import { AllSettingSchema, type AllSettingInput } from '@/schemas/setting';
|
||||
import { keys } from '@/api/queryKeys';
|
||||
|
||||
type SettingSavePayload = Partial<AllSetting> & Record<string, unknown>;
|
||||
|
||||
async function fetchAllSetting(): Promise<AllSettingInput | null> {
|
||||
const msg = await HttpUtil.post('/panel/api/setting/all', undefined, { silent: true });
|
||||
if (!msg?.success) throw new Error(msg?.msg || 'Failed to fetch settings');
|
||||
@@ -42,19 +44,21 @@ export function useAllSettings() {
|
||||
}, []);
|
||||
|
||||
const saveMut = useMutation({
|
||||
mutationFn: async (next: AllSetting): Promise<Msg<unknown>> => {
|
||||
const body = AllSettingSchema.partial().safeParse(next);
|
||||
mutationFn: async (next: SettingSavePayload): Promise<Msg<unknown>> => {
|
||||
const payload = { ...next };
|
||||
const body = AllSettingSchema.partial().safeParse(payload);
|
||||
if (!body.success) {
|
||||
console.warn('[zod] setting/update body failed validation', body.error.issues);
|
||||
}
|
||||
return HttpUtil.post('/panel/api/setting/update', body.success ? body.data : next);
|
||||
return HttpUtil.post('/panel/api/setting/update', body.success ? { ...payload, ...body.data } : payload);
|
||||
},
|
||||
onSuccess: (msg) => {
|
||||
if (msg?.success) queryClient.invalidateQueries({ queryKey: keys.settings.all() });
|
||||
},
|
||||
});
|
||||
|
||||
const saveAll = useCallback(() => saveMut.mutateAsync(draft), [saveMut, draft]);
|
||||
const saveAll = useCallback(() => saveMut.mutateAsync({ ...draft }), [saveMut, draft]);
|
||||
const savePayload = useCallback((payload: SettingSavePayload) => saveMut.mutateAsync(payload), [saveMut]);
|
||||
const saveDisabled = useMemo(() => server.equals(draft), [server, draft]);
|
||||
|
||||
return {
|
||||
@@ -65,5 +69,6 @@ export function useAllSettings() {
|
||||
setSpinning: setExtraSpinning,
|
||||
saveDisabled,
|
||||
saveAll,
|
||||
savePayload,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user