Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions seedelf-platform/seedelf-cli/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,16 @@ pub fn check_and_prepare_seedelf() -> Option<String> {

/// Prompt the user to enter a wallet name
pub fn prompt_wallet_name() -> String {
let mut wallet_name = String::new();
let mut wallet_name: String = String::new();
println!("{}", "\nEnter A Wallet Name:".bright_purple());
io::stdout().flush().unwrap();
io::stdin()
.read_line(&mut wallet_name)
.expect("Failed to read wallet name");
let final_name: String = wallet_name.trim().to_string();
let final_name: String = wallet_name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
if final_name.is_empty() {
println!("{}", "Wallet Must Not Have Empty Name.".red());
return prompt_wallet_name();
Expand Down
54 changes: 54 additions & 0 deletions seedelf-platform/seedelf-cli/tests/setup_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,57 @@ fn test_good_password() {
let pw: String = "i@G37xzM@qcgk3g".to_string();
assert_eq!(password_complexity_check(pw), true)
}

#[test]
fn test_remove_white_spaces_no_spaces() {
let name: String = "NoSpacesHere".to_string();
let final_name = name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
assert_eq!(name, final_name)
}

#[test]
fn test_remove_white_spaces_single_spaces() {
let name: String = "Single Space".to_string();
let final_name: String = name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
let expected: String = "Single_Space".to_string();
assert_eq!(expected, final_name)
}

#[test]
fn test_remove_white_spaces_multiple_spaces() {
let name: String = "Multiple Space".to_string();
let final_name: String = name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
let expected: String = "Multiple_Space".to_string();
assert_eq!(expected, final_name)
}

#[test]
fn test_remove_white_spaces_tab() {
let name: String = "Tab Space".to_string();
let final_name: String = name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
let expected: String = "Tab_Space".to_string();
assert_eq!(expected, final_name)
}

#[test]
fn test_remove_white_spaces_trailing() {
let name: String = " Single Space ".to_string();
let final_name: String = name
.split_whitespace() // breaks on any whitespace sequence
.collect::<Vec<_>>() // collect the pieces
.join("_");
let expected: String = "Single_Space".to_string();
assert_eq!(expected, final_name)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ interface PasswordFieldProps {
label: string;
value: string;
onChange: (v: string) => void;
disabled?: boolean;
}

export function PasswordField({ label, value, onChange }: PasswordFieldProps) {
export function PasswordField({ label, value, onChange, disabled }: PasswordFieldProps) {
const [show, setShow] = useState(false);
return (
<label className="flex flex-col gap-1 text-sm">
{label}
<div className="relative">
<input
disabled={disabled}
type={show ? "text" : "password"}
value={value}
onChange={(e) => onChange(e.target.value)}
className="w-full rounded border px-3 py-2 pr-10 focus:outline-none focus:ring"
/>
<button
type="button"
disabled={disabled}
onClick={() => setShow((x) => !x)}
className="absolute right-2 top-1/2 -translate-y-1/2 text-xs"
>
Expand Down
19 changes: 14 additions & 5 deletions seedelf-platform/seedelf-gui/src/pages/NewWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ export function NewWalletPage() {
const [confirm, setConfirm] = useState("");
const [message, setMessage] = useState<string | null>(null);
const [variant, setVariant] = useState<NotificationVariant>("error");
const [submitting, setSubmitting] = useState(false);

const navigate = useNavigate();

const handleSubmit = async () => {
// Simple custom rules – adjust as needed
if (!name.trim()) return setMessage("Wallet name is required.");
// spaces should be underscores
const walletName: string = name.trim().replace(/\s+/g, "_");

const isStrong = await invoke<boolean>("check_password_complexity", {password: pw});
if (!isStrong) return setMessage(`Passwords Must Contain The Following:
Expand All @@ -27,10 +30,14 @@ export function NewWalletPage() {
Number: Requires At Least One Digit.
Special Character: Requires At Least One Special Symbol.`);
if (pw !== confirm) return setMessage("Passwords do not match.");

setSubmitting(true);
let success = false;
try {
await invoke("create_new_wallet", { walletName: name, password: pw });
await invoke("create_new_wallet", { walletName: walletName, password: pw });
const walletExists = await invoke<WalletExistsResult>("check_if_wallet_exists");
if (walletExists) {
success = true;
setMessage(`Wallet Was Created!`);
setVariant('success');
setTimeout(() => navigate("/wallet/"), 2718);
Expand All @@ -41,6 +48,8 @@ export function NewWalletPage() {
}
} catch (e: any) {
setMessage(e as string);
} finally {
if (!success) setSubmitting(false);
}
};

Expand All @@ -50,10 +59,10 @@ export function NewWalletPage() {

<ShowNotification message={message} setMessage={setMessage} variant={variant} />

<TextField label="Wallet name" value={name} onChange={(e) => setName(e.target.value)} />
<TextField label="Wallet name" value={name} onChange={(e) => setName(e.target.value)} disabled={submitting}/>

<PasswordField label="Password" value={pw} onChange={setPw} />
<PasswordField label="Confirm password" value={confirm} onChange={setConfirm} />
<PasswordField label="Password" value={pw} onChange={setPw} disabled={submitting}/>
<PasswordField label="Confirm password" value={confirm} onChange={setConfirm} disabled={submitting}/>

<div className="flex items-center justify-between">
<button onClick={() => navigate("/")} className="rounded px-3 py-2 text-sm underline">
Expand All @@ -63,7 +72,7 @@ export function NewWalletPage() {
<button
onClick={handleSubmit}
className="rounded bg-blue-600 px-4 py-2 text-sm text-white disabled:opacity-50"
disabled={!name || !pw || !confirm}
disabled={submitting || !name || !pw || !confirm}
>
Create
</button>
Expand Down