Documentation
¶
Overview ¶
Package passwordtype provides HashedPassword — a one-way argon2id-hashed password column type for SQL databases that doubles as a gqlgen scalar.
The type wraps github.com/ubgo/crypt's HashPassword/VerifyPassword (argon2id, OWASP-recommended modern password hash). Plaintext is never recoverable from a HashedPassword; the only operations on the stored value are Verify and round-trip through SQL.
Defense in depth: every redaction path is closed.
- String, GoString return "[redacted]"
- MarshalJSON returns null
- LogValue returns "[redacted]" so slog never emits the hash
- MarshalGQL writes null so the hash never reaches a GraphQL response
On the input side, UnmarshalGQL accepts a plaintext string from a GraphQL input field, hashes it via crypt.HashPassword, and stores the hash. Resolvers therefore receive a HashedPassword that is already hashed — no manual hashing in business code, no temptation to log the plaintext.
gqlgen integration is duck-typed: this package does not import gqlgen.
Index ¶
- type HashedPassword
- func (p HashedPassword) GoString() string
- func (p HashedPassword) Hash() string
- func (p HashedPassword) IsSet() bool
- func (p HashedPassword) LogValue() slog.Value
- func (p HashedPassword) MarshalGQL(w io.Writer)
- func (p HashedPassword) MarshalJSON() ([]byte, error)
- func (p *HashedPassword) Scan(src any) error
- func (p HashedPassword) String() string
- func (p *HashedPassword) UnmarshalGQL(v any) error
- func (p *HashedPassword) UnmarshalJSON(data []byte) error
- func (p HashedPassword) Value() (driver.Value, error)
- func (p HashedPassword) Verify(plaintext string) bool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type HashedPassword ¶
type HashedPassword struct {
// contains filtered or unexported fields
}
HashedPassword is an argon2id password hash. The plaintext is never stored. The zero value is unset (Value returns NULL, Verify returns false).
func FromHash ¶
func FromHash(stored string) HashedPassword
FromHash wraps an already-hashed PHC string. Use when reading from trusted storage that bypasses Scan (e.g. a snapshot import).
func New ¶
func New(plaintext string) (HashedPassword, error)
New hashes plaintext with argon2id and returns a HashedPassword.
func (HashedPassword) GoString ¶
func (p HashedPassword) GoString() string
GoString returns "[redacted]" — same protection for %#v formatting.
func (HashedPassword) Hash ¶
func (p HashedPassword) Hash() string
Hash returns the raw stored hash. Intended only for callers that must re-export the value via a trusted boundary (e.g. user-export tooling behind admin auth). Most callers should prefer Verify.
func (HashedPassword) IsSet ¶
func (p HashedPassword) IsSet() bool
IsSet reports whether the password has been set.
func (HashedPassword) LogValue ¶
func (p HashedPassword) LogValue() slog.Value
LogValue makes HashedPassword safe for use with log/slog. The slog handler sees only "[redacted]", never the hash.
func (HashedPassword) MarshalGQL ¶
func (p HashedPassword) MarshalGQL(w io.Writer)
MarshalGQL is the gqlgen-compatible marshal hook. It always writes null — the hash must never leave the server via GraphQL.
func (HashedPassword) MarshalJSON ¶
func (p HashedPassword) MarshalJSON() ([]byte, error)
MarshalJSON always returns null. There is no legitimate JSON consumer that needs the raw hash; encode the entity without the password field, or expose Verify behind an authorization check.
func (*HashedPassword) Scan ¶
func (p *HashedPassword) Scan(src any) error
Scan implements [sql.Scanner]. Accepts string, []byte, or nil.
func (HashedPassword) String ¶
func (p HashedPassword) String() string
String returns "[redacted]" — the stored hash never appears in fmt output, debug prints, or panic traces.
func (*HashedPassword) UnmarshalGQL ¶
func (p *HashedPassword) UnmarshalGQL(v any) error
UnmarshalGQL accepts a plaintext string from a GraphQL input field and hashes it. Resolvers receive a HashedPassword whose Value is the hash, not the plaintext.
func (*HashedPassword) UnmarshalJSON ¶
func (p *HashedPassword) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts either null or a string. A string is treated as a plaintext password and hashed.
func (HashedPassword) Value ¶
func (p HashedPassword) Value() (driver.Value, error)
Value implements driver.Valuer. An unset password persists as SQL NULL.
func (HashedPassword) Verify ¶
func (p HashedPassword) Verify(plaintext string) bool
Verify reports whether plaintext matches the stored hash. Returns false when the password is unset or any comparison error occurs; callers who need to distinguish the two cases should call IsSet first.