[OCaml] High Intensity Training Online
1
(** A trainee: the account that owns a routine, a workout in progress, and a
2
logbook. Identity lives in {!Hito_app}, not the core, because the core needs
3
none.
4
5
A {!credential} is a password verifier, never the password. The hash is
6
computed and checked here so that no other layer sees a plaintext password
7
for longer than one request. *)
8
9
type id = private string
10
(** An opaque account identity, assigned by an adapter. *)
11
12
val id : string -> id
13
val id_to_string : id -> string
14
15
type username = private string
16
(** A normalized username: trimmed and lowercased ASCII. *)
17
18
type username_error =
19
| Too_short (** Fewer than {!username_min_length} characters. *)
20
| Too_long (** More than {!username_max_length} characters. *)
21
22
val username_min_length : int
23
val username_max_length : int
24
25
val username : string -> (username, username_error) result
26
(** Normalizes and validates a username. Trims and lowercases the input, then
27
requires its length within {!username_min_length}..{!username_max_length}
28
inclusive. *)
29
30
val username_to_string : username -> string
31
val pp_username_error : Format.formatter -> username_error -> unit
32
33
type credential
34
(** A password verifier. Carries a salted hash, never the password. *)
35
36
val credential_of_hash : string -> credential
37
(** Wraps a stored hash read back from persistence. *)
38
39
val credential_to_hash : credential -> string
40
(** The stored hash, for persistence. *)
41
42
val hash_password : string -> credential
43
(** Salts and hashes a new password. Accepts any string; there is no length or
44
content policy on passwords. *)
45
46
val verify_password : credential -> string -> bool
47
(** Constant-time verification of a candidate password against the verifier. *)
48
49
type t = { id : id; username : username; credential : credential }
50
(** A stored account. *)
51