mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-07 16:50:13 +00:00
Merge pull request #93 from EETagent/12_letter_code
This commit is contained in:
commit
91d567ba5a
4 changed files with 50 additions and 30 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
use portfolio_core::{
|
use portfolio_core::{
|
||||||
crypto::random_8_char_string,
|
crypto::random_12_char_string,
|
||||||
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService, portfolio_service::PortfolioService}, models::candidate::{BaseCandidateResponse, CreateCandidateResponse, ApplicationDetails}, sea_orm::prelude::Uuid, Query, error::ServiceError, utils::csv,
|
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService, portfolio_service::PortfolioService}, models::candidate::{BaseCandidateResponse, CreateCandidateResponse, ApplicationDetails}, sea_orm::prelude::Uuid, Query, error::ServiceError, utils::csv,
|
||||||
};
|
};
|
||||||
use requests::{AdminLoginRequest, RegisterRequest};
|
use requests::{AdminLoginRequest, RegisterRequest};
|
||||||
|
|
@ -90,7 +90,7 @@ pub async fn create_candidate(
|
||||||
let db = conn.into_inner();
|
let db = conn.into_inner();
|
||||||
let form = request.into_inner();
|
let form = request.into_inner();
|
||||||
|
|
||||||
let plain_text_password = random_8_char_string();
|
let plain_text_password = random_12_char_string();
|
||||||
|
|
||||||
ApplicationService::create_candidate_with_parent(
|
ApplicationService::create_candidate_with_parent(
|
||||||
db,
|
db,
|
||||||
|
|
@ -287,6 +287,6 @@ pub mod tests {
|
||||||
let cookies = admin_login(&client);
|
let cookies = admin_login(&client);
|
||||||
let response = create_candidate(&client, cookies, 1031511, "0".to_string());
|
let response = create_candidate(&client, cookies, 1031511, "0".to_string());
|
||||||
|
|
||||||
assert_eq!(response.password.len(), 8);
|
assert_eq!(response.password.len(), 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,24 +13,29 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use crate::error::ServiceError;
|
use crate::error::ServiceError;
|
||||||
|
|
||||||
/// Foolproof random 8 char string
|
/// Foolproof random 12 char string
|
||||||
/// only uppercase letters (except for 0 and O) and numbers
|
/// Only uppercase letters (except for O) and numbers (except for 0)
|
||||||
pub fn random_8_char_string() -> String {
|
pub fn random_12_char_string() -> String {
|
||||||
let iterator = rand::thread_rng()
|
let random_chars_12: Vec<char> = rand::thread_rng()
|
||||||
.sample_iter(&rand::distributions::Alphanumeric)
|
.sample_iter(&rand::distributions::Alphanumeric)
|
||||||
.map(char::from);
|
.map(char::from)
|
||||||
|
.filter(is_usable_char)
|
||||||
|
.take(12)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
random_chars_12
|
||||||
|
.iter()
|
||||||
|
.map(|c| c.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")
|
||||||
|
}
|
||||||
|
|
||||||
let mut s = String::new();
|
/// Exclude O and 0, lowercase letters
|
||||||
for c in iterator {
|
fn is_usable_char(c: &char) -> bool {
|
||||||
// add all characters except for: lowercase chars, 0 and O
|
('1'..='9').contains(&c) ||
|
||||||
if ('1'..='9').contains(&c) || ('A'..='N').contains(&c) || ('P'..'Z').contains(&c) {
|
('A'..='N').contains(&c) ||
|
||||||
s.push(c);
|
('P'..'Z').contains(&c) ||
|
||||||
if s.len() == 8 {
|
['@', '#', '$', '%'].contains(&c)
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn hash_password(password_plain_text: String) -> Result<String, ServiceError> {
|
pub async fn hash_password(password_plain_text: String) -> Result<String, ServiceError> {
|
||||||
|
|
@ -334,11 +339,11 @@ pub async fn decrypt_file_with_private_key_as_buffer<P: AsRef<Path>>(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_random_8_char_string() {
|
fn test_random_12_char_string() {
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let s = super::random_8_char_string();
|
let s = super::random_12_char_string();
|
||||||
// Is 8 chars long
|
// Is 8 chars long
|
||||||
assert_eq!(s.len(), 8);
|
assert_eq!(s.len(), 12);
|
||||||
// Does not contain possibly confusing characters
|
// Does not contain possibly confusing characters
|
||||||
assert!(!s.contains('0'));
|
assert!(!s.contains('0'));
|
||||||
assert!(!s.contains('O'));
|
assert!(!s.contains('O'));
|
||||||
|
|
@ -388,7 +393,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert!(key_2.len() >= 32);
|
assert!(key_2.len() >= 32);
|
||||||
|
|
||||||
let key_3 = super::convert_key_aes256(&super::random_8_char_string());
|
let key_3 = super::convert_key_aes256(&super::random_12_char_string());
|
||||||
assert!(key_3.len() >= 32);
|
assert!(key_3.len() >= 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ impl CandidateService {
|
||||||
let parents = Query::find_candidate_parents(db, &candidate).await?;
|
let parents = Query::find_candidate_parents(db, &candidate).await?;
|
||||||
|
|
||||||
|
|
||||||
let new_password_plain = crypto::random_8_char_string();
|
let new_password_plain = crypto::random_12_char_string();
|
||||||
let new_password_hash = crypto::hash_password(new_password_plain.clone()).await?;
|
let new_password_hash = crypto::hash_password(new_password_plain.clone()).await?;
|
||||||
|
|
||||||
let (pubkey, priv_key_plain_text) = crypto::create_identity();
|
let (pubkey, priv_key_plain_text) = crypto::create_identity();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
codeValueMobile = codeValueArray.join('');
|
codeValueMobile = codeValueArray.join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
$: if (codeValueArray.length === 8) {
|
$: if (codeValueArray.length === 12) {
|
||||||
submit();
|
submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
<span class="bg-sspsBlue mr-2 hidden h-2 w-8 sm:block" />
|
<span class="separater" />
|
||||||
{#each [5, 6, 7, 8] as value}
|
{#each [5, 6, 7, 8] as value}
|
||||||
<input
|
<input
|
||||||
class="codeInputDesktop"
|
class="codeInputDesktop"
|
||||||
|
|
@ -100,9 +100,20 @@
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
<span class="separater" />
|
||||||
|
{#each [9, 10, 11, 12] as value}
|
||||||
|
<input
|
||||||
|
class="codeInputDesktop"
|
||||||
|
bind:this={codeElementArray[value - 1]}
|
||||||
|
bind:value={codeValueArray[value - 1]}
|
||||||
|
on:keydown={(e) => inputDesktopOnKeyDown(value - 1, e)}
|
||||||
|
on:paste|preventDefault={(e) => onPaste(e)}
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-sspsBlue mx-8 mt-8 text-center text-xl font-semibold">
|
<h3 class="text-sspsBlue mx-8 mt-8 text-center text-xl font-semibold">
|
||||||
Zadejte 8místný kód pro aktivaci účtu
|
Zadejte 12místný kód pro aktivaci účtu
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sspsGray mx-8 mt-8 text-center">Nevíte si rady? Klikněte <u>zde</u></p>
|
<p class="text-sspsGray mx-8 mt-8 text-center">Nevíte si rady? Klikněte <u>zde</u></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -118,15 +129,19 @@
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
@apply text-sspsBlue text-center font-semibold;
|
@apply text-sspsBlue text-center font-semibold;
|
||||||
@apply focus:border-sspsBlue hover:border-sspsBlue rounded-xl border border-2 bg-[#f8fafb] p-3 caret-transparent shadow-lg outline-none transition-colors duration-300;
|
@apply transition-colors duration-300;
|
||||||
|
@apply focus:border-sspsBlue hover:border-sspsBlue rounded-xl border border-2 bg-[#f8fafb] p-3 caret-transparent shadow-lg outline-none;
|
||||||
|
}
|
||||||
|
.separater {
|
||||||
|
@apply bg-sspsBlue mr-2 hidden h-2 w-8 md:block;
|
||||||
}
|
}
|
||||||
.codeInputMobile {
|
.codeInputMobile {
|
||||||
@apply sm:hidden;
|
@apply md:hidden;
|
||||||
@apply mx-5 w-full;
|
@apply mx-5 w-full;
|
||||||
}
|
}
|
||||||
.codeInputDesktop {
|
.codeInputDesktop {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
@apply mr-1 md:mr-2;
|
@apply mr-1 md:mr-2;
|
||||||
@apply sm:h-15 xl:w-18 xl:h-22 sm:block sm:w-12 sm:text-xl md:h-20 md:w-16 md:text-4xl xl:p-0 xl:text-4xl;
|
@apply sm:h-15 2xl:w-18 2xl:h-22 sm:w-12 sm:text-xl md:block md:h-20 md:w-16 md:text-4xl xl:h-20 xl:w-16 xl:p-0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue