Expand description
Password hashing.
Upstream is src/password.js: bcrypt.hash(password, 10), using bcryptjs by default and
@node-rs/bcrypt when it can be required.
The cost factor and the output format are interop contract, not implementation detail. A
_User row written by parse-rust must be loginable by parse-server and the reverse, on the
same database. That is a mixed-fleet requirement, and it is the kind of thing that looks fine
until a second server exists. tests/bcrypt_interop.rs checks both directions against Node.
Both functions are async and hash on the blocking pool, and that is not a style choice.
bcrypt at cost 10 is tens of milliseconds of pure CPU with no await points in it. Run inline on
a tokio worker it parks that thread outright, and both entry points are reachable without
credentials: POST /users hashes on every signup and POST /login verifies for any known
username. As many concurrent requests as there are workers therefore stops the runtime polling
anything at all, including /health, and a single /batch of signups is one request that does
it. spawn_blocking puts the work on a bounded pool instead, which turns that into ordinary
queueing. Upstream has the property for free, because its bcrypt binding hands off to libuv’s
threadpool rather than running on the event loop.
This does not remove the need for login rate limiting. It removes the case where one caller takes the process down without needing volume.
Constants§
- BCRYPT_
COST - Upstream’s cost factor (
password.js,bcrypt.hash(password, 10)). - DUMMY_
HASH - Upstream’s fixed dummy hash, for timing normalization (
password.js:33).
Functions§
- hash
- Hash a password for storage in
_User._hashed_password. - verify
- Verify a password against a stored hash.
- verify_
dummy - Pay the bcrypt cost without having a hash to check, and discard the answer.