fix: open-api doc generation failing, post patch and delete not exported (#1565)

This commit is contained in:
Meier Lukas
2024-11-28 20:21:29 +01:00
committed by GitHub
parent 44e2105a8c
commit 2d7efc3ffa
4 changed files with 58 additions and 30 deletions

View File

@@ -17,6 +17,11 @@ const handlerAsync = async (req: NextRequest) => {
const { ua } = userAgent(req); const { ua } = userAgent(req);
const session: Session | null = await getSessionOrDefaultFromHeadersAsync(apiKeyHeaderValue, ipAddress, ua); const session: Session | null = await getSessionOrDefaultFromHeadersAsync(apiKeyHeaderValue, ipAddress, ua);
// Fallback to JSON if no content type is set
if (!req.headers.has("Content-Type")) {
req.headers.set("Content-Type", "application/json");
}
return createOpenApiFetchHandler({ return createOpenApiFetchHandler({
req, req,
endpoint: "/", endpoint: "/",
@@ -82,4 +87,10 @@ const getSessionOrDefaultFromHeadersAsync = async (
return await createSessionAsync(db, apiKeyFromDb.user); return await createSessionAsync(db, apiKeyFromDb.user);
}; };
export { handlerAsync as GET, handlerAsync as POST }; export {
handlerAsync as GET,
handlerAsync as POST,
handlerAsync as PUT,
handlerAsync as DELETE,
handlerAsync as PATCH,
};

View File

@@ -503,7 +503,7 @@ export const userRouter = createTRPCRouter({
}), }),
}); });
const createUserAsync = async (db: Database, input: z.infer<typeof validation.user.baseCreate>) => { const createUserAsync = async (db: Database, input: Omit<z.infer<typeof validation.user.baseCreate>, "groupIds">) => {
const salt = await createSaltAsync(); const salt = await createSaltAsync();
const hashedPassword = await hashPasswordAsync(input.password, salt); const hashedPassword = await hashPasswordAsync(input.password, salt);

View File

@@ -0,0 +1,16 @@
import { expect, test, vi } from "vitest";
import { openApiDocument } from "../open-api";
vi.mock("@homarr/auth", () => ({}));
test("OpenAPI documentation should be generated", () => {
// Arrange
const base = "https://homarr.dev";
// Act
const act = () => openApiDocument(base);
// Assert
expect(act).not.toThrow();
});

View File

@@ -37,43 +37,43 @@ const passwordSchema = z
}, },
); );
const confirmPasswordRefine = [ const addConfirmPasswordRefinement = <TObj extends { password: string; confirmPassword: string }>(
(data: { password: string; confirmPassword: string }) => data.password === data.confirmPassword, // eslint-disable-next-line @typescript-eslint/no-explicit-any
{ schema: z.ZodObject<any, "strip", z.ZodTypeAny, TObj>,
) => {
return schema.refine((data) => data.password === data.confirmPassword, {
path: ["confirmPassword"], path: ["confirmPassword"],
params: createCustomErrorParams({ params: createCustomErrorParams({
key: "passwordsDoNotMatch", key: "passwordsDoNotMatch",
params: {}, params: {},
}), }),
}, });
// eslint-disable-next-line @typescript-eslint/no-explicit-any };
] satisfies [(args: any) => boolean, unknown];
const baseCreateUserSchema = z const baseCreateUserSchema = z.object({
.object({ username: usernameSchema,
username: usernameSchema, password: passwordSchema,
password: passwordSchema, confirmPassword: z.string(),
confirmPassword: z.string(), email: z.string().email().or(z.string().length(0).optional()),
email: z.string().email().or(z.string().length(0).optional()), groupIds: z.array(z.string()),
}) });
.refine(confirmPasswordRefine[0], confirmPasswordRefine[1]);
const createUserSchema = baseCreateUserSchema.and(z.object({ groupIds: z.array(z.string()) })); const createUserSchema = addConfirmPasswordRefinement(baseCreateUserSchema);
const initUserSchema = baseCreateUserSchema; const initUserSchema = addConfirmPasswordRefinement(baseCreateUserSchema.omit({ groupIds: true }));
const signInSchema = z.object({ const signInSchema = z.object({
name: z.string().min(1), name: z.string().min(1),
password: z.string().min(1), password: z.string().min(1),
}); });
const registrationSchema = z const registrationSchema = addConfirmPasswordRefinement(
.object({ z.object({
username: usernameSchema, username: usernameSchema,
password: passwordSchema, password: passwordSchema,
confirmPassword: z.string(), confirmPassword: z.string(),
}) }),
.refine(confirmPasswordRefine[0], confirmPasswordRefine[1]); );
const registrationSchemaApi = registrationSchema.and( const registrationSchemaApi = registrationSchema.and(
z.object({ z.object({
@@ -94,15 +94,16 @@ const editProfileSchema = z.object({
.nullable(), .nullable(),
}); });
const changePasswordSchema = z const baseChangePasswordSchema = z.object({
.object({ previousPassword: z.string().min(1),
previousPassword: z.string().min(1), password: passwordSchema,
password: passwordSchema, confirmPassword: z.string(),
confirmPassword: z.string(), userId: z.string(),
}) });
.refine(confirmPasswordRefine[0], confirmPasswordRefine[1]);
const changePasswordApiSchema = changePasswordSchema.and(z.object({ userId: z.string() })); const changePasswordSchema = addConfirmPasswordRefinement(baseChangePasswordSchema.omit({ userId: true }));
const changePasswordApiSchema = addConfirmPasswordRefinement(baseChangePasswordSchema);
const changeHomeBoardSchema = z.object({ const changeHomeBoardSchema = z.object({
homeBoardId: z.string().min(1), homeBoardId: z.string().min(1),