Compare commits

...
3 Commits
Author SHA1 Message Date
reya 2eab6f04c7 chore: bump version 2024-08-30 13:30:29 +07:00
reya e06b0334a5 chore: bump version 2024-08-29 08:00:58 +07:00
reya 74d8bf2ead fix: cannot import ncryptsec 2024-08-29 07:48:26 +07:00
17 changed files with 8362 additions and 6239 deletions
+25 -25
View File
@@ -19,28 +19,28 @@
"@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/query-persist-client-core": "^5.51.21", "@tanstack/query-persist-client-core": "^5.52.3",
"@tanstack/react-query": "^5.51.23", "@tanstack/react-query": "^5.52.3",
"@tanstack/react-router": "^1.48.1", "@tanstack/react-router": "^1.51.6",
"@tanstack/react-store": "^0.5.5", "@tanstack/react-store": "^0.5.5",
"@tanstack/store": "^0.5.5", "@tanstack/store": "^0.5.5",
"@tauri-apps/api": "2.0.0-rc.1", "@tauri-apps/api": "2.0.0-rc.4",
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.0", "@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.1",
"@tauri-apps/plugin-dialog": "2.0.0-rc.0", "@tauri-apps/plugin-dialog": "2.0.0-rc.1",
"@tauri-apps/plugin-fs": "2.0.0-rc.1", "@tauri-apps/plugin-fs": "2.0.0-rc.2",
"@tauri-apps/plugin-http": "2.0.0-rc.1", "@tauri-apps/plugin-http": "2.0.0-rc.2",
"@tauri-apps/plugin-os": "2.0.0-rc.0", "@tauri-apps/plugin-os": "2.0.0-rc.1",
"@tauri-apps/plugin-process": "2.0.0-rc.0", "@tauri-apps/plugin-process": "2.0.0-rc.1",
"@tauri-apps/plugin-shell": "2.0.0-rc.0", "@tauri-apps/plugin-shell": "2.0.0-rc.1",
"@tauri-apps/plugin-store": "2.0.0-rc.0", "@tauri-apps/plugin-store": "2.0.0-rc.1",
"@tauri-apps/plugin-updater": "2.0.0-rc.0", "@tauri-apps/plugin-updater": "2.0.0-rc.1",
"@tauri-apps/plugin-upload": "2.0.0-rc.0", "@tauri-apps/plugin-upload": "2.0.0-rc.1",
"@tauri-apps/plugin-window-state": "2.0.0-rc.0", "@tauri-apps/plugin-window-state": "2.0.0-rc.1",
"bitcoin-units": "^1.0.0", "bitcoin-units": "^1.0.0",
"boring-avatars": "^1.10.2", "boring-avatars": "^1.10.2",
"dayjs": "^1.11.12", "dayjs": "^1.11.13",
"embla-carousel-react": "^8.1.8", "embla-carousel-react": "^8.2.0",
"i18next": "^23.13.0", "i18next": "^23.14.0",
"i18next-resources-to-backend": "^1.2.1", "i18next-resources-to-backend": "^1.2.1",
"light-bolt11-decoder": "^3.1.1", "light-bolt11-decoder": "^3.1.1",
"minidenticons": "^4.2.1", "minidenticons": "^4.2.1",
@@ -49,7 +49,7 @@
"react": "19.0.0-rc-d025ddd3-20240722", "react": "19.0.0-rc-d025ddd3-20240722",
"react-currency-input-field": "^3.8.0", "react-currency-input-field": "^3.8.0",
"react-dom": "19.0.0-rc-d025ddd3-20240722", "react-dom": "19.0.0-rc-d025ddd3-20240722",
"react-hook-form": "^7.52.2", "react-hook-form": "^7.53.0",
"react-i18next": "^15.0.1", "react-i18next": "^15.0.1",
"react-string-replace": "^1.1.1", "react-string-replace": "^1.1.1",
"slate": "^0.103.0", "slate": "^0.103.0",
@@ -60,11 +60,11 @@
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.8.3", "@biomejs/biome": "^1.8.3",
"@evilmartians/harmony": "^1.2.0", "@evilmartians/harmony": "^1.2.0",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.8",
"@tailwindcss/typography": "^0.5.14", "@tailwindcss/typography": "^0.5.15",
"@tanstack/router-devtools": "^1.48.1", "@tanstack/router-devtools": "^1.51.6",
"@tanstack/router-plugin": "^1.47.0", "@tanstack/router-plugin": "^1.51.6",
"@tauri-apps/cli": "2.0.0-rc.4", "@tauri-apps/cli": "2.0.0-rc.8",
"@types/react": "npm:types-react@19.0.0-rc.1", "@types/react": "npm:types-react@19.0.0-rc.1",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
@@ -78,7 +78,7 @@
"tailwindcss": "^3.4.10", "tailwindcss": "^3.4.10",
"tailwindcss-content-visibility": "^0.2.0", "tailwindcss-content-visibility": "^0.2.0",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vite": "^5.4.1", "vite": "^5.4.2",
"vite-tsconfig-paths": "^5.0.1" "vite-tsconfig-paths": "^5.0.1"
}, },
"overrides": { "overrides": {
+380 -380
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -5,3 +5,6 @@
# Generated by Tauri # Generated by Tauri
# will have schema files for capabilities auto-completion # will have schema files for capabilities auto-completion
/gen/schemas /gen/schemas
# Config
.cargo
+250 -585
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -35,7 +35,6 @@ tauri-plugin-shell = "2.0.0-rc"
tauri-plugin-updater = "2.0.0-rc" tauri-plugin-updater = "2.0.0-rc"
tauri-plugin-upload = "2.0.0-rc" tauri-plugin-upload = "2.0.0-rc"
tauri-plugin-store = "2.0.0-rc" tauri-plugin-store = "2.0.0-rc"
tauri-plugin-theme = "0.4.1"
tauri-plugin-decorum = "1.0.0" tauri-plugin-decorum = "1.0.0"
tauri-plugin-prevent-default = "0.4" tauri-plugin-prevent-default = "0.4"
tauri-specta = { version = "2.0.0-rc.15", features = ["derive", "typescript"] } tauri-specta = { version = "2.0.0-rc.15", features = ["derive", "typescript"] }
+1 -3
View File
@@ -41,8 +41,8 @@
"core:window:allow-minimize", "core:window:allow-minimize",
"core:window:allow-maximize", "core:window:allow-maximize",
"core:window:allow-set-size", "core:window:allow-set-size",
"core:window:allow-set-focus",
"core:window:allow-start-dragging", "core:window:allow-start-dragging",
"core:window:allow-toggle-maximize",
"decorum:allow-show-snap-overlay", "decorum:allow-show-snap-overlay",
"clipboard-manager:allow-write-text", "clipboard-manager:allow-write-text",
"clipboard-manager:allow-read-text", "clipboard-manager:allow-read-text",
@@ -57,8 +57,6 @@
"process:allow-restart", "process:allow-restart",
"process:allow-exit", "process:allow-exit",
"fs:allow-read-file", "fs:allow-read-file",
"theme:allow-set-theme",
"theme:allow-get-theme",
"core:menu:allow-new", "core:menu:allow-new",
"core:menu:allow-popup", "core:menu:allow-popup",
"shell:allow-open", "shell:allow-open",
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","panel","settings","search-*","zap-*","event-*","user-*","editor-*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","core:window:allow-create","core:window:allow-close","core:window:allow-destroy","core:window:allow-set-focus","core:window:allow-center","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-set-size","core:window:allow-set-focus","core:window:allow-start-dragging","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-size","core:webview:allow-set-webview-position","core:webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","process:allow-exit","fs:allow-read-file","theme:allow-set-theme","theme:allow-get-theme","core:menu:allow-new","core:menu:allow-popup","shell:allow-open","store:allow-get","store:allow-set","store:allow-delete","prevent-default:default",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["macOS","windows"]}} {"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","panel","settings","search-*","zap-*","event-*","user-*","editor-*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","core:window:allow-create","core:window:allow-close","core:window:allow-destroy","core:window:allow-set-focus","core:window:allow-center","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-set-size","core:window:allow-start-dragging","core:window:allow-toggle-maximize","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-size","core:webview:allow-set-webview-position","core:webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","process:allow-exit","fs:allow-read-file","core:menu:allow-new","core:menu:allow-popup","shell:allow-open","store:allow-get","store:allow-set","store:allow-delete","prevent-default:default",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["macOS","windows"]}}
-34
View File
@@ -7376,40 +7376,6 @@
"store:deny-values" "store:deny-values"
] ]
}, },
{
"type": "string",
"enum": [
"theme:default"
]
},
{
"description": "theme:allow-get-theme -> Enables the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-get-theme"
]
},
{
"description": "theme:allow-set-theme -> Enables the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:allow-set-theme"
]
},
{
"description": "theme:deny-get-theme -> Denies the get_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-get-theme"
]
},
{
"description": "theme:deny-set-theme -> Denies the set_theme command without any pre-configured scope.",
"type": "string",
"enum": [
"theme:deny-set-theme"
]
},
{ {
"description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n", "description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n",
"type": "string", "type": "string",
File diff suppressed because it is too large Load Diff
+24 -22
View File
@@ -44,7 +44,7 @@ pub async fn create_account(
let client = &state.client; let client = &state.client;
let keys = Keys::generate(); let keys = Keys::generate();
let npub = keys.public_key().to_bech32().map_err(|e| e.to_string())?; let npub = keys.public_key().to_bech32().map_err(|e| e.to_string())?;
let secret_key = keys.secret_key().map_err(|e| e.to_string())?; let secret_key = keys.secret_key();
let enc = EncryptedSecretKey::new(secret_key, password, 16, KeySecurity::Medium) let enc = EncryptedSecretKey::new(secret_key, password, 16, KeySecurity::Medium)
.map_err(|err| err.to_string())?; .map_err(|err| err.to_string())?;
let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?; let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
@@ -80,38 +80,40 @@ pub async fn create_account(
#[tauri::command] #[tauri::command]
#[specta::specta] #[specta::specta]
pub async fn import_account( pub async fn import_account(key: String, password: String) -> Result<String, String> {
key: String, let (npub, enc_bech32) = match key.starts_with("ncryptsec") {
password: Option<String>, true => {
state: State<'_, Nostr>, let enc = EncryptedSecretKey::from_bech32(key).map_err(|err| err.to_string())?;
) -> Result<String, String> { let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
let client = &state.client; let secret_key = enc.to_secret_key(password).map_err(|err| err.to_string())?;
let secret_key = SecretKey::from_bech32(key).map_err(|err| err.to_string())?; let keys = Keys::new(secret_key);
let keys = Keys::new(secret_key.clone()); let npub = keys.public_key().to_bech32().unwrap();
let npub = keys.public_key().to_bech32().unwrap();
let enc_bech32 = match password { (npub, enc_bech32)
Some(pw) => { }
let enc = EncryptedSecretKey::new(&secret_key, pw, 16, KeySecurity::Medium) false => {
let secret_key = SecretKey::from_bech32(key).map_err(|err| err.to_string())?;
let keys = Keys::new(secret_key.clone());
let npub = keys.public_key().to_bech32().unwrap();
let enc = EncryptedSecretKey::new(&secret_key, password, 16, KeySecurity::Medium)
.map_err(|err| err.to_string())?; .map_err(|err| err.to_string())?;
enc.to_bech32().map_err(|err| err.to_string())? let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
(npub, enc_bech32)
} }
None => secret_key.to_bech32().map_err(|err| err.to_string())?,
}; };
let keyring = Entry::new("Lume Secret Storage", &npub).map_err(|e| e.to_string())?; let keyring = Entry::new("Lume Secret Storage", &npub).map_err(|e| e.to_string())?;
let account = Account { let account = Account {
password: enc_bech32, password: enc_bech32,
nostr_connect: None, nostr_connect: None,
}; };
let j = serde_json::to_string(&account).map_err(|e| e.to_string())?;
let _ = keyring.set_password(&j);
let signer = NostrSigner::Keys(keys); let pwd = serde_json::to_string(&account).map_err(|e| e.to_string())?;
keyring.set_password(&pwd).map_err(|e| e.to_string())?;
// Update client's signer
client.set_signer(Some(signer)).await;
Ok(npub) Ok(npub)
} }
@@ -125,7 +127,7 @@ pub async fn connect_account(uri: String, state: State<'_, Nostr>) -> Result<Str
Ok(bunker_uri) => { Ok(bunker_uri) => {
// Local user // Local user
let app_keys = Keys::generate(); let app_keys = Keys::generate();
let app_secret = app_keys.secret_key().unwrap().to_string(); let app_secret = app_keys.secret_key().to_string();
// Get remote user // Get remote user
let remote_user = bunker_uri.signer_public_key().unwrap(); let remote_user = bunker_uri.signer_public_key().unwrap();
+3 -3
View File
@@ -206,7 +206,7 @@ pub async fn set_lume_store(
let public_key = signer.public_key().await.map_err(|e| e.to_string())?; let public_key = signer.public_key().await.map_err(|e| e.to_string())?;
let encrypted = signer let encrypted = signer
.nip44_encrypt(public_key, content) .nip44_encrypt(&public_key, content)
.await .await
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
let tag = Tag::identifier(key); let tag = Tag::identifier(key);
@@ -237,7 +237,7 @@ pub async fn get_lume_store(key: String, state: State<'_, Nostr>) -> Result<Stri
{ {
Ok(events) => { Ok(events) => {
if let Some(event) = get_latest_event(&events) { if let Some(event) = get_latest_event(&events) {
match signer.nip44_decrypt(public_key, event.content()).await { match signer.nip44_decrypt(&public_key, &event.content).await {
Ok(decrypted) => Ok(decrypted), Ok(decrypted) => Ok(decrypted),
Err(_) => Err(event.content.to_string()), Err(_) => Err(event.content.to_string()),
} }
@@ -522,7 +522,7 @@ pub async fn set_settings(
let signer = client.signer().await.map_err(|e| e.to_string())?; let signer = client.signer().await.map_err(|e| e.to_string())?;
let public_key = signer.public_key().await.map_err(|e| e.to_string())?; let public_key = signer.public_key().await.map_err(|e| e.to_string())?;
let encrypted = signer let encrypted = signer
.nip44_encrypt(public_key, settings) .nip44_encrypt(&public_key, settings)
.await .await
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
let tag = Tag::identifier(ident); let tag = Tag::identifier(ident);
+1 -2
View File
@@ -329,8 +329,7 @@ pub async fn get_user_settings(client: &Client) -> Result<Settings, String> {
{ {
Ok(events) => { Ok(events) => {
if let Some(event) = events.first() { if let Some(event) = events.first() {
let content = event.content(); match signer.nip44_decrypt(&public_key, &event.content).await {
match signer.nip44_decrypt(public_key, content).await {
Ok(decrypted) => match serde_json::from_str(&decrypted) { Ok(decrypted) => match serde_json::from_str(&decrypted) {
Ok(parsed) => Ok(parsed), Ok(parsed) => Ok(parsed),
Err(_) => Err("Could not parse settings payload".into()), Err(_) => Err("Could not parse settings payload".into()),
+1 -4
View File
@@ -156,8 +156,6 @@ fn main() {
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
let tauri_builder = tauri::Builder::default(); let tauri_builder = tauri::Builder::default();
let mut ctx = tauri::generate_context!();
tauri_builder tauri_builder
.invoke_handler(builder.invoke_handler()) .invoke_handler(builder.invoke_handler())
.setup(move |app| { .setup(move |app| {
@@ -364,7 +362,6 @@ fn main() {
Ok(()) Ok(())
}) })
.plugin(prevent_default()) .plugin(prevent_default())
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
.plugin(tauri_plugin_decorum::init()) .plugin(tauri_plugin_decorum::init())
.plugin(tauri_plugin_store::Builder::default().build()) .plugin(tauri_plugin_store::Builder::default().build())
.plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_clipboard_manager::init())
@@ -377,7 +374,7 @@ fn main() {
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_upload::init()) .plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_updater::Builder::new().build()) .plugin(tauri_plugin_updater::Builder::new().build())
.run(ctx) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/schema.json", "$schema": "../node_modules/@tauri-apps/cli/schema.json",
"productName": "Lume", "productName": "Lume",
"version": "4.1.0", "version": "4.1.2",
"identifier": "nu.lume.Lume", "identifier": "nu.lume.Lume",
"build": { "build": {
"beforeDevCommand": "pnpm dev", "beforeDevCommand": "pnpm dev",
+1 -1
View File
@@ -56,7 +56,7 @@ async createAccount(name: string, about: string, picture: string, password: stri
else return { status: "error", error: e as any }; else return { status: "error", error: e as any };
} }
}, },
async importAccount(key: string, password: string | null) : Promise<Result<string, string>> { async importAccount(key: string, password: string) : Promise<Result<string, string>> {
try { try {
return { status: "ok", data: await TAURI_INVOKE("import_account", { key, password }) }; return { status: "ok", data: await TAURI_INVOKE("import_account", { key, password }) };
} catch (e) { } catch (e) {
+4 -2
View File
@@ -95,13 +95,15 @@ function Screen() {
</button> </button>
</div> </div>
</div> </div>
{key.length && !key.startsWith("ncryptsec") ? ( {key.length ? (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<label <label
htmlFor="password" htmlFor="password"
className="text-sm font-medium text-neutral-800 dark:text-neutral-200" className="text-sm font-medium text-neutral-800 dark:text-neutral-200"
> >
Set password to secure your key {!key.startsWith("ncryptsec")
? "Set password to secure your key"
: "Enter password to decrypt your key"}
</label> </label>
<input <input
name="password" name="password"