@@ -12,8 +12,11 @@ use snafu::ResultExt as _;
1212use tower_sessions:: Session ;
1313
1414use super :: Maud ;
15- use crate :: error:: { OtherSnafu , RequestResult } ;
15+ use crate :: error:: {
16+ LoginRequiredSnafu , OtherSnafu , PublicKeyMissingSnafu , RequestResult , UnlockResult , UnlockSnafu ,
17+ } ;
1618use crate :: is_htmx:: IsHtmx ;
19+ use crate :: serde_util:: empty_string_as_none;
1720use crate :: { SharedState , UiState } ;
1821
1922pub async fn get (
@@ -31,64 +34,76 @@ pub async fn get(
3134 ) ] ;
3235 return Ok ( ( StatusCode :: OK , headers) . into_response ( ) ) ;
3336 }
34- Ok ( Maud ( state. unlock_page ( None , "" , None ) . await ?) . into_response ( ) )
37+ Ok ( Maud ( state. unlock_page ( None , None , None ) . await ?) . into_response ( ) )
3538}
3639
3740pub async fn get_random ( state : State < SharedState > ) -> RequestResult < impl IntoResponse > {
3841 let random_secret_key = RostraIdSecretKey :: generate ( ) ;
3942 Ok ( Maud (
4043 state
41- . unlock_page (
42- Some ( random_secret_key. id ( ) ) ,
43- & random_secret_key. to_string ( ) ,
44- None ,
45- )
44+ . unlock_page ( Some ( random_secret_key. id ( ) ) , Some ( random_secret_key) , None )
4645 . await ?,
4746 ) )
4847}
4948
5049#[ derive( Deserialize ) ]
5150pub struct Input {
5251 #[ serde( rename = "username" ) ]
53- rostra_id : RostraId ,
52+ #[ serde( deserialize_with = "empty_string_as_none" ) ]
53+ rostra_id : Option < RostraId > ,
5454 #[ serde( rename = "password" ) ]
55- mnemonic : String ,
55+ #[ serde( deserialize_with = "empty_string_as_none" ) ]
56+ mnemonic : Option < RostraIdSecretKey > ,
57+ }
58+
59+ impl Input {
60+ fn rostra_id ( & self ) -> UnlockResult < RostraId > {
61+ self . rostra_id
62+ . or_else ( || self . mnemonic . map ( |m| m. id ( ) ) )
63+ . ok_or_else ( || PublicKeyMissingSnafu . build ( ) )
64+ }
5665}
5766
5867pub async fn post_unlock (
5968 state : State < SharedState > ,
6069 session : Session ,
6170 Form ( form) : Form < Input > ,
6271) -> RequestResult < Response > {
63- Ok ( match state. unlock ( form. rostra_id , & form. mnemonic ) . await {
64- Ok ( secret_key_opt) => {
65- session
66- . insert (
67- SESSION_KEY ,
68- & UserSession :: new ( form. rostra_id , secret_key_opt) ,
69- )
70- . await
71- . boxed ( )
72- . context ( OtherSnafu ) ?;
73- let headers = [ (
74- HeaderName :: from_static ( "hx-redirect" ) ,
75- HeaderValue :: from_static ( "/ui" ) ,
76- ) ] ;
77- ( StatusCode :: SEE_OTHER , headers) . into_response ( )
78- }
79- Err ( e) => Maud (
80- state
81- . unlock_page (
82- Some ( form. rostra_id ) ,
83- & form. mnemonic ,
84- html ! {
85- span . "o-unlockScreen_notice" { ( e) }
86- } ,
87- )
88- . await ?,
89- )
90- . into_response ( ) ,
91- } )
72+ Ok (
73+ match state
74+ . unlock ( form. rostra_id ( ) . context ( UnlockSnafu ) ?, form. mnemonic )
75+ . await
76+ {
77+ Ok ( secret_key_opt) => {
78+ let rostra_id = secret_key_opt
79+ . map ( |secret| secret. id ( ) )
80+ . or ( form. rostra_id )
81+ . ok_or_else ( || LoginRequiredSnafu . build ( ) ) ?;
82+ session
83+ . insert ( SESSION_KEY , & UserSession :: new ( rostra_id, secret_key_opt) )
84+ . await
85+ . boxed ( )
86+ . context ( OtherSnafu ) ?;
87+ let headers = [ (
88+ HeaderName :: from_static ( "hx-redirect" ) ,
89+ HeaderValue :: from_static ( "/ui" ) ,
90+ ) ] ;
91+ ( StatusCode :: SEE_OTHER , headers) . into_response ( )
92+ }
93+ Err ( e) => Maud (
94+ state
95+ . unlock_page (
96+ form. rostra_id ,
97+ form. mnemonic ,
98+ html ! {
99+ span . "o-unlockScreen_notice" { ( e) }
100+ } ,
101+ )
102+ . await ?,
103+ )
104+ . into_response ( ) ,
105+ } ,
106+ )
92107}
93108
94109pub async fn logout ( session : Session ) -> RequestResult < impl IntoResponse > {
@@ -105,7 +120,7 @@ impl UiState {
105120 async fn unlock_page (
106121 & self ,
107122 current_rostra_id : Option < RostraId > ,
108- current_mnemonic : & str ,
123+ current_secret_key : Option < RostraIdSecretKey > ,
109124 notification : impl Into < Option < Markup > > ,
110125 ) -> RequestResult < Markup > {
111126 let random_rostra_id_secret = & RostraIdSecretKey :: generate ( ) ;
@@ -150,7 +165,7 @@ impl UiState {
150165 autocomplete="current-password"
151166 placeholder="Mnemonic (Secret Key) - if empty, read-only mode"
152167 title="Mnemonic is 12 words passphrase encoding secret key of your identity"
153- value=( current_mnemonic )
168+ value=( current_secret_key . as_ref ( ) . map ( ToString :: to_string ) . unwrap_or_default ( ) )
154169 { }
155170 button
156171 type ="button" // do not submit the form!
0 commit comments