> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/meteor/meteor/llms.txt
> Use this file to discover all available pages before exploring further.

# Passwords

> Password authentication and management

# Passwords API

The accounts-password package provides secure password-based authentication.

Source: `packages/accounts-password/`

## Client Methods

### Meteor.loginWithPassword()

Log the user in with a password.

**Locus:** Client

<ParamField body="selector" type="string | object" required>
  Either a string interpreted as a username or an email; or an object with a single key: `email`, `username` or `id`. Username or email match in a case insensitive manner.
</ParamField>

<ParamField body="password" type="string" required>
  The user's password.
</ParamField>

<ParamField body="callback" type="function">
  Optional callback. Called with no arguments on success, or with a single Error argument on failure.
</ParamField>

```javascript theme={null}
// Login with username
Meteor.loginWithPassword('johndoe', 'password123', (error) => {
  if (error) {
    alert('Login failed: ' + error.reason);
  } else {
    console.log('Logged in successfully');
  }
});

// Login with email
Meteor.loginWithPassword('user@example.com', 'password123', callback);

// Login with object selector
Meteor.loginWithPassword(
  { username: 'johndoe' },
  'password123',
  callback
);
```

### Accounts.changePassword()

Change the current user's password. Must be logged in.

**Locus:** Client

<ParamField body="oldPassword" type="string" required>
  The user's current password. This is **not** sent in plain text over the wire.
</ParamField>

<ParamField body="newPassword" type="string" required>
  A new password for the user. This is **not** sent in plain text over the wire.
</ParamField>

<ParamField body="callback" type="function">
  Optional callback. Called with no arguments on success, or with a single Error argument on failure.
</ParamField>

```javascript theme={null}
Accounts.changePassword('oldPassword', 'newPassword', (error) => {
  if (error) {
    alert('Password change failed: ' + error.reason);
  } else {
    alert('Password changed successfully');
  }
});
```

### Accounts.forgotPassword()

Request a forgot password email.

**Locus:** Client

<ParamField body="options" type="object" required>
  Must contain `email` field.
</ParamField>

<ResponseField name="email" type="string" required>
  The email address to send a password reset link.
</ResponseField>

```javascript theme={null}
Accounts.forgotPassword(
  { email: 'user@example.com' },
  (error) => {
    if (error) {
      alert('Error: ' + error.reason);
    } else {
      alert('Password reset email sent');
    }
  }
);
```

### Accounts.resetPassword()

Reset the password for a user using a token received in email. Logs the user in afterwards if the user doesn't have 2FA enabled.

**Locus:** Client

<ParamField body="token" type="string" required>
  The token retrieved from the reset password URL.
</ParamField>

<ParamField body="newPassword" type="string" required>
  A new password for the user. This is **not** sent in plain text over the wire.
</ParamField>

<ParamField body="callback" type="function">
  Optional callback. Called with no arguments on success, or with a single Error argument on failure.
</ParamField>

```javascript theme={null}
// Extract token from URL
const token = FlowRouter.getParam('token');

Accounts.resetPassword(token, 'newPassword123', (error) => {
  if (error) {
    alert('Password reset failed: ' + error.reason);
  } else {
    alert('Password reset successful');
    FlowRouter.go('/');
  }
});
```

### Accounts.verifyEmail()

Marks the user's email address as verified. Logs the user in afterwards if the user doesn't have 2FA enabled.

**Locus:** Client

<ParamField body="token" type="string" required>
  The token retrieved from the verification URL.
</ParamField>

```javascript theme={null}
const token = FlowRouter.getParam('token');

Accounts.verifyEmail(token, (error) => {
  if (error) {
    alert('Verification failed: ' + error.reason);
  } else {
    alert('Email verified successfully');
  }
});
```

## Server Methods

### Accounts.setPasswordAsync()

Forcibly change the password for a user.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The id of the user to update.
</ParamField>

<ParamField body="newPassword" type="string" required>
  A new password for the user.
</ParamField>

<ParamField body="options" type="object">
  Optional options object.
</ParamField>

<ResponseField name="logout" type="boolean">
  Logout all current connections with this userId (default: true)
</ResponseField>

```javascript theme={null}
// Change user password and log them out
await Accounts.setPasswordAsync(userId, 'newSecurePassword');

// Change password but keep them logged in
await Accounts.setPasswordAsync(userId, 'newPassword', { 
  logout: false 
});
```

### Accounts.sendResetPasswordEmail()

Send an email with a link the user can use to reset their password.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The id of the user to send email to.
</ParamField>

<ParamField body="email" type="string">
  Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
</ParamField>

<ParamField body="extraTokenData" type="object">
  Optional additional data to be added into the token record.
</ParamField>

<ParamField body="extraParams" type="object">
  Optional additional params to be added to the reset url.
</ParamField>

**Returns:** `Promise<{email, user, token, url, options}>`

```javascript theme={null}
await Accounts.sendResetPasswordEmail(userId, 'user@example.com');

// With extra params
await Accounts.sendResetPasswordEmail(
  userId,
  'user@example.com',
  null,
  { source: 'admin-panel' }
);
```

### Accounts.sendEnrollmentEmail()

Send an email with a link the user can use to set their initial password.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The id of the user to send email to.
</ParamField>

<ParamField body="email" type="string">
  Optional. Which address of the user's to send the email to.
</ParamField>

```javascript theme={null}
// Create user without password
const userId = await Accounts.createUserAsync({
  email: 'newuser@example.com',
  profile: { name: 'New User' }
});

// Send enrollment email
await Accounts.sendEnrollmentEmail(userId);
```

### Accounts.sendVerificationEmail()

Send an email with a link the user can use verify their email address.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The id of the user to send email to.
</ParamField>

<ParamField body="email" type="string">
  Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first unverified email in the list.
</ParamField>

```javascript theme={null}
await Accounts.sendVerificationEmail(userId);
```

## Email Management (Server)

### Accounts.addEmailAsync()

Add an email address for a user.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The ID of the user to update.
</ParamField>

<ParamField body="newEmail" type="string" required>
  A new email address for the user.
</ParamField>

<ParamField body="verified" type="boolean">
  Optional - whether the new email address should be marked as verified. Defaults to false.
</ParamField>

```javascript theme={null}
await Accounts.addEmailAsync(userId, 'newemail@example.com', false);
```

### Accounts.removeEmail()

Remove an email address for a user.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The ID of the user to update.
</ParamField>

<ParamField body="email" type="string" required>
  The email address to remove.
</ParamField>

```javascript theme={null}
await Accounts.removeEmail(userId, 'old@example.com');
```

### Accounts.replaceEmailAsync()

Replace an email address for a user.

**Locus:** Server

<ParamField body="userId" type="string" required>
  The ID of the user to update.
</ParamField>

<ParamField body="oldEmail" type="string" required>
  The email address to replace.
</ParamField>

<ParamField body="newEmail" type="string" required>
  The new email address to use.
</ParamField>

<ParamField body="verified" type="boolean">
  Optional - whether the new email address should be marked as verified. Defaults to false.
</ParamField>

```javascript theme={null}
await Accounts.replaceEmailAsync(
  userId,
  'old@example.com',
  'new@example.com',
  true
);
```

## Password Security Configuration

Configure password hashing algorithms and security parameters.

```javascript theme={null}
Accounts.config({
  // bcrypt configuration (default)
  bcryptRounds: 10,
  
  // Or use argon2 (more secure)
  argon2Enabled: true,
  argon2Type: 'argon2id', // 'argon2i', 'argon2d', or 'argon2id'
  argon2TimeCost: 2,
  argon2MemoryCost: 19456, // in KiB (19MB)
  argon2Parallelism: 1
});
```

## Complete Example: Password Reset Flow

```javascript theme={null}
// Server: Configure email URLs
import { Accounts } from 'meteor/accounts-base';

Accounts.urls.resetPassword = (token, extraParams) => {
  return Meteor.absoluteUrl(`reset-password/${token}`);
};

// Server: Send reset email
Meteor.methods({
  async sendPasswordReset(email) {
    const user = await Accounts.findUserByEmail(email);
    if (!user) {
      throw new Meteor.Error('not-found', 'User not found');
    }
    await Accounts.sendResetPasswordEmail(user._id, email);
  }
});

// Client: Request password reset
Template.forgotPassword.events({
  'submit form'(event) {
    event.preventDefault();
    const email = event.target.email.value;
    
    Meteor.call('sendPasswordReset', email, (error) => {
      if (error) {
        alert(error.reason);
      } else {
        alert('Password reset email sent');
      }
    });
  }
});

// Client: Reset password page
Template.resetPassword.onCreated(function() {
  this.token = FlowRouter.getParam('token');
});

Template.resetPassword.events({
  'submit form'(event, template) {
    event.preventDefault();
    const newPassword = event.target.password.value;
    
    Accounts.resetPassword(template.token, newPassword, (error) => {
      if (error) {
        alert('Reset failed: ' + error.reason);
      } else {
        alert('Password reset successful');
        FlowRouter.go('/');
      }
    });
  }
});
```
