Skip to main content

Local Authentication

Local authentication uses email and password credentials stored in MongoDB with bcrypt-hashed passwords.

Registration

Programmatic

const user = await app.auth.createUser({
email: "alice@example.com",
password: "secure-password-123",
name: "Alice Johnson",
metadata: {
plan: "free",
},
});

console.log(user._id); // MongoDB ObjectId
console.log(user.email); // "alice@example.com"
console.log(user.name); // "Alice Johnson"

REST API

curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"password": "secure-password-123",
"name": "Alice Johnson"
}'

Response (201):

{
"user": {
"_id": "65a1b2c3d4e5f6a7b8c9d0e1",
"email": "alice@example.com",
"name": "Alice Johnson",
"createdAt": "2025-01-15T10:30:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}

Login

Programmatic

const result = await app.auth.login({
email: "alice@example.com",
password: "secure-password-123",
});

console.log(result.user); // User object
console.log(result.token); // JWT string

REST API

curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"password": "secure-password-123"
}'

Response (200):

{
"user": {
"_id": "65a1b2c3d4e5f6a7b8c9d0e1",
"email": "alice@example.com",
"name": "Alice Johnson"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}

Response (401):

{
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Invalid email or password"
}
}

Password Management

Change Password

await app.auth.changePassword(userId, {
currentPassword: "old-password",
newPassword: "new-secure-password",
});
curl -X POST http://localhost:3000/auth/change-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGci..." \
-d '{
"currentPassword": "old-password",
"newPassword": "new-secure-password"
}'

Reset Password

// Request a password reset (sends email if messaging wire is loaded)
await app.auth.requestPasswordReset("alice@example.com");

// Complete the reset with the token from the email
await app.auth.resetPassword(resetToken, "new-password");

User Data Model

Users are stored in the auth_users collection:

interface User {
_id: ObjectId;
email: string;
passwordHash: string; // bcrypt hash, never exposed via API
name?: string;
metadata?: Record<string, unknown>;
emailVerified: boolean;
createdAt: Date;
updatedAt: Date;
}

Configuration Options

auth({
local: {
passwordMinLength: 8, // Minimum password length
requireEmailVerification: true, // Require email verification
maxLoginAttempts: 5, // Lock after N failed attempts
lockDuration: 15 * 60_000, // Lock duration in ms (15 min)
},
});