Can clear 2FA login history from edit_user page
This commit is contained in:
		
							
								
								
									
										161
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										161
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -222,7 +222,7 @@ dependencies = [
 | 
				
			|||||||
 "serde_urlencoded",
 | 
					 "serde_urlencoded",
 | 
				
			||||||
 "smallvec",
 | 
					 "smallvec",
 | 
				
			||||||
 "socket2",
 | 
					 "socket2",
 | 
				
			||||||
 "time",
 | 
					 "time 0.3.17",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -325,6 +325,15 @@ dependencies = [
 | 
				
			|||||||
 "alloc-no-stdlib",
 | 
					 "alloc-no-stdlib",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "android_system_properties"
 | 
				
			||||||
 | 
					version = "0.1.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anyhow"
 | 
					name = "anyhow"
 | 
				
			||||||
version = "1.0.66"
 | 
					version = "1.0.66"
 | 
				
			||||||
@@ -392,7 +401,7 @@ dependencies = [
 | 
				
			|||||||
 "num-traits",
 | 
					 "num-traits",
 | 
				
			||||||
 "rusticata-macros",
 | 
					 "rusticata-macros",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
 "time",
 | 
					 "time 0.3.17",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -495,6 +504,7 @@ dependencies = [
 | 
				
			|||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "bcrypt",
 | 
					 "bcrypt",
 | 
				
			||||||
 "bincode",
 | 
					 "bincode",
 | 
				
			||||||
 | 
					 "chrono",
 | 
				
			||||||
 "clap",
 | 
					 "clap",
 | 
				
			||||||
 "digest",
 | 
					 "digest",
 | 
				
			||||||
 "env_logger",
 | 
					 "env_logger",
 | 
				
			||||||
@@ -644,6 +654,21 @@ version = "1.0.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
					checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "chrono"
 | 
				
			||||||
 | 
					version = "0.4.23"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "iana-time-zone",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "num-integer",
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					 "time 0.1.44",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cipher"
 | 
					name = "cipher"
 | 
				
			||||||
version = "0.4.3"
 | 
					version = "0.4.3"
 | 
				
			||||||
@@ -699,10 +724,20 @@ checksum = "454038500439e141804c655b4cd1bc6a70bcb95cd2bc9463af5661b6956f0e46"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "wasi",
 | 
					 "wasi 0.11.0+wasi-snapshot-preview1",
 | 
				
			||||||
 "wasm-bindgen",
 | 
					 "wasm-bindgen",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "codespan-reporting"
 | 
				
			||||||
 | 
					version = "0.11.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "termcolor",
 | 
				
			||||||
 | 
					 "unicode-width",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "color_quant"
 | 
					name = "color_quant"
 | 
				
			||||||
version = "1.1.0"
 | 
					version = "1.1.0"
 | 
				
			||||||
@@ -752,10 +787,16 @@ dependencies = [
 | 
				
			|||||||
 "rand",
 | 
					 "rand",
 | 
				
			||||||
 "sha2",
 | 
					 "sha2",
 | 
				
			||||||
 "subtle",
 | 
					 "subtle",
 | 
				
			||||||
 "time",
 | 
					 "time 0.3.17",
 | 
				
			||||||
 "version_check",
 | 
					 "version_check",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "core-foundation-sys"
 | 
				
			||||||
 | 
					version = "0.8.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cpufeatures"
 | 
					name = "cpufeatures"
 | 
				
			||||||
version = "0.2.5"
 | 
					version = "0.2.5"
 | 
				
			||||||
@@ -861,6 +902,50 @@ dependencies = [
 | 
				
			|||||||
 "cipher",
 | 
					 "cipher",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cxx"
 | 
				
			||||||
 | 
					version = "1.0.81"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					 "cxxbridge-flags",
 | 
				
			||||||
 | 
					 "cxxbridge-macro",
 | 
				
			||||||
 | 
					 "link-cplusplus",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cxx-build"
 | 
				
			||||||
 | 
					version = "1.0.81"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					 "codespan-reporting",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "scratch",
 | 
				
			||||||
 | 
					 "syn",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cxxbridge-flags"
 | 
				
			||||||
 | 
					version = "1.0.81"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cxxbridge-macro"
 | 
				
			||||||
 | 
					version = "1.0.81"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "data-encoding"
 | 
					name = "data-encoding"
 | 
				
			||||||
version = "2.3.2"
 | 
					version = "2.3.2"
 | 
				
			||||||
@@ -1140,7 +1225,7 @@ dependencies = [
 | 
				
			|||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "js-sys",
 | 
					 "js-sys",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "wasi",
 | 
					 "wasi 0.11.0+wasi-snapshot-preview1",
 | 
				
			||||||
 "wasm-bindgen",
 | 
					 "wasm-bindgen",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1322,6 +1407,30 @@ version = "2.1.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 | 
					checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "iana-time-zone"
 | 
				
			||||||
 | 
					version = "0.1.53"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "android_system_properties",
 | 
				
			||||||
 | 
					 "core-foundation-sys",
 | 
				
			||||||
 | 
					 "iana-time-zone-haiku",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "iana-time-zone-haiku"
 | 
				
			||||||
 | 
					version = "0.1.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cxx",
 | 
				
			||||||
 | 
					 "cxx-build",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "idna"
 | 
					name = "idna"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.3.0"
 | 
				
			||||||
@@ -1516,6 +1625,15 @@ version = "0.2.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
 | 
					checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "link-cplusplus"
 | 
				
			||||||
 | 
					version = "1.0.7"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "local-channel"
 | 
					name = "local-channel"
 | 
				
			||||||
version = "0.1.3"
 | 
					version = "0.1.3"
 | 
				
			||||||
@@ -1616,7 +1734,7 @@ checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "wasi",
 | 
					 "wasi 0.11.0+wasi-snapshot-preview1",
 | 
				
			||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2163,6 +2281,12 @@ version = "1.1.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 | 
					checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "scratch"
 | 
				
			||||||
 | 
					version = "1.0.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "sec1"
 | 
					name = "sec1"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.3.0"
 | 
				
			||||||
@@ -2424,6 +2548,17 @@ dependencies = [
 | 
				
			|||||||
 "weezl",
 | 
					 "weezl",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "time"
 | 
				
			||||||
 | 
					version = "0.1.44"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "wasi 0.10.0+wasi-snapshot-preview1",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "time"
 | 
					name = "time"
 | 
				
			||||||
version = "0.3.17"
 | 
					version = "0.3.17"
 | 
				
			||||||
@@ -2585,6 +2720,12 @@ dependencies = [
 | 
				
			|||||||
 "tinyvec",
 | 
					 "tinyvec",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-width"
 | 
				
			||||||
 | 
					version = "0.1.10"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "unicode-xid"
 | 
					name = "unicode-xid"
 | 
				
			||||||
version = "0.2.4"
 | 
					version = "0.2.4"
 | 
				
			||||||
@@ -2659,6 +2800,12 @@ version = "0.9.4"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 | 
					checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "wasi"
 | 
				
			||||||
 | 
					version = "0.10.0+wasi-snapshot-preview1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "wasi"
 | 
					name = "wasi"
 | 
				
			||||||
version = "0.11.0+wasi-snapshot-preview1"
 | 
					version = "0.11.0+wasi-snapshot-preview1"
 | 
				
			||||||
@@ -2888,7 +3035,7 @@ dependencies = [
 | 
				
			|||||||
 "oid-registry",
 | 
					 "oid-registry",
 | 
				
			||||||
 "rusticata-macros",
 | 
					 "rusticata-macros",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
 "time",
 | 
					 "time 0.3.17",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,3 +36,4 @@ webauthn-rs = { version = "0.4.7", features = ["danger-allow-state-serialisation
 | 
				
			|||||||
url = "2.3.1"
 | 
					url = "2.3.1"
 | 
				
			||||||
aes-gcm = { version = "0.10.1", features = ["aes"] }
 | 
					aes-gcm = { version = "0.10.1", features = ["aes"] }
 | 
				
			||||||
bincode = "1.3.3"
 | 
					bincode = "1.3.3"
 | 
				
			||||||
 | 
					chrono = "0.4.22"
 | 
				
			||||||
@@ -60,6 +60,7 @@ pub struct UpdateUserQuery {
 | 
				
			|||||||
    grant_type: String,
 | 
					    grant_type: String,
 | 
				
			||||||
    granted_clients: String,
 | 
					    granted_clients: String,
 | 
				
			||||||
    two_factor: String,
 | 
					    two_factor: String,
 | 
				
			||||||
 | 
					    clear_2fa_history: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn users_route(
 | 
					pub async fn users_route(
 | 
				
			||||||
@@ -114,10 +115,15 @@ pub async fn users_route(
 | 
				
			|||||||
                let temp_pass = rand_str(TEMPORARY_PASSWORDS_LEN);
 | 
					                let temp_pass = rand_str(TEMPORARY_PASSWORDS_LEN);
 | 
				
			||||||
                user.password = hash_password(&temp_pass).expect("Failed to hash password");
 | 
					                user.password = hash_password(&temp_pass).expect("Failed to hash password");
 | 
				
			||||||
                user.need_reset_password = true;
 | 
					                user.need_reset_password = true;
 | 
				
			||||||
 | 
					                user.last_successful_2fa = Default::default();
 | 
				
			||||||
                Some(temp_pass)
 | 
					                Some(temp_pass)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if update.0.clear_2fa_history.is_some() {
 | 
				
			||||||
 | 
					            user.last_successful_2fa = Default::default();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let res = users
 | 
					        let res = users
 | 
				
			||||||
            .send(users_actor::UpdateUserRequest(user.clone()))
 | 
					            .send(users_actor::UpdateUserRequest(user.clone()))
 | 
				
			||||||
            .await
 | 
					            .await
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					use std::net::IpAddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
 | 
					use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
 | 
				
			||||||
use crate::data::client::ClientID;
 | 
					use crate::data::client::ClientID;
 | 
				
			||||||
use crate::data::entity_manager::EntityManager;
 | 
					use crate::data::entity_manager::EntityManager;
 | 
				
			||||||
@@ -5,9 +8,7 @@ use crate::data::login_redirect::LoginRedirect;
 | 
				
			|||||||
use crate::data::totp_key::TotpKey;
 | 
					use crate::data::totp_key::TotpKey;
 | 
				
			||||||
use crate::data::webauthn_manager::WebauthnPubKey;
 | 
					use crate::data::webauthn_manager::WebauthnPubKey;
 | 
				
			||||||
use crate::utils::err::Res;
 | 
					use crate::utils::err::Res;
 | 
				
			||||||
use crate::utils::time::time;
 | 
					use crate::utils::time::{fmt_time, time};
 | 
				
			||||||
use std::collections::HashMap;
 | 
					 | 
				
			||||||
use std::net::IpAddr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub struct UserID(pub String);
 | 
					pub struct UserID(pub String);
 | 
				
			||||||
@@ -64,6 +65,19 @@ impl TwoFactor {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct Successful2FALogin {
 | 
				
			||||||
 | 
					    pub ip: IpAddr,
 | 
				
			||||||
 | 
					    pub time: u64,
 | 
				
			||||||
 | 
					    pub can_bypass_2fa: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Successful2FALogin {
 | 
				
			||||||
 | 
					    pub fn fmt_time(&self) -> String {
 | 
				
			||||||
 | 
					        fmt_time(self.time)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub struct User {
 | 
					pub struct User {
 | 
				
			||||||
    pub uid: UserID,
 | 
					    pub uid: UserID,
 | 
				
			||||||
@@ -175,6 +189,17 @@ impl User {
 | 
				
			|||||||
            })
 | 
					            })
 | 
				
			||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_formatted_2fa_successful_logins(&self) -> Vec<Successful2FALogin> {
 | 
				
			||||||
 | 
					        self.last_successful_2fa
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .map(|(ip, time)| Successful2FALogin {
 | 
				
			||||||
 | 
					                ip: *ip,
 | 
				
			||||||
 | 
					                time: *time,
 | 
				
			||||||
 | 
					                can_bypass_2fa: self.can_bypass_two_factors_for_ip(*ip),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl PartialEq for User {
 | 
					impl PartialEq for User {
 | 
				
			||||||
@@ -268,6 +293,7 @@ impl EntityManager<User> {
 | 
				
			|||||||
        self.update_user(id, |mut user| {
 | 
					        self.update_user(id, |mut user| {
 | 
				
			||||||
            user.password = new_hash;
 | 
					            user.password = new_hash;
 | 
				
			||||||
            user.need_reset_password = temporary;
 | 
					            user.need_reset_password = temporary;
 | 
				
			||||||
 | 
					            user.two_factor_exemption_after_successful_login = Default::default();
 | 
				
			||||||
            user
 | 
					            user
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use chrono::{DateTime, NaiveDateTime, Utc};
 | 
				
			||||||
use std::time::{SystemTime, UNIX_EPOCH};
 | 
					use std::time::{SystemTime, UNIX_EPOCH};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get the current time since epoch
 | 
					/// Get the current time since epoch
 | 
				
			||||||
@@ -7,3 +8,16 @@ pub fn time() -> u64 {
 | 
				
			|||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
        .as_secs()
 | 
					        .as_secs()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Format unix timestamp to a human-readable string
 | 
				
			||||||
 | 
					pub fn fmt_time(timestamp: u64) -> String {
 | 
				
			||||||
 | 
					    // Create a NaiveDateTime from the timestamp
 | 
				
			||||||
 | 
					    let naive =
 | 
				
			||||||
 | 
					        NaiveDateTime::from_timestamp_opt(timestamp as i64, 0).expect("Failed to parse timestamp!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create a normal DateTime from the NaiveDateTime
 | 
				
			||||||
 | 
					    let datetime: DateTime<Utc> = DateTime::from_utc(naive, Utc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Format the datetime how you want
 | 
				
			||||||
 | 
					    datetime.format("%Y-%m-%d %H:%M:%S").to_string()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,6 +98,28 @@
 | 
				
			|||||||
    </fieldset>
 | 
					    </fieldset>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Two factor authentication history -->
 | 
				
			||||||
 | 
					    {% if !u.last_successful_2fa.is_empty() %}
 | 
				
			||||||
 | 
					    <fieldset class="form-group">
 | 
				
			||||||
 | 
					        <legend class="mt-4">Last successful 2FA authentications</legend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Clear 2FA history -->
 | 
				
			||||||
 | 
					        <div class="form-check">
 | 
				
			||||||
 | 
					            <input class="form-check-input" type="checkbox" name="clear_2fa_history" id="clear_2fa_history">
 | 
				
			||||||
 | 
					            <label class="form-check-label" for="clear_2fa_history">
 | 
				
			||||||
 | 
					                Clear 2FA authentication history
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <ul>
 | 
				
			||||||
 | 
					        {% for e in u.get_formatted_2fa_successful_logins() %}
 | 
				
			||||||
 | 
					            {% if e.can_bypass_2fa %}<li style="font-weight: bold;">{{ e.ip }} - {{ e.fmt_time() }} - BYPASS 2FA</li>
 | 
				
			||||||
 | 
					            {% else %}<li>{{ e.ip }} - {{ e.fmt_time() }}</li>{% endif %}
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					    </fieldset>
 | 
				
			||||||
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Granted clients -->
 | 
					    <!-- Granted clients -->
 | 
				
			||||||
    <fieldset class="form-group">
 | 
					    <fieldset class="form-group">
 | 
				
			||||||
        <legend class="mt-4">Granted clients</legend>
 | 
					        <legend class="mt-4">Granted clients</legend>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user