~core/sage

ref: a5ea94fd04873a203d0a5e2066ca4177c5102c93 sage/src/cmds/createid.rs -rw-r--r-- 1.5 KiB
a5ea94fd — core feat: better err msg 21 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::db::Database;
use crate::identity::{IdKeyData, Identity};
use age::secrecy::ExposeSecret;
use regex::Regex;
use std::path::Path;
use std::process::exit;

pub fn create_id(db_path: &Path, name: String, email: String) -> anyhow::Result<()> {
    let mut db = Database::load_or_create(db_path)?;

    // sanity check to ensure this id does not already exist
    for key in &db.keys {
        if key.name == name && key.email == email {
            eprintln!(
                "key '{:?}' (keyid {}) already exists  in database",
                key,
                key.keys.keyid()?
            );
            eprintln!("if you want to recreate it, remove it first");
            exit(1);
        }
    }

    // Email is a fucking nightmare
    // RFC5322, I hate you
    let email_re = Regex::new(
        r#"(?x)
            ^(?P<login>[^@\s]+)@
            ([[:word:]]+\.)*
            [[:word:]]+$
            "#,
    )
    .unwrap();

    if !email_re.is_match(&email) {
        eprintln!("`{email}` is not a valid RFC5322 email address");
        exit(1);
    }

    let key = age::x25519::Identity::generate();
    let ss = key.to_string();
    let ss = ss.expose_secret();

    let identity = Identity {
        name,
        email,
        keys: IdKeyData::Local(ss.to_string()),
    };

    db.keys.push(identity.clone());
    // save database
    db.write(db_path)?;

    println!(
        "wrote new key {:?} (keyid {}) to database",
        identity,
        identity.keys.keyid()?
    );

    Ok(())
}