← All @molecule/* packages · App templates

@molecule/api-password

Core interface · password · API (Node) · v1.0.1 · Apache-2.0

Password hashing interface for molecule.dev

npm install @molecule/api-password

npm · Source on GitHub

How it works

@molecule/api-password is the password core interface on the API (Node) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 1 provider: @molecule/api-password-bcrypt.

import { hash, compare } from '@molecule/api-password'

// Register: store ONLY the hash.
const passwordHash = await hash(req.body.password)
await createUser({ email, passwordHash })

// Log in: constant-time compare; never `user.passwordHash === x`.
const ok = await compare(req.body.password, user.passwordHash)
if (!ok) return res.status(401).json({ error: 'Invalid credentials.' }) // don't reveal which field

Providers (1): @molecule/api-password-bcrypt

Works with: @molecule/api-bond, @molecule/api-i18n

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Password hashing interface for molecule.dev.

Defines the standard interface for password hashing providers.

Quick Start

import { hash, compare } from '@molecule/api-password'

// Register: store ONLY the hash.
const passwordHash = await hash(req.body.password)
await createUser({ email, passwordHash })

// Log in: constant-time compare; never `user.passwordHash === x`.
const ok = await compare(req.body.password, user.passwordHash)
if (!ok) return res.status(401).json({ error: 'Invalid credentials.' }) // don't reveal which field

Type

core

Installation

npm install @molecule/api-password @molecule/api-bond @molecule/api-i18n

API

Interfaces

PasswordProvider

Password provider interface.

All password providers must implement this interface.

interface PasswordProvider {
  /**
   * Hashes a plain-text password.
   *
   * @param password - The plain-text password to hash
   * @param saltRounds - Number of salt rounds (cost factor)
   * @returns The hashed password string
   */
  hash(password: string, saltRounds?: number): Promise<string>

  /**
   * Compares a plain-text password against a hash.
   *
   * @param password - The plain-text password to check
   * @param passwordHash - The hash to compare against
   * @returns true if the password matches the hash
   */
  compare(password: string, passwordHash: string): Promise<boolean>
}

Functions

compare(password, passwordHash)

Compares a plain-text password against a stored hash using the bonded provider.

function compare(password: string, passwordHash: string): Promise<boolean>
  • password — The plain-text password to check.
  • passwordHash — The stored hash to compare against.

Returns: true if the password matches the hash.

getProvider()

Retrieves the bonded password provider, throwing if none is configured.

function getProvider(): PasswordProvider

Returns: The bonded password provider.

hash(password, saltRounds)

Hashes a plain-text password using the bonded provider.

function hash(password: string, saltRounds?: number): Promise<string>
  • password — The plain-text password to hash. The env-derived default is clamped to a sane bcrypt-cost range of 10–16 (mirroring @molecule/api-password-bcrypt's own default): the cost factor is EXPONENTIAL (each +1 doubles the work), so a misread SALT_ROUNDS=32 would otherwise hang every signup for hours with zero error output, and SALT_ROUNDS=4 would silently produce weak hashes. An explicitly passed saltRounds argument is honored as-is (a deliberate caller choice, e.g. fast test fixtures).
  • saltRounds — Number of salt rounds (cost factor); defaults to the SALT_ROUNDS env var (clamped to 10–16) or 12.

Returns: The resulting password hash string.

hasProvider()

Checks whether a password provider is currently bonded.

function hasProvider(): boolean

Returns: true if a password provider is bonded.

setProvider(provider)

Registers a password hashing provider as the active singleton. Called by bond packages during application startup.

function setProvider(provider: PasswordProvider): void
  • provider — The password hashing provider implementation to bond.

Available Providers

ProviderPackage
bcrypt@molecule/api-password-bcrypt

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-i18n ^1.0.1

Runtime Dependencies

  • @molecule/api-bond
  • @molecule/api-i18n

Use {@link hash} and {@link compare} from the bonded provider — NEVER roll your own password hashing.

  • Never store, log, or return a password OR its hash to the client. Persist only the hash server-side; a login response returns a session/token, never the hash.
  • Compare with {@link compare}, never ===. It is a constant-time check via the bond (bcrypt); a plain string/hash equality is a timing oracle and won't even match a salted hash.
  • Do not implement your own MD5/SHA/salt scheme, and never put a password in a URL, query string, or GET request (it lands in logs/history).
  • hash() uses SALT_ROUNDS (default 12, env value clamped to 10–16) from config — don't hardcode a weaker cost. The cost is EXPONENTIAL (each +1 doubles the work), so an unclamped 32 would hang every signup for hours.
  • bcrypt only reads the first 72 BYTES of a password — two passwords sharing the same first 72 bytes compare equal. Don't prepend a long app-controlled prefix (pepper, username) to the password before hashing, and don't reject long passphrases thinking extra length past ~72 bytes (fewer with multi-byte UTF-8) adds strength.