@@ -20,6 +20,7 @@ fn default_schemes() -> Vec<HashingScheme> {
2020 cost: None ,
2121 secret: None ,
2222 secret_file: None ,
23+ unicode_normalization: false ,
2324 } ]
2425}
2526
@@ -124,7 +125,7 @@ impl PasswordsConfig {
124125 /// not be read.
125126 pub async fn load (
126127 & self ,
127- ) -> Result < Vec < ( u16 , Algorithm , Option < u32 > , Option < Vec < u8 > > ) > , anyhow:: Error > {
128+ ) -> Result < Vec < ( u16 , Algorithm , Option < u32 > , Option < Vec < u8 > > , bool ) > , anyhow:: Error > {
128129 let mut schemes: Vec < & HashingScheme > = self . schemes . iter ( ) . collect ( ) ;
129130 schemes. sort_unstable_by_key ( |a| Reverse ( a. version ) ) ;
130131 schemes. dedup_by_key ( |a| a. version ) ;
@@ -151,13 +152,24 @@ impl PasswordsConfig {
151152 ( None , None ) => None ,
152153 } ;
153154
154- mapped_result. push ( ( scheme. version , scheme. algorithm , scheme. cost , secret) ) ;
155+ mapped_result. push ( (
156+ scheme. version ,
157+ scheme. algorithm ,
158+ scheme. cost ,
159+ secret,
160+ scheme. unicode_normalization ,
161+ ) ) ;
155162 }
156163
157164 Ok ( mapped_result)
158165 }
159166}
160167
168+ #[ allow( clippy:: trivially_copy_pass_by_ref) ]
169+ const fn is_default_false ( value : & bool ) -> bool {
170+ !* value
171+ }
172+
161173/// Parameters for a password hashing scheme
162174#[ derive( Debug , Clone , Serialize , Deserialize , JsonSchema ) ]
163175pub struct HashingScheme {
@@ -168,6 +180,14 @@ pub struct HashingScheme {
168180 /// The hashing algorithm to use
169181 pub algorithm : Algorithm ,
170182
183+ /// Whether to apply Unicode normalization to the password before hashing
184+ ///
185+ /// Defaults to `false`, and generally recommended to stay false. This is
186+ /// although recommended when importing password hashs from Synapse, as it
187+ /// applies an NFKC normalization to the password before hashing it.
188+ #[ serde( default , skip_serializing_if = "is_default_false" ) ]
189+ pub unicode_normalization : bool ,
190+
171191 /// Cost for the bcrypt algorithm
172192 #[ serde( skip_serializing_if = "Option::is_none" ) ]
173193 #[ schemars( default = "default_bcrypt_cost" ) ]
0 commit comments