65 lines
3.9 KiB
Markdown
65 lines
3.9 KiB
Markdown
<!-- markdownlint-disable MD024 -->
|
|
|
|
# Capability Spec Delta: crypto-bin (crypto-completion)
|
|
|
|
**Package**: `@suaveplan/crypto-bin`
|
|
**Status**: PROPOSED
|
|
|
|
> Every requirement below carries a `**Verified by:**` line at authoring time. This is a new package; the entire spec below is `## ADDED Requirements`.
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: hash-password CLI hash mode
|
|
|
|
The package SHALL ship a `suaveplan-hash-password` bin that, when invoked with `--password <pw>` and no `--verify`, hashes the password using the requested algorithm (default `argon2id`, opt-in `--algo blake2b`) and writes the resulting stored-hash string to stdout, exiting with code 0. The CLI SHALL route through `@suaveplan/cli`'s arg parser (so `--help` works automatically) and SHALL NEVER call `process.exit` directly — it SHALL use `cli.exit(code)` to keep test harness compatibility.
|
|
|
|
#### Scenario: argon2id mode prints stored hash
|
|
|
|
- **WHEN** `suaveplan-hash-password --password "correct horse battery staple"` is invoked
|
|
- **THEN** stdout contains a string starting with `"$argon2id$"` AND the exit code is 0
|
|
|
|
#### Scenario: blake2b mode prints stored hash
|
|
|
|
- **WHEN** `suaveplan-hash-password --password "..." --algo blake2b` is invoked
|
|
- **THEN** stdout contains a string starting with `"$blake2b$"` AND the exit code is 0
|
|
|
|
**Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"argon2id mode writes a $argon2id$-prefixed hash to stdout and exits 0"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"blake2b mode writes a $blake2b$-prefixed hash to stdout and exits 0"`
|
|
|
|
---
|
|
|
|
### Requirement: hash-password CLI verify mode
|
|
|
|
When invoked with `--password <pw>` and `--verify <stored>`, the bin SHALL detect the algorithm from the stored hash's prefix, run the matching verify function (`verifyPasswordArgon2id` or `verifyPasswordBlake2b`), exit with code 0 on match and code 1 on mismatch. The bin SHALL NOT print anything to stdout in verify mode (so the exit code is the only signal — suitable for use in shell pipelines).
|
|
|
|
#### Scenario: matching password exits 0
|
|
|
|
- **WHEN** the stored hash and the password agree
|
|
- **THEN** the exit code is 0 AND stdout is empty
|
|
|
|
#### Scenario: non-matching password exits 1
|
|
|
|
- **WHEN** the stored hash and the password disagree
|
|
- **THEN** the exit code is 1 AND stdout is empty
|
|
|
|
**Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"verify mode exits 0 when password matches stored hash"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"verify mode exits 1 when password does not match stored hash"`
|
|
|
|
---
|
|
|
|
### Requirement: hash-password CLI argument validation
|
|
|
|
The bin SHALL reject malformed invocations (missing `--password`, unknown `--algo`, malformed `--verify` value) with a non-zero exit code and a `SuaveplanError` whose code is one of `CRYPTO.HASH_PASSWORD_CLI_BAD_ARGS`, `CRYPTO.HASH_PASSWORD_CLI_UNKNOWN_ALGO`, or `CRYPTO.HASH_PASSWORD_CLI_VERIFY_FAILED`. The error message SHALL be human-readable and SHALL be printed to stderr (not stdout, so it does not contaminate pipe output).
|
|
|
|
#### Scenario: missing --password rejected
|
|
|
|
- **WHEN** `suaveplan-hash-password` is invoked with no `--password`
|
|
- **THEN** the exit code is non-zero AND stderr mentions `--password` AND the underlying error code is `CRYPTO.HASH_PASSWORD_CLI_BAD_ARGS`
|
|
|
|
#### Scenario: unknown algorithm rejected
|
|
|
|
- **WHEN** `suaveplan-hash-password --password pw --algo bcrypt` is invoked
|
|
- **THEN** the exit code is non-zero AND the underlying error code is `CRYPTO.HASH_PASSWORD_CLI_UNKNOWN_ALGO` AND `context.algo === "bcrypt"`
|
|
|
|
**Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.spec-conformance.test.ts::"missing --password emits HASH_PASSWORD_CLI_BAD_ARGS"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.spec-conformance.test.ts::"unknown --algo emits HASH_PASSWORD_CLI_UNKNOWN_ALGO"`
|
|
|
|
<!-- markdownlint-enable MD024 -->
|