Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
@ -1,7 +0,0 @@
|
|||||||
version = 1
|
|
||||||
|
|
||||||
[[analyzers]]
|
|
||||||
name = "rust"
|
|
||||||
|
|
||||||
[analyzers.meta]
|
|
||||||
msrv = "stable"
|
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,4 +2,3 @@
|
|||||||
*_backup
|
*_backup
|
||||||
*ignore*
|
*ignore*
|
||||||
msi/
|
msi/
|
||||||
/src-tauri/gen/
|
|
2
library
2
library
@ -1 +1 @@
|
|||||||
Subproject commit 96cb053e659123afc394187229949e7f32c23372
|
Subproject commit 3326ee886b0121237a84217ab9508728c722f8d4
|
3126
src-tauri/Cargo.lock
generated
3126
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -2,25 +2,20 @@
|
|||||||
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"
|
|
||||||
|
|
||||||
[lib]
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
name = "ipass_gui_lib"
|
|
||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2.0.0-beta", features = [] }
|
tauri-build = { version = "1.2", 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 = "2.0.0-beta", features = [] }
|
tauri = { version = "1.2.4", features = ["dialog-confirm"] }
|
||||||
ip_lib = { path = "../library/" }
|
ip_lib = { path = "../library/" }
|
||||||
rand="0.8.5"
|
rand="0.8.5"
|
||||||
open="5.0.0"
|
open="4.0"
|
||||||
tokio="1.28.2"
|
tokio="1.27"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# by default Tauri runs in production mode
|
# by default Tauri runs in production mode
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
#![cfg_attr(
|
|
||||||
all(not(debug_assertions), target_os = "windows"),
|
|
||||||
windows_subsystem = "windows"
|
|
||||||
)]
|
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use tauri::State;
|
|
||||||
use tokio::runtime::Runtime;
|
|
||||||
|
|
||||||
extern crate ip_lib;
|
|
||||||
extern crate open;
|
|
||||||
extern crate rand;
|
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_version() -> String {
|
|
||||||
option_env!("CARGO_PKG_VERSION")
|
|
||||||
.unwrap_or("x.x.x")
|
|
||||||
.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn create_entry(name: &str, username: String, pw: &str, mpw: &str) -> bool {
|
|
||||||
let username_and_pw = username + ";" + pw;
|
|
||||||
let return_value = ip_lib::create_entry(name, &username_and_pw, mpw);
|
|
||||||
if return_value {
|
|
||||||
isync_save();
|
|
||||||
}
|
|
||||||
return_value
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn random_password() -> String {
|
|
||||||
ip_lib::random_password()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_entry(name: &str, mpw: &str) -> Result<(String, String), String> {
|
|
||||||
let binding = ip_lib::get_entry(name, mpw);
|
|
||||||
if let Ok(data) = binding {
|
|
||||||
let mut split = data.split(';');
|
|
||||||
Ok((
|
|
||||||
split.next().unwrap().to_string(),
|
|
||||||
split.next().unwrap().to_string(),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Err(binding.expect_err("expected error"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_entries() -> Vec<String> {
|
|
||||||
let mut vector: Vec<String> = Vec::default();
|
|
||||||
for entry in ip_lib::get_entries() {
|
|
||||||
let entry_filename = entry.unwrap().file_name();
|
|
||||||
let ent = entry_filename.to_str().unwrap();
|
|
||||||
if ent != "token.ipasst" && ent.len() > 6 {
|
|
||||||
vector.insert(0, ent[..ent.len() - 6].to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vector.sort();
|
|
||||||
|
|
||||||
vector
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn remove_entry(name: &str) -> bool {
|
|
||||||
let filepath = &(ip_lib::get_ipass_folder() + name + ".ipass");
|
|
||||||
if std::path::Path::new(filepath).exists() {
|
|
||||||
std::fs::remove_file(filepath).unwrap();
|
|
||||||
isync_save();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn open_authorize() -> u32 {
|
|
||||||
let code: u32 = rand::random();
|
|
||||||
open::that(format!("https://ipost.rocks/authorize?id=1&extra={}", code)).unwrap();
|
|
||||||
//the IPass app id is 1
|
|
||||||
code
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn store_token(token: String) {
|
|
||||||
let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
|
|
||||||
let mut file = File::create(filepath).unwrap();
|
|
||||||
file.write_all(token.as_bytes()).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn remove_token() {
|
|
||||||
let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
|
|
||||||
std::fs::remove_file(filepath).unwrap();
|
|
||||||
//TODO: cleaner solution via IPass api call to unauthorize
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_isync_status() -> bool {
|
|
||||||
let filepath = &(ip_lib::get_ipass_folder() + "token.ipasst");
|
|
||||||
std::path::Path::new(filepath).exists()
|
|
||||||
}
|
|
||||||
|
|
||||||
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]
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
||||||
pub fn run() {
|
|
||||||
let rt = Runtime::new().unwrap();
|
|
||||||
|
|
||||||
tauri::Builder::default()
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
|
||||||
get_version,
|
|
||||||
create_entry,
|
|
||||||
random_password,
|
|
||||||
get_entry,
|
|
||||||
get_entries,
|
|
||||||
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");
|
|
||||||
}
|
|
@ -1,5 +1,123 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(
|
||||||
|
all(not(debug_assertions), target_os = "windows"),
|
||||||
|
windows_subsystem = "windows"
|
||||||
|
)]
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
|
extern crate ip_lib;
|
||||||
|
extern crate rand;
|
||||||
|
extern crate open;
|
||||||
|
|
||||||
|
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_version() -> String {
|
||||||
|
option_env!("CARGO_PKG_VERSION").unwrap_or("x.x.x").to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn create_entry(name: String, username: String, pw: &str, mpw: String) -> bool {
|
||||||
|
let return_value = ip_lib::create_entry(&name, username+";"+pw, mpw);
|
||||||
|
if return_value {
|
||||||
|
isync_save();
|
||||||
|
}
|
||||||
|
return_value
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn random_password() -> String {
|
||||||
|
ip_lib::random_password()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_entry(name: String, mpw: String) -> Result<(String,String),String> {
|
||||||
|
let binding = ip_lib::get_entry(&name, mpw);
|
||||||
|
if let Ok(data) = binding {
|
||||||
|
let mut split = data.split(';');
|
||||||
|
Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string()))
|
||||||
|
} else {
|
||||||
|
Err(binding.expect_err("expected error"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_entries() -> Vec<String> {
|
||||||
|
let mut vector: Vec<String> = Vec::default();
|
||||||
|
for entry in ip_lib::get_entries() {
|
||||||
|
let entry_filename = entry.unwrap().file_name();
|
||||||
|
let ent = entry_filename.to_str().unwrap();
|
||||||
|
if ent != "token.ipasst" {
|
||||||
|
vector.insert(0, ent[..ent.len()-6].to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector.sort();
|
||||||
|
|
||||||
|
vector
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn remove_entry(name: &str) -> bool {
|
||||||
|
let filepath = &(ip_lib::get_ipass_folder()+name+".ipass");
|
||||||
|
if std::path::Path::new(filepath).exists() {
|
||||||
|
std::fs::remove_file(filepath).unwrap();
|
||||||
|
isync_save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn open_authorize() -> u32 {
|
||||||
|
let code:u32 = rand::random();
|
||||||
|
open::that(format!("https://ipost.rocks/authorize?id=1&extra={}",code)).unwrap();
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn store_token(token: String) {
|
||||||
|
let filepath = &(ip_lib::get_ipass_folder()+"token.ipasst");
|
||||||
|
let mut file = File::create(filepath).unwrap();
|
||||||
|
file.write_all(token.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_isync_status() -> bool {
|
||||||
|
let filepath = &(ip_lib::get_ipass_folder()+"token.ipasst");
|
||||||
|
std::path::Path::new(filepath).exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
fn sync_isync() {
|
||||||
|
let rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
|
let isync_get_future = ip_lib::isync_get();
|
||||||
|
|
||||||
|
//println!("going to block on isync_get");
|
||||||
|
let _get_output = rt.block_on(isync_get_future);
|
||||||
|
//println!("isync_get: {}",get_output);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
ipass_gui_lib::run();
|
sync_isync();
|
||||||
|
|
||||||
|
tauri::Builder::default()
|
||||||
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
get_version,create_entry,random_password,
|
||||||
|
get_entry,get_entries,remove_entry,
|
||||||
|
open_authorize,store_token,get_isync_status,
|
||||||
|
sync_isync])
|
||||||
|
.run(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,40 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"build": {
|
||||||
"windows": [
|
"beforeDevCommand": "",
|
||||||
{
|
"beforeBuildCommand": "",
|
||||||
"fullscreen": false,
|
"devPath": "../src",
|
||||||
"height": 600,
|
"distDir": "../src",
|
||||||
"resizable": true,
|
|
||||||
"theme": "Dark",
|
|
||||||
"title": "IPass",
|
|
||||||
"width": 880
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"withGlobalTauri": true
|
"withGlobalTauri": true
|
||||||
},
|
},
|
||||||
"build": {
|
"package": {
|
||||||
"beforeBuildCommand": "",
|
"productName": "ipass",
|
||||||
"beforeDevCommand": "",
|
"version": "1.0.0"
|
||||||
"frontendDist": "../src"
|
},
|
||||||
|
"tauri": {
|
||||||
|
"allowlist": {
|
||||||
|
"all": false,
|
||||||
|
"dialog": {
|
||||||
|
"all": false,
|
||||||
|
"open": false,
|
||||||
|
"save": false,
|
||||||
|
"ask": false,
|
||||||
|
"message": false,
|
||||||
|
"confirm": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"category": "DeveloperTool",
|
"category": "DeveloperTool",
|
||||||
"copyright": "",
|
"copyright": "",
|
||||||
|
"deb": {
|
||||||
|
"depends": []
|
||||||
|
},
|
||||||
"externalBin": [],
|
"externalBin": [],
|
||||||
"icon": [
|
"icon": [
|
||||||
"icons/icon.ico",
|
"icons/icon.ico",
|
||||||
"icons/icon.png"
|
"icons/icon.png"
|
||||||
],
|
],
|
||||||
|
"identifier": "rocks.ipost.ipass",
|
||||||
"longDescription": "",
|
"longDescription": "",
|
||||||
"macOS": {
|
"macOS": {
|
||||||
"entitlements": null,
|
"entitlements": null,
|
||||||
@ -43,7 +52,21 @@
|
|||||||
"timestampUrl": ""
|
"timestampUrl": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {},
|
"security": {
|
||||||
"productName": "ipass",
|
"csp": null
|
||||||
"version": "1.0.0"
|
},
|
||||||
|
"updater": {
|
||||||
|
"active": false
|
||||||
|
},
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"fullscreen": false,
|
||||||
|
"height": 600,
|
||||||
|
"resizable": true,
|
||||||
|
"title": "IPass",
|
||||||
|
"width": 880,
|
||||||
|
"theme": "Dark"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
11
src/main.js
11
src/main.js
@ -1,4 +1,4 @@
|
|||||||
const { invoke } = window.__TAURI__.core;
|
const { invoke } = window.__TAURI__.tauri;
|
||||||
|
|
||||||
let master_pw;
|
let master_pw;
|
||||||
let lock_status = true;
|
let lock_status = true;
|
||||||
@ -30,7 +30,6 @@ async function run_isync() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setInterval(run_isync, 1000 * 10);
|
setInterval(run_isync, 1000 * 10);
|
||||||
run_isync();
|
|
||||||
|
|
||||||
async function startup() {
|
async function startup() {
|
||||||
|
|
||||||
@ -67,9 +66,7 @@ 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 qs = "#"+input.parentElement.id.slice(0,input.parentElement.id.length-5)+"_name > input[type=text]"
|
let entry_name = input.parentElement.id.slice(0,input.parentElement.id.length-5)
|
||||||
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",{
|
||||||
@ -275,8 +272,8 @@ async function get_pw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function showEntry(entry_name) {
|
async function showEntry(entry_name) {
|
||||||
let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-").replaceAll(".","\\.")}_user > input`);
|
let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-")}_user > input`);
|
||||||
let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-").replaceAll(".","\\.")}_pass > input`);
|
let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-")}_pass > input`);
|
||||||
|
|
||||||
if(this.innerText == "Show"){
|
if(this.innerText == "Show"){
|
||||||
let info = await invoke("get_entry",{
|
let info = await invoke("get_entry",{
|
||||||
|
@ -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>
|
||||||
<button id="enableISyncButton"><a href="/enableISync.html" class="nostyle" id="enableISync">Enable ISync</a></button>
|
<a href="/enableISync.html" class="nostyle" id="enableISync">Enable ISync</a>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const { invoke } = window.__TAURI__.tauri;
|
const { invoke } = window.__TAURI__.tauri;
|
||||||
@ -21,11 +21,7 @@
|
|||||||
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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user