diff --git a/lib/backend/Routes/Api/Login.ml b/lib/backend/Routes/Api/Login.ml index 524acd3..2660f1b 100644 --- a/lib/backend/Routes/Api/Login.ml +++ b/lib/backend/Routes/Api/Login.ml @@ -1 +1,39 @@ -let handler _ = Dream.empty `OK +open HigherOrderHandlers +open Types_native.Definitions_j +open Vault_native + +let get_secrets request username = + Dream.sql request @@ fun db -> + match%lwt Models.Secrets.get_by_username ~username db with + | Ok user -> Lwt.return_ok user + | Error e -> Lwt.return_error e + +let handler request = + let handle_salt username = + match%lwt get_secrets request username with + | Ok (Some { client_random_value; _ }) -> + Dream.info (fun log -> log "User exists, serving client salt."); + let salt = + client_random_value |> Bytes.of_string |> Salt.compute_digest + in + Dream.json @@ string_of_login_salt_response { salt } + | Ok None -> + Dream.info (fun log -> log "User does not exist, serving server salt."); + let salt = Cipher.server_salt () in + Dream.json @@ string_of_login_salt_response { salt } + | Error (#Caqti_error.t as e) -> + Dream.error (fun log -> log "Failed with %s" @@ Caqti_error.show e); + Dream.respond ~code:422 "Invalid payload." + in + let handle_auth _ _ = assert false in + let inner ({ username; auth_token } : login_payload) = + match ValidationUsername.validate username with + | Validated Success -> ( + match auth_token with + | None -> handle_salt username + | Some auth_token -> handle_auth username auth_token) + | _ -> + Dream.error (fun log -> log "Rejecting invalid username: %s" username); + Dream.respond ~code:422 @@ string_of_login_error_content `CouldNotLogIn + in + with_json_body request login_payload_of_string inner diff --git a/lib/backend/Routes/Api/Register.ml b/lib/backend/Routes/Api/Register.ml index aa6d479..cbd6c92 100644 --- a/lib/backend/Routes/Api/Register.ml +++ b/lib/backend/Routes/Api/Register.ml @@ -2,7 +2,7 @@ open HigherOrderHandlers open Types_native.Definitions_j let handler request = - let inner { username; auth_token } = + let inner ({ username; auth_token } : register_user_payload) = match ValidationUsername.validate username with | Validated Success -> ( let auth_token = Cipher.double_hmac auth_token in diff --git a/lib/types/definitions.atd b/lib/types/definitions.atd index f0105e8..0874536 100644 --- a/lib/types/definitions.atd +++ b/lib/types/definitions.atd @@ -38,6 +38,21 @@ type register_error_content = [ type register_error_response = register_error_content base_error_response +(* login api types *) + +type login_payload = { + username: string; + ?auth_token: string option; +} + +type login_salt_response = { + salt: string; +} + +type login_error_content = [ + | CouldNotLogIn +] + (* client session types *) type logged_in = {