Password verification functionality for comparing plain text passwords against bcrypt hashes. Provides both synchronous and asynchronous APIs with optional progress tracking for time-intensive operations.
Synchronously tests a password against a bcrypt hash.
/**
* Synchronously tests a password against a hash.
* @param password Password to test
* @param hash Hash to test against
* @returns true if matching, otherwise false
*/
function compareSync(password: string, hash: string): boolean;Usage Examples:
import { compareSync } from "bcryptjs";
// Basic password verification
const hash = "$2b$10$N9qo8uLOickgx2ZMRZoMye2Z8WSdtXvKLhXfV.O/JZ4MYxvmq4dS6";
const isValid = compareSync("myPassword", hash);
console.log(isValid); // true or false
// Login verification function
function verifyLogin(username, password, storedHash) {
try {
const isValid = compareSync(password, storedHash);
if (isValid) {
console.log(`Login successful for ${username}`);
return true;
} else {
console.log(`Invalid password for ${username}`);
return false;
}
} catch (error) {
console.error("Password verification failed:", error);
return false;
}
}Asynchronously tests a password against a hash using Promises.
/**
* Asynchronously tests a password against a hash.
* @param password Password to test
* @param hash Hash to test against
* @returns Promise resolving to boolean result
*/
function compare(password: string, hash: string): Promise<boolean>;Usage Examples:
import { compare } from "bcryptjs";
// Basic async verification
const hash = "$2b$10$N9qo8uLOickgx2ZMRZoMye2Z8WSdtXvKLhXfV.O/JZ4MYxvmq4dS6";
const isValid = await compare("myPassword", hash);
console.log(isValid); // true or false
// Async login verification
async function verifyLoginAsync(username, password, storedHash) {
try {
const isValid = await compare(password, storedHash);
if (isValid) {
console.log(`Login successful for ${username}`);
return { success: true, user: username };
} else {
console.log(`Invalid password for ${username}`);
return { success: false, error: "Invalid credentials" };
}
} catch (error) {
console.error("Password verification failed:", error);
return { success: false, error: "Verification failed" };
}
}
// Express.js middleware example
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await getUserByUsername(username);
if (!user) {
return res.status(401).json({ error: "Invalid credentials" });
}
const isValid = await compare(password, user.hashedPassword);
if (isValid) {
// Generate JWT token or session
res.json({ success: true, token: generateToken(user) });
} else {
res.status(401).json({ error: "Invalid credentials" });
}
});Asynchronously tests a password against a hash using callback-based API with optional progress tracking.
/**
* Asynchronously tests a password against a hash.
* @param password Password to test
* @param hash Hash to test against
* @param callback Callback receiving the error, if any, and the result
* @param progressCallback Optional callback for progress updates (0.0 - 1.0)
*/
function compare(
password: string,
hash: string,
callback?: Callback<boolean>,
progressCallback?: ProgressCallback
): void;Usage Examples:
import { compare } from "bcryptjs";
// Basic callback usage
const hash = "$2b$10$N9qo8uLOickgx2ZMRZoMye2Z8WSdtXvKLhXfV.O/JZ4MYxvmq4dS6";
compare("myPassword", hash, (err, result) => {
if (err) {
console.error("Comparison failed:", err);
return;
}
console.log("Password is valid:", result);
});
// With progress callback for high-round hashes
compare("myPassword", highRoundHash,
(err, result) => {
if (err) {
console.error("Comparison failed:", err);
return;
}
console.log("Verification completed:", result);
},
(progress) => {
console.log(`Verification progress: ${Math.round(progress * 100)}%`);
}
);
// Node.js callback-style authentication
function authenticateUser(username, password, callback) {
getUserHash(username, (err, storedHash) => {
if (err) {
return callback(err);
}
compare(password, storedHash, (err, isValid) => {
if (err) {
return callback(err);
}
callback(null, isValid);
});
});
}bcryptjs implements constant-time comparison to prevent timing attacks. The verification time remains consistent regardless of whether the password matches or not.
The comparison functions validate the hash format before processing:
// Valid bcrypt hash format
const validHash = "$2b$10$N9qo8uLOickgx2ZMRZoMye2Z8WSdtXvKLhXfV.O/JZ4MYxvmq4dS6";
// Invalid formats will cause comparison to return false
const invalidHash1 = "plaintext"; // Not a hash
const invalidHash2 = "$2a$10$invalid"; // Malformed hash
const invalidHash3 = ""; // Empty string
// All these will return false safely
console.log(compareSync("password", invalidHash1)); // false
console.log(compareSync("password", invalidHash2)); // false
console.log(compareSync("password", invalidHash3)); // false// Synchronous error handling
function safeCompareSync(password, hash) {
try {
return compareSync(password, hash);
} catch (error) {
console.error("Password comparison failed:", error);
return false; // Fail securely
}
}
// Asynchronous error handling
async function safeCompareAsync(password, hash) {
try {
return await compare(password, hash);
} catch (error) {
console.error("Password comparison failed:", error);
return false; // Fail securely
}
}
// Callback error handling
function safeCompareCallback(password, hash, done) {
compare(password, hash, (err, result) => {
if (err) {
console.error("Password comparison failed:", err);
return done(null, false); // Fail securely
}
done(null, result);
});
}// Express.js authentication middleware
const authenticateToken = async (req, res, next) => {
const { password } = req.body;
const user = req.user; // From previous middleware
try {
const isValid = await compare(password, user.hashedPassword);
if (!isValid) {
return res.status(401).json({ error: "Invalid password" });
}
next();
} catch (error) {
res.status(500).json({ error: "Authentication failed" });
}
};
// React login form handler
const handleLogin = async (username, password) => {
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
if (response.ok) {
const data = await response.json();
localStorage.setItem('token', data.token);
return { success: true };
} else {
return { success: false, error: 'Invalid credentials' };
}
} catch (error) {
return { success: false, error: 'Login failed' };
}
};