mirror of
https://github.com/better-auth/better-auth.git
synced 2026-06-04 21:36:39 -05:00
fix: use object parameters for password verification to clarify hash and password roles
This commit is contained in:
@@ -370,10 +370,10 @@ export const signInEmail = createAuthEndpoint(
|
||||
message: "Unexpected error",
|
||||
});
|
||||
}
|
||||
const validPassword = await ctx.context.password.verify(
|
||||
currentPassword,
|
||||
const validPassword = await ctx.context.password.verify({
|
||||
hash: currentPassword,
|
||||
password,
|
||||
);
|
||||
});
|
||||
if (!validPassword) {
|
||||
ctx.context.logger.error("Invalid password");
|
||||
throw new APIError("UNAUTHORIZED", {
|
||||
|
||||
@@ -191,10 +191,10 @@ export const changePassword = createAuthEndpoint(
|
||||
});
|
||||
}
|
||||
const passwordHash = await ctx.context.password.hash(newPassword);
|
||||
const verify = await ctx.context.password.verify(
|
||||
account.password,
|
||||
currentPassword,
|
||||
);
|
||||
const verify = await ctx.context.password.verify({
|
||||
hash: account.password,
|
||||
password: currentPassword,
|
||||
});
|
||||
if (!verify) {
|
||||
throw new APIError("BAD_REQUEST", {
|
||||
message: "Incorrect password",
|
||||
|
||||
@@ -12,7 +12,7 @@ describe("Password hashing and verification", () => {
|
||||
it("should verify a correct password", async () => {
|
||||
const password = "correctPassword123!";
|
||||
const hash = await hashPassword(password);
|
||||
const isValid = await verifyPassword(hash, password);
|
||||
const isValid = await verifyPassword({ hash, password });
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ describe("Password hashing and verification", () => {
|
||||
const correctPassword = "correctPassword123!";
|
||||
const incorrectPassword = "wrongPassword456!";
|
||||
const hash = await hashPassword(correctPassword);
|
||||
const isValid = await verifyPassword(hash, incorrectPassword);
|
||||
const isValid = await verifyPassword({ hash, password: incorrectPassword });
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
|
||||
@@ -34,15 +34,21 @@ describe("Password hashing and verification", () => {
|
||||
it("should handle long passwords", async () => {
|
||||
const password = "a".repeat(1000);
|
||||
const hash = await hashPassword(password);
|
||||
const isValid = await verifyPassword(hash, password);
|
||||
const isValid = await verifyPassword({ hash, password });
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
|
||||
it("should be case-sensitive", async () => {
|
||||
const password = "CaseSensitivePassword123!";
|
||||
const hash = await hashPassword(password);
|
||||
const isValidLower = await verifyPassword(hash, password.toLowerCase());
|
||||
const isValidUpper = await verifyPassword(hash, password.toUpperCase());
|
||||
const isValidLower = await verifyPassword({
|
||||
hash,
|
||||
password: password.toLowerCase(),
|
||||
});
|
||||
const isValidUpper = await verifyPassword({
|
||||
hash,
|
||||
password: password.toUpperCase(),
|
||||
});
|
||||
expect(isValidLower).toBe(false);
|
||||
expect(isValidUpper).toBe(false);
|
||||
});
|
||||
@@ -50,7 +56,7 @@ describe("Password hashing and verification", () => {
|
||||
it("should handle Unicode characters", async () => {
|
||||
const password = "пароль123!";
|
||||
const hash = await hashPassword(password);
|
||||
const isValid = await verifyPassword(hash, password);
|
||||
const isValid = await verifyPassword({ hash, password });
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,10 @@ export const hashPassword = async (password: string) => {
|
||||
return `${salt}:${encodeHex(key)}`;
|
||||
};
|
||||
|
||||
export const verifyPassword = async (hash: string, password: string) => {
|
||||
export const verifyPassword = async ({
|
||||
hash,
|
||||
password,
|
||||
}: { hash: string; password: string }) => {
|
||||
const [salt, key] = hash.split(":");
|
||||
const targetKey = await generateKey(password, salt!);
|
||||
return constantTimeEqual(targetKey, decodeHex(key!));
|
||||
|
||||
@@ -171,7 +171,7 @@ export type AuthContext = {
|
||||
secondaryStorage: SecondaryStorage | undefined;
|
||||
password: {
|
||||
hash: (password: string) => Promise<string>;
|
||||
verify: (password: string, hash: string) => Promise<boolean>;
|
||||
verify: (data: { password: string; hash: string }) => Promise<boolean>;
|
||||
config: {
|
||||
minPasswordLength: number;
|
||||
maxPasswordLength: number;
|
||||
|
||||
@@ -199,10 +199,10 @@ export const phoneNumber = (options?: {
|
||||
message: "Unexpected error",
|
||||
});
|
||||
}
|
||||
const validPassword = await ctx.context.password.verify(
|
||||
currentPassword,
|
||||
const validPassword = await ctx.context.password.verify({
|
||||
hash: currentPassword,
|
||||
password,
|
||||
);
|
||||
});
|
||||
if (!validPassword) {
|
||||
ctx.context.logger.error("Invalid password");
|
||||
throw new APIError("UNAUTHORIZED", {
|
||||
|
||||
@@ -107,10 +107,10 @@ export const username = () => {
|
||||
message: "Unexpected error",
|
||||
});
|
||||
}
|
||||
const validPassword = await ctx.context.password.verify(
|
||||
currentPassword,
|
||||
ctx.body.password,
|
||||
);
|
||||
const validPassword = await ctx.context.password.verify({
|
||||
hash: currentPassword,
|
||||
password: ctx.body.password,
|
||||
});
|
||||
if (!validPassword) {
|
||||
ctx.context.logger.error("Invalid password");
|
||||
throw new APIError("UNAUTHORIZED", {
|
||||
|
||||
@@ -206,7 +206,7 @@ export interface BetterAuthOptions {
|
||||
*/
|
||||
password?: {
|
||||
hash?: (password: string) => Promise<string>;
|
||||
verify?: (hash: string, password: string) => Promise<boolean>;
|
||||
verify?: (data: { hash: string; password: string }) => Promise<boolean>;
|
||||
};
|
||||
/**
|
||||
* Automatically sign in the user after sign up
|
||||
|
||||
@@ -16,10 +16,10 @@ export async function validatePassword(
|
||||
if (!credentialAccount || !currentPassword) {
|
||||
return false;
|
||||
}
|
||||
const compare = await ctx.context.password.verify(
|
||||
currentPassword,
|
||||
data.password,
|
||||
);
|
||||
const compare = await ctx.context.password.verify({
|
||||
hash: currentPassword,
|
||||
password: data.password,
|
||||
});
|
||||
return compare;
|
||||
}
|
||||
|
||||
@@ -29,15 +29,15 @@ export async function checkPassword(userId: string, c: GenericEndpointContext) {
|
||||
(account) => account.providerId === "credential",
|
||||
);
|
||||
const currentPassword = credentialAccount?.password;
|
||||
if (!credentialAccount || !currentPassword) {
|
||||
if (!credentialAccount || !currentPassword || !c.body.password) {
|
||||
throw new APIError("BAD_REQUEST", {
|
||||
message: "No password credential found",
|
||||
});
|
||||
}
|
||||
const compare = await c.context.password.verify(
|
||||
currentPassword,
|
||||
c.body.password,
|
||||
);
|
||||
const compare = await c.context.password.verify({
|
||||
hash: currentPassword,
|
||||
password: c.body.password,
|
||||
});
|
||||
if (!compare) {
|
||||
throw new APIError("BAD_REQUEST", {
|
||||
message: "Invalid password",
|
||||
|
||||
Reference in New Issue
Block a user