fix(auth): verify reauth passwords against credential account
This commit is contained in:
parent
4a06891db9
commit
068eed4a0f
2 changed files with 64 additions and 1 deletions
63
app/server/modules/auth/__tests__/helpers.test.ts
Normal file
63
app/server/modules/auth/__tests__/helpers.test.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { db } from "~/server/db/db";
|
||||
import { account, usersTable } from "~/server/db/schema";
|
||||
import { createUser, randomId, randomSlug } from "~/test/helpers/user-org";
|
||||
import { verifyUserPassword } from "../helpers";
|
||||
|
||||
const { verifyPassword } = vi.hoisted(() => ({
|
||||
verifyPassword: vi.fn(async ({ hash }: { hash: string }) => hash === "credential-password-hash"),
|
||||
}));
|
||||
|
||||
vi.mock("better-auth/crypto", () => ({
|
||||
verifyPassword,
|
||||
}));
|
||||
|
||||
async function createAccount({
|
||||
password,
|
||||
providerId,
|
||||
userId,
|
||||
}: {
|
||||
password: string | null;
|
||||
providerId: string;
|
||||
userId: string;
|
||||
}) {
|
||||
await db.insert(account).values({
|
||||
id: randomId(),
|
||||
accountId: randomSlug("account"),
|
||||
providerId,
|
||||
userId,
|
||||
password,
|
||||
});
|
||||
}
|
||||
|
||||
describe("verifyUserPassword", () => {
|
||||
beforeEach(async () => {
|
||||
verifyPassword.mockClear();
|
||||
await db.delete(account);
|
||||
await db.delete(usersTable);
|
||||
});
|
||||
|
||||
test("verifies against the credential account when the user also has SSO accounts", async () => {
|
||||
const userId = await createUser(`${randomSlug("user")}@example.com`);
|
||||
await createAccount({ userId, providerId: "oidc-acme", password: null });
|
||||
await createAccount({ userId, providerId: "credential", password: "credential-password-hash" });
|
||||
|
||||
const result = await verifyUserPassword({ userId, password: "correct-password" });
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(verifyPassword).toHaveBeenCalledWith({
|
||||
password: "correct-password",
|
||||
hash: "credential-password-hash",
|
||||
});
|
||||
});
|
||||
|
||||
test("returns false when the user has no credential password account", async () => {
|
||||
const userId = await createUser(`${randomSlug("user")}@example.com`);
|
||||
await createAccount({ userId, providerId: "oidc-acme", password: null });
|
||||
|
||||
const result = await verifyUserPassword({ userId, password: "correct-password" });
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(verifyPassword).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
@ -8,7 +8,7 @@ type PasswordVerificationBody = {
|
|||
|
||||
export const verifyUserPassword = async ({ password, userId }: PasswordVerificationBody) => {
|
||||
const userAccount = await db.query.account.findFirst({
|
||||
where: { userId },
|
||||
where: { AND: [{ userId }, { providerId: "credential" }] },
|
||||
});
|
||||
|
||||
if (!userAccount || !userAccount.password) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue