mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
fixed verification code, added tests (#259)
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
This commit is contained in:
parent
d8568069bd
commit
8587e87778
@ -84,8 +84,8 @@ export function createVerificationCodeHandler<
|
||||
user: UsersCrud["Admin"]["Read"] | undefined
|
||||
) => Promise<DetailsResponse>) : undefined,
|
||||
}): VerificationCodeHandler<Data, SendCodeExtraOptions, DetailsResponse extends SmartResponse ? true : false, Method> {
|
||||
const createHandler = (type: 'post' | 'check' | 'details') => createSmartRouteHandler({
|
||||
metadata: options.metadata?.[type],
|
||||
const createHandler = (handlerType: 'post' | 'check' | 'details') => createSmartRouteHandler({
|
||||
metadata: options.metadata?.[handlerType],
|
||||
request: yupObject({
|
||||
auth: yupObject({
|
||||
project: adaptSchema.required(),
|
||||
@ -95,9 +95,9 @@ export function createVerificationCodeHandler<
|
||||
code: yupString().required(),
|
||||
// we cast to undefined as a typehack because the types are a bit icky
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
}).concat((type === 'post' ? options.requestBody : undefined) as undefined ?? yupObject({})).required(),
|
||||
}).concat((handlerType === 'post' ? options.requestBody : undefined) as undefined ?? yupObject({})).required(),
|
||||
}),
|
||||
response: type === 'check' ?
|
||||
response: handlerType === 'check' ?
|
||||
yupObject({
|
||||
statusCode: yupNumber().oneOf([200]).required(),
|
||||
bodyType: yupString().oneOf(["json"]).required(),
|
||||
@ -105,7 +105,7 @@ export function createVerificationCodeHandler<
|
||||
"is_code_valid": yupBoolean().oneOf([true]).required(),
|
||||
}).required(),
|
||||
}).required() as yup.ObjectSchema<any> :
|
||||
type === 'details' ?
|
||||
handlerType === 'details' ?
|
||||
options.detailsResponse || throwErr('detailsResponse is required') :
|
||||
options.response,
|
||||
async handler({ body: { code, ...requestBody }, auth }) {
|
||||
@ -134,7 +134,7 @@ export function createVerificationCodeHandler<
|
||||
await options.validate(auth.project, validatedMethod, validatedData, requestBody as any, auth.user as any);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
switch (handlerType) {
|
||||
case 'post': {
|
||||
await prismaClient.verificationCode.update({
|
||||
where: {
|
||||
@ -142,6 +142,7 @@ export function createVerificationCodeHandler<
|
||||
projectId: auth.project.id,
|
||||
code,
|
||||
},
|
||||
type: options.type,
|
||||
},
|
||||
data: {
|
||||
usedAt: new Date(),
|
||||
|
||||
@ -59,3 +59,59 @@ it("each verification code that was already requested can be used exactly once",
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
it("should not allow verify a code that doesn't exist", async ({ expect }) => {
|
||||
await Auth.Password.signUpWithEmail();
|
||||
const response = await niceBackendFetch("/api/v1/contact-channels/verify", {
|
||||
method: "POST",
|
||||
accessType: "client",
|
||||
body: {
|
||||
code: "nonexistentcode",
|
||||
},
|
||||
});
|
||||
expect(response).toMatchInlineSnapshot(`
|
||||
NiceResponse {
|
||||
"status": 404,
|
||||
"body": {
|
||||
"code": "VERIFICATION_CODE_NOT_FOUND",
|
||||
"error": "The verification code does not exist for this project.",
|
||||
},
|
||||
"headers": Headers {
|
||||
"x-stack-known-error": "VERIFICATION_CODE_NOT_FOUND",
|
||||
<some fields may have been hidden>,
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("should not allow verification of a code that is sent from a different endpoint", async ({ expect }) => {
|
||||
await Auth.Otp.sendSignInCode();
|
||||
const mailbox = backendContext.value.mailbox;
|
||||
const messages = await mailbox.fetchMessages();
|
||||
const verifyMessage = messages.find((message) => message.subject.includes("Sign in"));
|
||||
const verificationCode = verifyMessage?.body?.text.match(/http:\/\/localhost:12345\/some-callback-url\?code=([a-zA-Z0-9]+)/)?.[1] ?? throwErr("Verification code not found");
|
||||
|
||||
// Try to verify the magic link code using the contact channels verification endpoint
|
||||
const verifyResponse = await niceBackendFetch("/api/v1/contact-channels/verify", {
|
||||
method: "POST",
|
||||
accessType: "client",
|
||||
body: {
|
||||
code: verificationCode,
|
||||
},
|
||||
});
|
||||
|
||||
// Expect the verification to fail
|
||||
expect(verifyResponse).toMatchInlineSnapshot(`
|
||||
NiceResponse {
|
||||
"status": 404,
|
||||
"body": {
|
||||
"code": "VERIFICATION_CODE_NOT_FOUND",
|
||||
"error": "The verification code does not exist for this project.",
|
||||
},
|
||||
"headers": Headers {
|
||||
"x-stack-known-error": "VERIFICATION_CODE_NOT_FOUND",
|
||||
<some fields may have been hidden>,
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user