mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-23 15:31:53 +08:00
refactor: use yup custom validator
This commit is contained in:
+107
-24
@@ -1,27 +1,110 @@
|
||||
import * as z from "zod";
|
||||
import { TFunction } from "i18next";
|
||||
import { useCallback } from "react";
|
||||
import { FieldErrors } from "react-hook-form";
|
||||
import * as yup from "yup";
|
||||
import { ShellToolType } from "./shell";
|
||||
|
||||
export const formSchema = z.object({
|
||||
server: z.string().min(1),
|
||||
targetJdkVersion: z.optional(z.string()),
|
||||
debug: z.optional(z.boolean()),
|
||||
bypassJavaModule: z.optional(z.boolean()),
|
||||
shellClassName: z.string().optional(),
|
||||
shellTool: z.string().min(1),
|
||||
shellType: z.string().min(1),
|
||||
urlPattern: z.optional(z.string()),
|
||||
godzillaPass: z.optional(z.string()),
|
||||
godzillaKey: z.optional(z.string()),
|
||||
behinderPass: z.optional(z.string()),
|
||||
antSwordPass: z.optional(z.string()),
|
||||
commandParamName: z.optional(z.string()),
|
||||
implementationClass: z.optional(z.string()),
|
||||
headerName: z.optional(z.string()),
|
||||
headerValue: z.optional(z.string()),
|
||||
injectorClassName: z.optional(z.string()),
|
||||
packingMethod: z.string().min(1),
|
||||
shrink: z.optional(z.boolean()),
|
||||
shellClassBase64: z.optional(z.string()),
|
||||
encryptor: z.optional(z.string()),
|
||||
export const formSchema = yup.object({
|
||||
server: yup.string().required().min(1),
|
||||
targetJdkVersion: yup.string().optional(),
|
||||
debug: yup.boolean().optional(),
|
||||
bypassJavaModule: yup.boolean().optional(),
|
||||
shellClassName: yup.string().optional(),
|
||||
shellTool: yup.string().required().min(1),
|
||||
shellType: yup.string().required().min(1),
|
||||
urlPattern: yup.string().optional(),
|
||||
godzillaPass: yup.string().optional(),
|
||||
godzillaKey: yup.string().optional(),
|
||||
behinderPass: yup.string().optional(),
|
||||
antSwordPass: yup.string().optional(),
|
||||
commandParamName: yup.string().optional(),
|
||||
implementationClass: yup.string().optional(),
|
||||
headerName: yup.string().optional(),
|
||||
headerValue: yup.string().optional(),
|
||||
injectorClassName: yup.string().optional(),
|
||||
packingMethod: yup.string().required().min(1),
|
||||
shrink: yup.boolean().optional(),
|
||||
shellClassBase64: yup.string().optional(),
|
||||
encryptor: yup.string().optional(),
|
||||
});
|
||||
|
||||
export type FormSchema = z.infer<typeof formSchema>;
|
||||
interface ValidationResult {
|
||||
values: FormSchema;
|
||||
errors: FieldErrors<FormSchema>;
|
||||
}
|
||||
|
||||
const urlPatternIsNeeded = (shellType: string) => {
|
||||
return (
|
||||
shellType.endsWith("Servlet") ||
|
||||
shellType.endsWith("ControllerHandler") ||
|
||||
shellType === "HandlerMethod" ||
|
||||
shellType === "HandlerFunction" ||
|
||||
shellType.endsWith("WebSocket")
|
||||
);
|
||||
};
|
||||
|
||||
const isInvalidUrl = (urlPattern: string | undefined) =>
|
||||
urlPattern === "/" || urlPattern === "/*" || !urlPattern?.startsWith("/") || !urlPattern;
|
||||
|
||||
export const useYupValidationResolver = (validationSchema: yup.ObjectSchema<any>, t: TFunction) =>
|
||||
useCallback(
|
||||
async (data: FormSchema): Promise<ValidationResult> => {
|
||||
try {
|
||||
const values = (await validationSchema.validate(data, {
|
||||
abortEarly: false,
|
||||
})) as FormSchema;
|
||||
|
||||
const urlPattern: keyof FormSchema = "urlPattern";
|
||||
const shellClassBase64: keyof FormSchema = "shellClassBase64";
|
||||
const errors = {} as any;
|
||||
|
||||
if (urlPatternIsNeeded(values?.shellType) && isInvalidUrl(values?.urlPattern)) {
|
||||
errors[urlPattern] = {
|
||||
type: "custom",
|
||||
message: t("tips.specificUrlPattern"),
|
||||
};
|
||||
}
|
||||
if (values.shellTool === ShellToolType.Custom && !values.shellClassBase64) {
|
||||
errors[shellClassBase64] = {
|
||||
type: "custom",
|
||||
message: t("tips.customShellClass"),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
values,
|
||||
errors,
|
||||
};
|
||||
} catch (errors) {
|
||||
if (errors instanceof yup.ValidationError) {
|
||||
return {
|
||||
values: {} as FormSchema,
|
||||
errors: errors.inner.reduce(
|
||||
(allErrors, currentError) => ({
|
||||
// biome-ignore lint/performance/noAccumulatingSpread: <explanation>
|
||||
...allErrors,
|
||||
[currentError.path as keyof FormSchema]: {
|
||||
type: currentError.type ?? "validation",
|
||||
message: currentError.message,
|
||||
},
|
||||
}),
|
||||
{},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
values: {} as FormSchema,
|
||||
errors: {
|
||||
server: {
|
||||
type: "unknown",
|
||||
message: "An unexpected validation error occurred",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
[validationSchema, t],
|
||||
);
|
||||
|
||||
export type FormSchema = yup.InferType<typeof formSchema>;
|
||||
|
||||
Reference in New Issue
Block a user