npm package: @gm-mikele/password
Description: Better Auth compatible password hashing service - framework agnostic
Latest version: 1.0.0

# @better-auth-compat/password

Better Auth compatible password hashing service - framework agnostic.

[![npm version](https://img.shields.io/npm/v/@better-auth-compat/password)](https://www.npmjs.com/package/@better-auth-compat/password)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Installation

```bash
npm install @better-auth-compat/password
# or
pnpm add @better-auth-compat/password
# or
yarn add @better-auth-compat/password
```

## Usage

```typescript
import { PasswordService } from '@better-auth-compat/password';

const passwordService = new PasswordService();

// Hash password
const hash = await passwordService.hashPassword('myPassword123!');
// Returns: "salt:hash" (both hex-encoded)
// Example: "ff2260be96728d140332e138d81e9aea:f357208a8eb032d1759b4865b5d29aeab22ecf55138dfd5360301e2dc832c34547bb8cdf603004c875c966064a0e330c5cbc3dc27ac346fe09b6b91c644e1255"

// Verify password
const isValid = await passwordService.verifyPassword('myPassword123!', hash);
// Returns: boolean

// Validate password strength (optional)
const validation = passwordService.validatePasswordStrength('password');
// Returns: { isValid: boolean; errors: string[] }
```

## Better Auth Compatibility

This package uses the **exact same** password hashing algorithm as Better Auth:

- **Algorithm**: `@noble/hashes/scrypt`
- **Parameters**: N=16384, r=16, p=1, dkLen=64
- **Salt**: 16 random bytes (32 hex characters)
- **Format**: `salt:hash` (both hex-encoded)
- **Normalization**: NFKC Unicode normalization

Passwords hashed with Better Auth will work with this package and vice versa. This makes it perfect for:

- Migrating from Better Auth to other frameworks
- Maintaining password compatibility across different systems
- Using Better Auth's password hashing in non-Better Auth projects

## API Reference

### `PasswordService`

The main class for password operations.

#### `hashPassword(password: string): Promise<string>`

Hashes a password using Better Auth's scrypt implementation.

**Parameters:**
- `password` (string): The plain text password to hash

**Returns:** Promise<string> - The hashed password in format `"salt:hash"`

**Example:**
```typescript
const hash = await passwordService.hashPassword('mySecurePassword123!');
```

#### `verifyPassword(password: string, hash: string): Promise<boolean>`

Verifies a password against a stored hash.

**Parameters:**
- `password` (string): The plain text password to verify
- `hash` (string): The stored hash in format `"salt:hash"`

**Returns:** Promise<boolean> - `true` if password matches, `false` otherwise

**Example:**
```typescript
const isValid = await passwordService.verifyPassword('myPassword', storedHash);
if (isValid) {
  // Password is correct
}
```

#### `validatePasswordStrength(password: string): PasswordValidationResult`

Validates password strength according to common security requirements.

**Parameters:**
- `password` (string): The password to validate

**Returns:** `PasswordValidationResult` - Object with `isValid` (boolean) and `errors` (string[])

**Example:**
```typescript
const result = passwordService.validatePasswordStrength('weak');
if (!result.isValid) {
  console.log('Password errors:', result.errors);
}
```

### `PasswordValidationResult`

```typescript
interface PasswordValidationResult {
  isValid: boolean;
  errors: string[];
}
```

## Security

- ✅ **Constant-time comparison** - Prevents timing attacks
- ✅ **Unicode normalization** - Ensures compatibility across different input methods
- ✅ **High scrypt cost parameters** - N=16384 provides strong security
- ✅ **Cryptographically secure random salt** - Each password gets a unique salt
- ✅ **No side effects** - Library doesn't log errors or expose sensitive information

## Requirements

- Node.js >= 18.0.0
- TypeScript >= 4.0.0 (for TypeScript projects)

## Module Support

This package supports both CommonJS and ES Modules:

```javascript
// CommonJS
const { PasswordService } = require('@better-auth-compat/password');

// ES Modules
import { PasswordService } from '@better-auth-compat/password';
```

## Migration from Better Auth

If you're migrating from Better Auth, your existing password hashes will work without any changes:

```typescript
// Before (Better Auth)
import { hash } from 'better-auth/utils';
const hash = await hash(password);

// After (This package)
import { PasswordService } from '@better-auth-compat/password';
const passwordService = new PasswordService();
const hash = await passwordService.hashPassword(password);
```

Both hashes are compatible and can verify each other.

## Examples

### Express.js

```typescript
import express from 'express';
import { PasswordService } from '@better-auth-compat/password';

const app = express();
const passwordService = new PasswordService();

app.post('/register', async (req, res) => {
  const { password } = req.body;
  const hash = await passwordService.hashPassword(password);
  // Store hash in database
  res.json({ success: true });
});

app.post('/login', async (req, res) => {
  const { password, storedHash } = req.body;
  const isValid = await passwordService.verifyPassword(password, storedHash);
  if (isValid) {
    res.json({ success: true });
  } else {
    res.status(401).json({ error: 'Invalid password' });
  }
});
```

### Next.js API Route

```typescript
import { NextApiRequest, NextApiResponse } from 'next';
import { PasswordService } from '@better-auth-compat/password';

const passwordService = new PasswordService();

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method === 'POST') {
    const { password } = req.body;
    const hash = await passwordService.hashPassword(password);
    res.status(200).json({ hash });
  }
}
```

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.