11 Commits
Author SHA1 Message Date
code002lover a1559e3a2c update tauri to newer version 2024-02-18 18:45:16 +01:00
code002lover f332bca033 update library version and fix args 2024-02-18 18:27:31 +01:00
code002lover ebad72d440 add license
update dependencies
2023-09-08 14:23:21 +02:00
Mystikfluu e430ec9ced update dependencies 2023-07-09 17:43:10 +02:00
Mystikfluu 159b701c9f fix erroring upon showing entry with . in name 2023-06-24 18:12:33 +02:00
deepsource-io[bot]andGitHub bb6427316d ci: Add .deepsource.toml 2023-06-23 13:04:32 +00:00
Mystikfluu 31d0fa3285 run periodic ISync update asynchronously
update library
2023-05-13 17:36:43 +02:00
none 54ca3760f7 fix error when filename is errorous
update library
2023-05-08 10:59:42 +02:00
Mystikfluu 7f680ff4a1 fix crash when copying entry with space in name 2023-05-07 21:53:46 +02:00
Mystikfluu 7b089f89e3 update dependencies 2023-05-07 21:53:12 +02:00
Mystikfluu 0085866268 add button to disable ISync 2023-04-04 15:26:09 +02:00
9 changed files with 2405 additions and 1062 deletions
+7
View File
@@ -0,0 +1,7 @@
version = 1
[[analyzers]]
name = "rust"
[analyzers.meta]
msrv = "stable"
+2 -1
View File
@@ -1,4 +1,5 @@
/src-tauri/target /src-tauri/target
*_backup *_backup
*ignore* *ignore*
msi/ msi/
/src-tauri/gen/
+1 -1
Submodule library updated: 3326ee886b...96cb053e65
+2252 -922
View File
File diff suppressed because it is too large Load Diff
+7 -4
View File
@@ -2,20 +2,23 @@
name = "ipass-gui" name = "ipass-gui"
version = "1.0.0" version = "1.0.0"
edition = "2021" edition = "2021"
license = "GNU GPLv3"
description = "A Password manager"
repository = "https://git.ipost.rocks/Code002Lover/IPass-GUI"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies] [build-dependencies]
tauri-build = { version = "1.2", features = [] } tauri-build = { version = "2.0.0-beta.1", features = [] }
[dependencies] [dependencies]
serde_json = "1.0" serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.2.4", features = ["dialog-confirm"] } tauri = { version = "2.0.0-beta.2", features = [] }
ip_lib = { path = "../library/" } ip_lib = { path = "../library/" }
rand="0.8.5" rand="0.8.5"
open="4.0" open="5.0.0"
tokio="1.27" tokio="1.28.2"
[features] [features]
# by default Tauri runs in production mode # by default Tauri runs in production mode
+87 -65
View File
@@ -5,119 +5,141 @@
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use tauri::State;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
extern crate ip_lib; extern crate ip_lib;
extern crate rand;
extern crate open; extern crate open;
extern crate rand;
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command] #[tauri::command]
fn get_version() -> String { fn get_version() -> String {
option_env!("CARGO_PKG_VERSION").unwrap_or("x.x.x").to_string() option_env!("CARGO_PKG_VERSION")
.unwrap_or("x.x.x")
.to_string()
} }
#[tauri::command] #[tauri::command]
fn create_entry(name: String, username: String, pw: &str, mpw: String) -> bool { fn create_entry(name: &str, username: String, pw: &str, mpw: &str) -> bool {
let return_value = ip_lib::create_entry(&name, username+";"+pw, mpw); let username_and_pw = username + ";" + pw;
if return_value { let return_value = ip_lib::create_entry(name, &username_and_pw, mpw);
isync_save(); if return_value {
} isync_save();
return_value }
return_value
} }
#[tauri::command] #[tauri::command]
fn random_password() -> String { fn random_password() -> String {
ip_lib::random_password() ip_lib::random_password()
} }
#[tauri::command] #[tauri::command]
fn get_entry(name: String, mpw: String) -> Result<(String,String),String> { fn get_entry(name: &str, mpw: &str) -> Result<(String, String), String> {
let binding = ip_lib::get_entry(&name, mpw); let binding = ip_lib::get_entry(name, mpw);
if let Ok(data) = binding { if let Ok(data) = binding {
let mut split = data.split(';'); let mut split = data.split(';');
Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string())) Ok((
} else { split.next().unwrap().to_string(),
Err(binding.expect_err("expected error")) split.next().unwrap().to_string(),
} ))
} else {
Err(binding.expect_err("expected error"))
}
} }
#[tauri::command] #[tauri::command]
fn get_entries() -> Vec<String> { fn get_entries() -> Vec<String> {
let mut vector: Vec<String> = Vec::default(); let mut vector: Vec<String> = Vec::default();
for entry in ip_lib::get_entries() { for entry in ip_lib::get_entries() {
let entry_filename = entry.unwrap().file_name(); let entry_filename = entry.unwrap().file_name();
let ent = entry_filename.to_str().unwrap(); let ent = entry_filename.to_str().unwrap();
if ent != "token.ipasst" { if ent != "token.ipasst" && ent.len() > 6 {
vector.insert(0, ent[..ent.len()-6].to_string()); vector.insert(0, ent[..ent.len() - 6].to_string());
} }
} }
vector.sort(); vector.sort();
vector vector
} }
#[tauri::command] #[tauri::command]
fn remove_entry(name: &str) -> bool { fn remove_entry(name: &str) -> bool {
let filepath = &(ip_lib::get_ipass_folder()+name+".ipass"); let filepath = &(ip_lib::get_ipass_folder() + name + ".ipass");
if std::path::Path::new(filepath).exists() { if std::path::Path::new(filepath).exists() {
std::fs::remove_file(filepath).unwrap(); std::fs::remove_file(filepath).unwrap();
isync_save(); isync_save();
return true; return true;
} }
false false
} }
#[tauri::command] #[tauri::command]
fn open_authorize() -> u32 { fn open_authorize() -> u32 {
let code:u32 = rand::random(); let code: u32 = rand::random();
open::that(format!("https://ipost.rocks/authorize?id=1&extra={}",code)).unwrap(); open::that(format!("https://ipost.rocks/authorize?id=1&extra={}", code)).unwrap();
code //the IPass app id is 1
code
} }
#[tauri::command] #[tauri::command]
fn store_token(token: String) { fn store_token(token: String) {
let filepath = &(ip_lib::get_ipass_folder()+"token.ipasst"); let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
let mut file = File::create(filepath).unwrap(); let mut file = File::create(filepath).unwrap();
file.write_all(token.as_bytes()).unwrap(); file.write_all(token.as_bytes()).unwrap();
} }
#[tauri::command] #[tauri::command]
fn get_isync_status() -> bool { fn remove_token() {
let filepath = &(ip_lib::get_ipass_folder()+"token.ipasst"); let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
std::path::Path::new(filepath).exists() std::fs::remove_file(filepath).unwrap();
} //TODO: cleaner solution via IPass api call to unauthorize
fn isync_save() {
let isync_save_future = ip_lib::isync_save();
let rt = Runtime::new().unwrap();
let _save_output = rt.block_on(isync_save_future);
//println!("isync_save: {}",save_output);
} }
#[tauri::command] #[tauri::command]
fn sync_isync() { fn get_isync_status() -> bool {
let rt = Runtime::new().unwrap(); let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
std::path::Path::new(filepath).exists()
}
let isync_get_future = ip_lib::isync_get(); fn isync_save() {
let isync_save_future = ip_lib::isync_save();
//println!("going to block on isync_get"); let rt = Runtime::new().unwrap();
let _get_output = rt.block_on(isync_get_future); let _save_output = rt.block_on(isync_save_future);
//println!("isync_get: {}",get_output); //println!("isync_save: {}",save_output);
}
#[tauri::command]
fn sync_isync(rt: State<Runtime>) {
//println!("going to sync");
rt.spawn(async {
let _get_output = ip_lib::isync_get().await;
//println!("isync_get: {}",_get_output);
});
} }
fn main() { fn main() {
sync_isync(); let rt = Runtime::new().unwrap();
tauri::Builder::default() tauri::Builder::default()
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
get_version,create_entry,random_password, get_version,
get_entry,get_entries,remove_entry, create_entry,
open_authorize,store_token,get_isync_status, random_password,
sync_isync]) get_entry,
.run(tauri::generate_context!()) get_entries,
.expect("error while running tauri application"); remove_entry,
open_authorize,
store_token,
get_isync_status,
sync_isync,
remove_token
])
.manage(rt)
.run(tauri::generate_context!())
.expect("error while running tauri application");
} }
+38 -65
View File
@@ -2,71 +2,44 @@
"build": { "build": {
"beforeDevCommand": "", "beforeDevCommand": "",
"beforeBuildCommand": "", "beforeBuildCommand": "",
"devPath": "../src", "frontendDist": "../src"
"distDir": "../src",
"withGlobalTauri": true
}, },
"package": { "productName": "ipass",
"productName": "ipass", "version": "1.0.0",
"version": "1.0.0" "bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"externalBin": [],
"icon": [
"icons/icon.ico",
"icons/icon.png"
],
"longDescription": "",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
}, },
"tauri": { "app": {
"allowlist": { "windows": [{
"all": false, "fullscreen": false,
"dialog": { "height": 600,
"all": false, "resizable": true,
"open": false, "title": "IPass",
"save": false, "width": 880,
"ask": false, "theme": "Dark"
"message": false, }]
"confirm": true
}
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/icon.ico",
"icons/icon.png"
],
"identifier": "rocks.ipost.ipass",
"longDescription": "",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "IPass",
"width": 880,
"theme": "Dark"
}
]
} }
} }
+6 -3
View File
@@ -30,6 +30,7 @@ async function run_isync() {
} }
} }
setInterval(run_isync, 1000 * 10); setInterval(run_isync, 1000 * 10);
run_isync();
async function startup() { async function startup() {
@@ -66,7 +67,9 @@ async function startup() {
if(!lock_status) { if(!lock_status) {
let isUsername = input.parentElement.classList.contains("entry_user") let isUsername = input.parentElement.classList.contains("entry_user")
let entry_name = input.parentElement.id.slice(0,input.parentElement.id.length-5) let qs = "#"+input.parentElement.id.slice(0,input.parentElement.id.length-5)+"_name > input[type=text]"
console.log(qs)
let entry_name = document.querySelector(qs).value
console.log(entry_name,input.parentElement.id) console.log(entry_name,input.parentElement.id)
let info = await invoke("get_entry",{ let info = await invoke("get_entry",{
@@ -272,8 +275,8 @@ async function get_pw() {
} }
async function showEntry(entry_name) { async function showEntry(entry_name) {
let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-")}_user > input`); let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-").replaceAll(".","\\.")}_user > input`);
let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-")}_pass > input`); let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-").replaceAll(".","\\.")}_pass > input`);
if(this.innerText == "Show"){ if(this.innerText == "Show"){
let info = await invoke("get_entry",{ let info = await invoke("get_entry",{
+5 -1
View File
@@ -13,7 +13,7 @@
<h2>ISync</h2> <h2>ISync</h2>
<h4>Keep your passwords up-to-date on multiple devices</h4> <h4>Keep your passwords up-to-date on multiple devices</h4>
<span>Current status: <b id="ISyncStatus">Checking</b></span> <span>Current status: <b id="ISyncStatus">Checking</b></span>
<a href="/enableISync.html" class="nostyle" id="enableISync">Enable ISync</a> <button id="enableISyncButton"><a href="/enableISync.html" class="nostyle" id="enableISync">Enable ISync</a></button>
</div> </div>
<script> <script>
const { invoke } = window.__TAURI__.tauri; const { invoke } = window.__TAURI__.tauri;
@@ -21,7 +21,11 @@
let status = await invoke("get_isync_status") let status = await invoke("get_isync_status")
document.getElementById("ISyncStatus").innerText=status?"Enabled":"Disabled" document.getElementById("ISyncStatus").innerText=status?"Enabled":"Disabled"
if(status){ if(status){
document.getElementById("enableISyncButton").innerText="Disable ISync"
document.getElementById("enableISync").remove() document.getElementById("enableISync").remove()
document.getElementById("enableISyncButton").addEventListener("onclick",(_e)=>{
invoke("remove_token")
})
} }
} }
start() start()