fix(phone-number): call callback on password reset (#8046)

This commit is contained in:
Joél Solano
2026-02-19 06:19:45 +01:00
committed by GitHub
parent 830bfd251a
commit 8fe651400a
2 changed files with 85 additions and 2 deletions

View File

@@ -506,6 +506,82 @@ describe("reset password session revocation", async () => {
});
});
describe("reset password onPasswordReset callback", async () => {
let otp = "";
let resetOtp = "";
const onPasswordReset = vi.fn();
const { client, sessionSetter } = await getTestInstance(
{
emailAndPassword: {
enabled: true,
onPasswordReset,
},
plugins: [
phoneNumber({
async sendOTP({ code }) {
otp = code;
},
sendPasswordResetOTP(data) {
resetOtp = data.code;
},
signUpOnVerification: {
getTempEmail(phoneNumber) {
return `temp-${phoneNumber}`;
},
},
}),
],
},
{
clientOptions: {
plugins: [phoneNumberClient()],
},
},
);
const testPhoneNumber = "+251911999888";
it("should call onPasswordReset after phone number password reset", async () => {
const headers = new Headers();
await client.phoneNumber.sendOtp({
phoneNumber: testPhoneNumber,
});
await client.phoneNumber.verify(
{
phoneNumber: testPhoneNumber,
code: otp,
},
{
onSuccess: sessionSetter(headers),
},
);
await client.phoneNumber.requestPasswordReset({
phoneNumber: testPhoneNumber,
});
const res = await client.phoneNumber.resetPassword({
phoneNumber: testPhoneNumber,
otp: resetOtp,
newPassword: "new-password-123",
});
expect(res.error).toBe(null);
expect(res.data?.status).toBe(true);
expect(onPasswordReset).toHaveBeenCalledOnce();
expect(onPasswordReset).toHaveBeenCalledWith(
expect.objectContaining({
user: expect.objectContaining({
phoneNumber: testPhoneNumber,
}),
}),
expect.anything(),
);
});
});
describe("phone number verification requirement", async () => {
let otp = "";
const { client } = await getTestInstance(

View File

@@ -6,7 +6,7 @@ import { setSessionCookie } from "../../cookies";
import { generateRandomString } from "../../crypto/random";
import { parseUserInput } from "../../db";
import { parseUserOutput } from "../../db/schema";
import type { Account, User } from "../../types";
import type { Account } from "../../types";
import { getDate } from "../../utils/date";
import { PHONE_NUMBER_ERROR_CODES } from "./error-codes";
import type { PhoneNumberOptions, UserWithPhoneNumber } from "./types";
@@ -811,7 +811,7 @@ export const resetPasswordPhoneNumber = (opts: RequiredPhoneNumberOptions) =>
);
}
const userRes = await ctx.context.adapter.findOne<
User & { account: Account[] | undefined }
UserWithPhoneNumber & { account: Account[] | undefined }
>({
model: "user",
where: [
@@ -862,6 +862,13 @@ export const resetPasswordPhoneNumber = (opts: RequiredPhoneNumberOptions) =>
verification.id,
);
if (ctx.context.options.emailAndPassword?.onPasswordReset) {
await ctx.context.options.emailAndPassword.onPasswordReset(
{ user },
ctx.request,
);
}
if (ctx.context.options.emailAndPassword?.revokeSessionsOnPasswordReset) {
await ctx.context.internalAdapter.deleteSessions(user.id);
}