add simple ISync authentication

This commit is contained in:
Code002Lover Arch Laptop 2023-03-07 13:11:29 +01:00
parent c46565c4ce
commit 624b69d6d1
14 changed files with 970 additions and 841 deletions

6
.gitignore vendored
View File

@ -1,4 +1,4 @@
/src-tauri/target /src-tauri/target
*_backup *_backup
*ignore* *ignore*
msi/ msi/

6
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "library"] [submodule "library"]
path = library path = library
url = https://github.com/002Hub/IPass-library url = https://github.com/002Hub/IPass-library

View File

@ -1 +1 @@
# IPass # IPass

117
src-tauri/Cargo.lock generated
View File

@ -617,7 +617,7 @@ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall",
"windows-sys", "windows-sys 0.42.0",
] ]
[[package]] [[package]]
@ -672,24 +672,24 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
dependencies = [ dependencies = [
"futures-core", "futures-core",
] ]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -698,15 +698,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -715,15 +715,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-macro", "futures-macro",
@ -1215,6 +1215,8 @@ name = "ipass-gui"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ip_lib", "ip_lib",
"open",
"rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"tauri", "tauri",
@ -1593,6 +1595,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "open"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21ecf2487e799604735754d2c5896106785987b441b5aee58f242e4d4963179a"
dependencies = [
"pathdiff",
]
[[package]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@ -1644,7 +1655,7 @@ dependencies = [
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec",
"windows-sys", "windows-sys 0.42.0",
] ]
[[package]] [[package]]
@ -1653,6 +1664,12 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "pathdiff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.2.0" version = "2.2.0"
@ -2752,16 +2769,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.24.1" version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
"memchr", "memchr",
"num_cpus", "num_cpus",
"pin-project-lite", "pin-project-lite",
"windows-sys", "windows-sys 0.45.0",
] ]
[[package]] [[package]]
@ -3225,12 +3242,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0", "windows_aarch64_msvc 0.42.1",
"windows_i686_gnu 0.42.0", "windows_i686_gnu 0.42.1",
"windows_i686_msvc 0.42.0", "windows_i686_msvc 0.42.1",
"windows_x86_64_gnu 0.42.0", "windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.0", "windows_x86_64_msvc 0.42.1",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.1",
"windows_i686_gnu 0.42.1",
"windows_i686_msvc 0.42.1",
"windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.1",
] ]
[[package]] [[package]]
@ -3241,9 +3282,9 @@ checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@ -3259,9 +3300,9 @@ checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@ -3277,9 +3318,9 @@ checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@ -3295,9 +3336,9 @@ checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@ -3313,15 +3354,15 @@ checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
@ -3337,9 +3378,9 @@ checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]] [[package]]
name = "winres" name = "winres"

View File

@ -13,6 +13,8 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.2", features = ["dialog-confirm"] } tauri = { version = "1.2", features = ["dialog-confirm"] }
ip_lib = { path = "../library/" } ip_lib = { path = "../library/" }
rand="0.8.5"
open="3.4.0"
[features] [features]
# by default Tauri runs in production mode # by default Tauri runs in production mode

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
tauri_build::build() tauri_build::build()
} }

View File

@ -1,65 +1,95 @@
#![cfg_attr( #![cfg_attr(
all(not(debug_assertions), target_os = "linux"), all(not(debug_assertions), target_os = "linux"),
windows_subsystem = "windows" windows_subsystem = "windows"
)] )]
extern crate ip_lib; use std::fs::File;
use std::io::Write;
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
extern crate ip_lib;
#[tauri::command] extern crate rand;
fn get_version() -> String { extern crate open;
return option_env!("CARGO_PKG_VERSION").unwrap_or("x.x.x").to_string();
} // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command] #[tauri::command]
fn create_entry(name: String, username: String, pw: &str, mpw: String) -> bool { fn get_version() -> String {
ip_lib::create_entry(&name, username+";"+pw, mpw) return option_env!("CARGO_PKG_VERSION").unwrap_or("x.x.x").to_string();
} }
#[tauri::command] #[tauri::command]
fn random_password() -> String { fn create_entry(name: String, username: String, pw: &str, mpw: String) -> bool {
ip_lib::random_password() ip_lib::create_entry(&name, username+";"+pw, mpw)
} }
#[tauri::command] #[tauri::command]
fn get_entry(name: String, mpw: String) -> Result<(String,String),String> { fn random_password() -> String {
let binding = ip_lib::get_entry(&name, mpw); ip_lib::random_password()
if let Ok(data) = binding { }
let mut split = data.split(";");
return Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string())); #[tauri::command]
} else { fn get_entry(name: String, mpw: String) -> Result<(String,String),String> {
return Err(binding.expect_err("expected error")); let binding = ip_lib::get_entry(&name, mpw);
} if let Ok(data) = binding {
} let mut split = data.split(";");
return Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string()));
#[tauri::command] } else {
fn get_entries() -> Vec<String> { return Err(binding.expect_err("expected error"));
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(); #[tauri::command]
vector.insert(0, ent[..ent.len()-6].to_string()); fn get_entries() -> Vec<String> {
} let mut vector: Vec<String> = Vec::default();
for entry in ip_lib::get_entries() {
vector.sort(); let entry_filename = entry.unwrap().file_name();
let ent = entry_filename.to_str().unwrap();
return vector; if ent != "token.ipasst" {
} vector.insert(0, ent[..ent.len()-6].to_string());
}
#[tauri::command] }
fn remove_entry(name: &str) -> bool {
let filepath = &(ip_lib::get_ipass_folder()+name+".ipass"); vector.sort();
if std::path::Path::new(filepath).exists() {
std::fs::remove_file(filepath).unwrap(); return vector;
return true; }
}
return false; #[tauri::command]
} fn remove_entry(name: &str) -> bool {
let filepath = &(ip_lib::get_ipass_folder()+name+".ipass");
fn main() { if std::path::Path::new(filepath).exists() {
tauri::Builder::default() std::fs::remove_file(filepath).unwrap();
.invoke_handler(tauri::generate_handler![get_version,create_entry,random_password,get_entry,get_entries,remove_entry]) return true;
.run(tauri::generate_context!()) }
.expect("error while running tauri application"); return false;
} }
#[tauri::command]
fn open_authorize() -> u32 {
let code:u32 = rand::random();
open::that(format!("https://ipost.rocks/authorize?id=1&extra={}",code)).unwrap();
return 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 main() {
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])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -1,72 +1,72 @@
{ {
"build": { "build": {
"beforeDevCommand": "", "beforeDevCommand": "",
"beforeBuildCommand": "", "beforeBuildCommand": "",
"devPath": "../src", "devPath": "../src",
"distDir": "../src", "distDir": "../src",
"withGlobalTauri": true "withGlobalTauri": true
}, },
"package": { "package": {
"productName": "ipass", "productName": "ipass",
"version": "0.1.0" "version": "0.1.0"
}, },
"tauri": { "tauri": {
"allowlist": { "allowlist": {
"all": false, "all": false,
"dialog": { "dialog": {
"all": false, "all": false,
"open": false, "open": false,
"save": false, "save": false,
"ask": false, "ask": false,
"message": false, "message": false,
"confirm": true "confirm": true
} }
}, },
"bundle": { "bundle": {
"active": true, "active": true,
"category": "DeveloperTool", "category": "DeveloperTool",
"copyright": "", "copyright": "",
"deb": { "deb": {
"depends": [] "depends": []
}, },
"externalBin": [], "externalBin": [],
"icon": [ "icon": [
"icons/icon.ico", "icons/icon.ico",
"icons/icon.png" "icons/icon.png"
], ],
"identifier": "rocks.ipost.ipass", "identifier": "rocks.ipost.ipass",
"longDescription": "", "longDescription": "",
"macOS": { "macOS": {
"entitlements": null, "entitlements": null,
"exceptionDomain": "", "exceptionDomain": "",
"frameworks": [], "frameworks": [],
"providerShortName": null, "providerShortName": null,
"signingIdentity": null "signingIdentity": null
}, },
"resources": [], "resources": [],
"shortDescription": "", "shortDescription": "",
"targets": "all", "targets": "all",
"windows": { "windows": {
"certificateThumbprint": null, "certificateThumbprint": null,
"digestAlgorithm": "sha256", "digestAlgorithm": "sha256",
"timestampUrl": "" "timestampUrl": ""
} }
}, },
"security": { "security": {
"csp": null "csp": null
}, },
"updater": { "updater": {
"active": false "active": false
}, },
"windows": [ "windows": [
{ {
"fullscreen": false, "fullscreen": false,
"height": 600, "height": 600,
"resizable": true, "resizable": true,
"title": "IPass", "title": "IPass",
"width": 880, "width": 880,
"theme": "Dark" "theme": "Dark"
} }
] ]
} }
} }

40
src/enableISync.html Normal file
View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body, html {
height: 100%;
margin: 0;
padding: 0;
}
iframe {
display: block;
width: 100%;
height: 100%;
border: none;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
Please authorise the Application in your browser!
<script>
const { invoke } = window.__TAURI__.tauri;
async function start() {
let code = await invoke("open_authorize");
let token= await (await fetch("https://ipass.ipost.rocks/get_token?code="+code)).text()
invoke("store_token",{
token: token
})
location.href="/settings.html"
}
start()
</script>
</body>
</html>

View File

@ -1,41 +1,41 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title id="pageTitle">IPass - x.x.x</title> <title id="pageTitle">IPass - x.x.x</title>
<script type="module" src="/main.js"></script> <script type="module" src="/main.js"></script>
<script type="module" src="/pwprompt.js"></script> <script type="module" src="/pwprompt.js"></script>
</head> </head>
<body> <body>
<h1 id="title">IPass</h1> <h1 id="title">IPass</h1>
<div class="select"> <div class="select">
<img src="/images/menu.png" width="50" height="50"> <img src="/images/menu.png" width="50" height="50">
<div> <div>
<div><a href="/settings"><img id="cogWImg" src="/images/settings.png" width="50" height="50" alt="Locked" title="Locked"></a></div> <div><a href="/settings"><img id="cogWImg" src="/images/settings.png" width="50" height="50" alt="Locked" title="Locked"></a></div>
<div><img alt="Lock" id="lockImg" src="/images/security_lock_locked.png" height=50 width=50></img></div> <div><img alt="Lock" id="lockImg" src="/images/security_lock_locked.png" height=50 width=50></img></div>
</div> </div>
</div> </div>
<br> <br>
<div id="table_div"> <div id="table_div">
<div id="table_entries"> <div id="table_entries">
<div>Entry name</div> <div>Entry name</div>
<div class="entry_name" id="createEntry_name"><input type="text" placeholder="New Entry Name" tabindex="1"></div> <div class="entry_name" id="createEntry_name"><input type="text" placeholder="New Entry Name" tabindex="1"></div>
</div> </div>
<div id="table_users"> <div id="table_users">
<div>Username</div> <div>Username</div>
<div class="entry_user" id="createEntry_user"><input type="text" placeholder="New Username" tabindex="1"></div> <div class="entry_user" id="createEntry_user"><input type="text" placeholder="New Username" tabindex="1"></div>
</div> </div>
<div id="table_pwds"> <div id="table_pwds">
<div>Password</div> <div>Password</div>
<div class="entry_pass" id="createEntry_pass"><input type="password" placeholder="New Password" tabindex="1"></div> <div class="entry_pass" id="createEntry_pass"><input type="password" placeholder="New Password" tabindex="1"></div>
</div> </div>
<div id="table_actions"> <div id="table_actions">
<div>Action</div> <div>Action</div>
<div class="button" id="createEntry_actions"><button tabindex="1">Create</button></div> <div class="button" id="createEntry_actions"><button tabindex="1">Create</button></div>
</div> </div>
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,330 +1,330 @@
const { invoke } = window.__TAURI__.tauri; const { invoke } = window.__TAURI__.tauri;
let master_pw; let master_pw;
let lock_status = true; let lock_status = true;
// async function greet() { // async function greet() {
// // 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
// greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); // greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value });
// } // }
window.addEventListener("DOMContentLoaded", () => { window.addEventListener("DOMContentLoaded", () => {
document.getElementById("lockImg").addEventListener("click",toggleLock); document.getElementById("lockImg").addEventListener("click",toggleLock);
startup(); startup();
}); });
async function startup() { async function startup() {
let select = document.querySelector(".select"); let select = document.querySelector(".select");
select.addEventListener("click", function(){ select.addEventListener("click", function(){
this.enabled = !this.enabled this.enabled = !this.enabled
if(this.enabled) { if(this.enabled) {
this.classList.add("open") this.classList.add("open")
} else { } else {
this.classList.remove("open") this.classList.remove("open")
} }
for(let cont of document.querySelectorAll(".select > div")) { for(let cont of document.querySelectorAll(".select > div")) {
cont.style.display=(this.enabled && "block") || "none" cont.style.display=(this.enabled && "block") || "none"
} }
document.querySelector('#table_div').style.marginTop=(this.enabled && "8em") || "0px"; document.querySelector('#table_div').style.marginTop=(this.enabled && "8em") || "0px";
}); });
document.querySelector("#createEntry_actions > button").addEventListener("click",createEntry); document.querySelector("#createEntry_actions > button").addEventListener("click",createEntry);
let entries = await invoke("get_entries"); let entries = await invoke("get_entries");
for(let i = 0; i < entries.length; i++) { for(let i = 0; i < entries.length; i++) {
buildEntry(entries[i]); buildEntry(entries[i]);
} }
for (let input of document.querySelectorAll('input[readonly]')) { for (let input of document.querySelectorAll('input[readonly]')) {
input.addEventListener('click', async function() { input.addEventListener('click', async function() {
if(!input.hasAttribute("readonly"))return if(!input.hasAttribute("readonly"))return
if(input.getAttribute("type")!="text" && lock_status)return if(input.getAttribute("type")!="text" && lock_status)return
let to_copy = input.value let to_copy = input.value
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 entry_name = input.parentElement.id.slice(0,input.parentElement.id.length-5)
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",{
name: entry_name, name: entry_name,
mpw: await get_pw() mpw: await get_pw()
}) })
if(isUsername) { if(isUsername) {
to_copy = info[0] to_copy = info[0]
} else { } else {
if(input.parentElement.classList.contains("entry_name")) { if(input.parentElement.classList.contains("entry_name")) {
to_copy = entry_name to_copy = entry_name
} else { } else {
to_copy = info[1] to_copy = info[1]
} }
} }
} }
navigator.clipboard.writeText(to_copy).then(function() { navigator.clipboard.writeText(to_copy).then(function() {
let originalColor = input.style.borderColor; let originalColor = input.style.borderColor;
input.style.borderColor = "lightgreen"; input.style.borderColor = "lightgreen";
setTimeout(function(){ setTimeout(function(){
input.style.borderColor = originalColor; input.style.borderColor = originalColor;
},250) },250)
console.log('Text copied to clipboard'); console.log('Text copied to clipboard');
}, function(err) { }, function(err) {
let originalColor = input.style.borderColor; let originalColor = input.style.borderColor;
input.style.borderColor = "red"; input.style.borderColor = "red";
setTimeout(function(){ setTimeout(function(){
input.style.borderColor = originalColor; input.style.borderColor = originalColor;
},500) },500)
console.error('Failed to copy text: ', err); console.error('Failed to copy text: ', err);
}); });
}); });
} }
} }
let entry_priority = 1 let entry_priority = 1
function buildEntry(entry) { function buildEntry(entry) {
entry_priority++; entry_priority++;
let nameDiv = document.createElement("div"); let nameDiv = document.createElement("div");
nameDiv.setAttribute("class", "entry_name"); nameDiv.setAttribute("class", "entry_name");
nameDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_name`) nameDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_name`)
let nameInput = document.createElement("input"); let nameInput = document.createElement("input");
nameInput.setAttribute("type", "text"); nameInput.setAttribute("type", "text");
nameInput.setAttribute("placeholder", "New Entry Name"); nameInput.setAttribute("placeholder", "New Entry Name");
nameInput.setAttribute("value", entry); nameInput.setAttribute("value", entry);
nameInput.setAttribute("readonly", true); nameInput.setAttribute("readonly", true);
nameInput.setAttribute("unselectable", "on") nameInput.setAttribute("unselectable", "on")
nameInput.setAttribute("tabindex",entry_priority) nameInput.setAttribute("tabindex",entry_priority)
nameDiv.appendChild(nameInput); nameDiv.appendChild(nameInput);
let userDiv = document.createElement("div"); let userDiv = document.createElement("div");
userDiv.setAttribute("class", "entry_user"); userDiv.setAttribute("class", "entry_user");
userDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_user`) userDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_user`)
let userInput = document.createElement("input"); let userInput = document.createElement("input");
userInput.setAttribute("type", "password"); userInput.setAttribute("type", "password");
userInput.setAttribute("placeholder", "New Username"); userInput.setAttribute("placeholder", "New Username");
userInput.setAttribute("value", "PLACEHOLDER"); userInput.setAttribute("value", "PLACEHOLDER");
userInput.setAttribute("readonly", true); userInput.setAttribute("readonly", true);
userInput.setAttribute("unselectable", "on") userInput.setAttribute("unselectable", "on")
userInput.setAttribute("tabindex",entry_priority) userInput.setAttribute("tabindex",entry_priority)
userDiv.appendChild(userInput); userDiv.appendChild(userInput);
let passDiv = document.createElement("div"); let passDiv = document.createElement("div");
passDiv.setAttribute("class", "entry_pass"); passDiv.setAttribute("class", "entry_pass");
passDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_pass`) passDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_pass`)
let passInput = document.createElement("input"); let passInput = document.createElement("input");
passInput.setAttribute("type", "password"); passInput.setAttribute("type", "password");
passInput.setAttribute("placeholder", "New Password"); passInput.setAttribute("placeholder", "New Password");
passInput.setAttribute("value", "PLACEHOLDER!"); passInput.setAttribute("value", "PLACEHOLDER!");
passInput.setAttribute("readonly", true); passInput.setAttribute("readonly", true);
passInput.setAttribute("unselectable", "on") passInput.setAttribute("unselectable", "on")
userInput.setAttribute("tabindex",entry_priority) userInput.setAttribute("tabindex",entry_priority)
passDiv.appendChild(passInput); passDiv.appendChild(passInput);
let showButton = document.createElement("button"); let showButton = document.createElement("button");
showButton.innerText = "Show"; showButton.innerText = "Show";
showButton.addEventListener("click",showEntry.bind(showButton, entry),false); showButton.addEventListener("click",showEntry.bind(showButton, entry),false);
showButton.setAttribute("class", "showbutton"); showButton.setAttribute("class", "showbutton");
showButton.setAttribute("tabindex",entry_priority) showButton.setAttribute("tabindex",entry_priority)
let editButton = document.createElement("button"); let editButton = document.createElement("button");
editButton.innerText = "Edit"; editButton.innerText = "Edit";
editButton.addEventListener("click", editEntry.bind(editButton, entry), false); editButton.addEventListener("click", editEntry.bind(editButton, entry), false);
editButton.setAttribute("class", "editbutton"); editButton.setAttribute("class", "editbutton");
editButton.setAttribute("tabindex",entry_priority) editButton.setAttribute("tabindex",entry_priority)
let deleteButton = document.createElement("button"); let deleteButton = document.createElement("button");
deleteButton.innerText = "Delete"; deleteButton.innerText = "Delete";
deleteButton.addEventListener("click", deleteEntry.bind(deleteButton, entry), false); deleteButton.addEventListener("click", deleteEntry.bind(deleteButton, entry), false);
deleteButton.setAttribute("class", "deletebutton"); deleteButton.setAttribute("class", "deletebutton");
deleteButton.setAttribute("tabindex",entry_priority) deleteButton.setAttribute("tabindex",entry_priority)
let actionDiv = document.createElement("div") let actionDiv = document.createElement("div")
actionDiv.appendChild(showButton) actionDiv.appendChild(showButton)
actionDiv.appendChild(editButton) actionDiv.appendChild(editButton)
actionDiv.appendChild(deleteButton) actionDiv.appendChild(deleteButton)
actionDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_actions`) actionDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_actions`)
document.getElementById("table_entries").appendChild(nameDiv) document.getElementById("table_entries").appendChild(nameDiv)
document.getElementById("table_users").appendChild(userDiv) document.getElementById("table_users").appendChild(userDiv)
document.getElementById("table_pwds").appendChild(passDiv) document.getElementById("table_pwds").appendChild(passDiv)
document.getElementById("table_actions").appendChild(actionDiv) document.getElementById("table_actions").appendChild(actionDiv)
} }
function deleteEntry(entry) { function deleteEntry(entry) {
let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user`); let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user`);
let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass`); let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass`);
let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name`); let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name`);
let actions = document.querySelector(`#${entry.replaceAll(" ","-")}_actions`); let actions = document.querySelector(`#${entry.replaceAll(" ","-")}_actions`);
entry_user.remove() entry_user.remove()
entry_pass.remove() entry_pass.remove()
entry_name.remove() entry_name.remove()
actions.remove() actions.remove()
invoke("remove_entry",{name: entry}) invoke("remove_entry",{name: entry})
} }
async function editEntry(entry) { async function editEntry(entry) {
let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user > input`); let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user > input`);
let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass > input`); let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass > input`);
let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name > input`); let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name > input`);
let show_button = document.querySelector(`#${entry.replaceAll(" ","-")}_actions > .showbutton`); let show_button = document.querySelector(`#${entry.replaceAll(" ","-")}_actions > .showbutton`);
if(this.innerText == "Edit") { if(this.innerText == "Edit") {
let info = await invoke("get_entry",{ let info = await invoke("get_entry",{
name: entry_name.value, name: entry_name.value,
mpw: await get_pw() mpw: await get_pw()
}) })
entry_user.value = info[0]; entry_user.value = info[0];
entry_pass.value = info[1]; entry_pass.value = info[1];
entry_user.removeAttribute("readonly"); entry_user.removeAttribute("readonly");
entry_user.setAttribute("unselectable", "off") entry_user.setAttribute("unselectable", "off")
entry_user.type = "text"; entry_user.type = "text";
entry_pass.removeAttribute("readonly"); entry_pass.removeAttribute("readonly");
entry_pass.setAttribute("unselectable", "off") entry_pass.setAttribute("unselectable", "off")
entry_pass.type = "text"; entry_pass.type = "text";
entry_name.removeAttribute("readonly"); entry_name.removeAttribute("readonly");
entry_name.setAttribute("unselectable", "off") entry_name.setAttribute("unselectable", "off")
show_button.disabled = true; show_button.disabled = true;
this.innerText = "Save"; this.innerText = "Save";
this.Name = entry_name.value this.Name = entry_name.value
} else { } else {
//To Delete: this.Name //To Delete: this.Name
let isDeleted = await invoke("remove_entry", {name: this.Name}) let isDeleted = await invoke("remove_entry", {name: this.Name})
if(!isDeleted) { if(!isDeleted) {
alert("Could not edit entry!") alert("Could not edit entry!")
return; return;
} }
let success = await invoke("create_entry", {name: entry_name.value, username: entry_user.value, pw: entry_pass.value, mpw: await get_pw()}); let success = await invoke("create_entry", {name: entry_name.value, username: entry_user.value, pw: entry_pass.value, mpw: await get_pw()});
if(!success) { if(!success) {
alert("Could not edit entry!") alert("Could not edit entry!")
return; return;
} }
entry_user.setAttribute("readonly", true); entry_user.setAttribute("readonly", true);
entry_user.setAttribute("unselectable", "off") entry_user.setAttribute("unselectable", "off")
entry_user.type = "password" entry_user.type = "password"
entry_user.value = "PLACEHOLDER" entry_user.value = "PLACEHOLDER"
entry_pass.setAttribute("readonly", true); entry_pass.setAttribute("readonly", true);
entry_pass.setAttribute("unselectable", "off") entry_pass.setAttribute("unselectable", "off")
entry_pass.type = "password" entry_pass.type = "password"
entry_pass.value = "PLACEHOLDER!" entry_pass.value = "PLACEHOLDER!"
entry_name.setAttribute("readonly", true); entry_name.setAttribute("readonly", true);
entry_name.setAttribute("unselectable", "off") entry_name.setAttribute("unselectable", "off")
show_button.disabled = false; show_button.disabled = false;
this.innerText = "Edit"; this.innerText = "Edit";
} }
} }
async function ask_pw() { async function ask_pw() {
return await password_prompt("Enter your master password to proceed") return await password_prompt("Enter your master password to proceed")
} }
async function get_pw() { async function get_pw() {
let mpw = master_pw; let mpw = master_pw;
if(lock_status){ if(lock_status){
mpw = await ask_pw(); mpw = await ask_pw();
} }
return mpw; return mpw;
} }
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(" ","-")}_user > input`);
let entry_pass = document.querySelector(`#${entry_name.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",{
name: entry_name, name: entry_name,
mpw: await get_pw() mpw: await get_pw()
}) })
entry_user.value = info[0]; entry_user.value = info[0];
entry_pass.value = info[1]; entry_pass.value = info[1];
entry_user.type = "text"; entry_user.type = "text";
entry_pass.type = "text"; entry_pass.type = "text";
this.innerText = "Hide"; this.innerText = "Hide";
} else { } else {
entry_user.value = "PLACEHOLDER"; entry_user.value = "PLACEHOLDER";
entry_pass.value = "PLACEHOLDER!"; entry_pass.value = "PLACEHOLDER!";
entry_user.type = "password"; entry_user.type = "password";
entry_pass.type = "password"; entry_pass.type = "password";
this.innerText = "Show"; this.innerText = "Show";
} }
} }
async function createEntry() { async function createEntry() {
let entryNameField = document.querySelector("#createEntry_name > input"); let entryNameField = document.querySelector("#createEntry_name > input");
let entryUserField = document.querySelector("#createEntry_user > input"); let entryUserField = document.querySelector("#createEntry_user > input");
let entryPassField = document.querySelector("#createEntry_pass > input"); let entryPassField = document.querySelector("#createEntry_pass > input");
if(entryNameField.value == "" || entryUserField.value == "") { if(entryNameField.value == "" || entryUserField.value == "") {
alert("Not all needed fields filled out!"); alert("Not all needed fields filled out!");
return; return;
} }
if(entryPassField.value == "") { if(entryPassField.value == "") {
if(!(confirm("No password provided, do you want to generate a secure password?"))) { if(!(confirm("No password provided, do you want to generate a secure password?"))) {
alert("Cant create entry without password!"); alert("Cant create entry without password!");
return; return;
} }
entryPassField.value = await invoke("random_password"); entryPassField.value = await invoke("random_password");
} }
let mpw = await get_pw() let mpw = await get_pw()
let success = await invoke("create_entry", {name: entryNameField.value, username: entryUserField.value, pw: entryPassField.value, mpw: mpw}); let success = await invoke("create_entry", {name: entryNameField.value, username: entryUserField.value, pw: entryPassField.value, mpw: mpw});
if(success) { if(success) {
alert("Successfully created entry!"); alert("Successfully created entry!");
buildEntry(entryNameField.value) buildEntry(entryNameField.value)
entryNameField.value = "" entryNameField.value = ""
entryUserField.value = "" entryUserField.value = ""
entryPassField.value = "" entryPassField.value = ""
} else { } else {
alert("A critical error occured during entry creation"); alert("A critical error occured during entry creation");
} }
} }
async function toggleLock() { async function toggleLock() {
let txt = (lock_status && "Unlocked") || "Locked"; let txt = (lock_status && "Unlocked") || "Locked";
let src = (lock_status && "/images/security_lock_unlocked.png") || "/images/security_lock_locked.png"; let src = (lock_status && "/images/security_lock_unlocked.png") || "/images/security_lock_locked.png";
if(lock_status){ if(lock_status){
master_pw = await ask_pw(); master_pw = await ask_pw();
console.log(master_pw) console.log(master_pw)
if(master_pw == "" || master_pw == null)return; if(master_pw == "" || master_pw == null)return;
} }
document.getElementById("lockImg").title = txt; document.getElementById("lockImg").title = txt;
document.getElementById("lockImg").alt = txt; document.getElementById("lockImg").alt = txt;
document.getElementById("lockImg").src = src; document.getElementById("lockImg").src = src;
lock_status = !lock_status; lock_status = !lock_status;
} }

View File

@ -1,64 +1,64 @@
window.password_prompt = async function(label_message, submitbutton_message, cancelbutton_message) { window.password_prompt = async function(label_message, submitbutton_message, cancelbutton_message) {
return new Promise((res,rej) => { return new Promise((res,rej) => {
let width = 200,height = 100; let width = 200,height = 100;
if (typeof label_message !== "string") label_message = "Password:"; if (typeof label_message !== "string") label_message = "Password:";
if (typeof submitbutton_message !== "string") submitbutton_message = "Submit"; if (typeof submitbutton_message !== "string") submitbutton_message = "Submit";
if (typeof cancelbutton_message !== "string") cancelbutton_message = "Cancel"; if (typeof cancelbutton_message !== "string") cancelbutton_message = "Cancel";
let submit = function() { let submit = function() {
document.body.removeChild(div); document.body.removeChild(div);
window.removeEventListener("resize", resize, false); window.removeEventListener("resize", resize, false);
res(input.value) res(input.value)
}; };
let cancel = function() { let cancel = function() {
document.body.removeChild(div) document.body.removeChild(div)
window.removeEventListener("resize", resize, false) window.removeEventListener("resize", resize, false)
rej() rej()
} }
let resize = function() { let resize = function() {
div.style.left = ((window.innerWidth / 2) - (width / 2)) + "px"; div.style.left = ((window.innerWidth / 2) - (width / 2)) + "px";
div.style.top = ((window.innerHeight / 2) - (height / 2)) + "px"; div.style.top = ((window.innerHeight / 2) - (height / 2)) + "px";
}; };
let div = document.createElement("div"); let div = document.createElement("div");
div.id = "password_prompt"; div.id = "password_prompt";
let label = document.createElement("label"); let label = document.createElement("label");
label.id = "password_prompt_label"; label.id = "password_prompt_label";
label.innerHTML = label_message; label.innerHTML = label_message;
label.for = "password_prompt_input"; label.for = "password_prompt_input";
div.appendChild(label); div.appendChild(label);
div.appendChild(document.createElement("br")); div.appendChild(document.createElement("br"));
let input = document.createElement("input"); let input = document.createElement("input");
input.id = "password_prompt_input"; input.id = "password_prompt_input";
input.type = "password"; input.type = "password";
input.addEventListener("keyup", function(event) { input.addEventListener("keyup", function(event) {
if (event.key == "Enter") submit(); if (event.key == "Enter") submit();
}, false); }, false);
div.appendChild(input); div.appendChild(input);
div.appendChild(document.createElement("br")); div.appendChild(document.createElement("br"));
let actionDiv = document.createElement("div") let actionDiv = document.createElement("div")
let submitbutton = document.createElement("button"); let submitbutton = document.createElement("button");
submitbutton.innerHTML = submitbutton_message; submitbutton.innerHTML = submitbutton_message;
submitbutton.style.display = "inline-block" submitbutton.style.display = "inline-block"
submitbutton.addEventListener("click", submit, false); submitbutton.addEventListener("click", submit, false);
actionDiv.appendChild(submitbutton); actionDiv.appendChild(submitbutton);
let cancelbutton = document.createElement("button"); let cancelbutton = document.createElement("button");
cancelbutton.innerHTML = cancelbutton_message; cancelbutton.innerHTML = cancelbutton_message;
cancelbutton.style.display = "inline-block" cancelbutton.style.display = "inline-block"
cancelbutton.addEventListener("click", cancel, false); cancelbutton.addEventListener("click", cancel, false);
actionDiv.appendChild(cancelbutton); actionDiv.appendChild(cancelbutton);
div.appendChild(actionDiv) div.appendChild(actionDiv)
document.body.appendChild(div); document.body.appendChild(div);
window.addEventListener("resize", resize, false); window.addEventListener("resize", resize, false);
}) })
}; };

View File

@ -1,14 +1,30 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Settings</title> <title>Settings</title>
</head> </head>
<body> <body>
<h1 id="title"><a href="/" class="nostyle">IPass</a></h1> <h1 id="title"><a href="/" class="nostyle">IPass</a></h1>
<div>
</body> <h2>ISync</h2>
<h4>Keep your passwords up-to-date on multiple devices</h4>
<span>Current status: <b id="ISyncStatus">Checking</b></span>
<a href="/enableISync.html" class="nostyle" id="enableISync">Enable ISync</a>
</div>
<script>
const { invoke } = window.__TAURI__.tauri;
async function start() {
let status = await invoke("get_isync_status")
document.getElementById("ISyncStatus").innerText=status?"Enabled":"Disabled"
if(status){
document.getElementById("enableISync").remove()
}
}
start()
</script>
</body>
</html> </html>

View File

@ -1,211 +1,211 @@
:root { :root {
font-family: MonoLisa, Inter, Avenir, Helvetica, Arial, sans-serif; font-family: MonoLisa, Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px; font-size: 16px;
line-height: 24px; line-height: 24px;
font-weight: 400; font-weight: 400;
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
} }
:root { :root {
--green: #C2F9BB; /* links etc */ --green: #C2F9BB; /* links etc */
--fg-color: #303034; /* post background */ --fg-color: #303034; /* post background */
--bg-color: #1B1B1E; /* page background etc */ --bg-color: #1B1B1E; /* page background etc */
--text-color: #ECEAF1; /* text */ --text-color: #ECEAF1; /* text */
color: var(--text-color); color: var(--text-color);
background-color: var(--bg-color); background-color: var(--bg-color);
} }
a:hover { a:hover {
color: #24c8db; color: #24c8db;
} }
input, input,
button { button {
color: var(--text-color); color: var(--text-color);
background-color: var(--fg-color); background-color: var(--fg-color);
border-radius: 8px; border-radius: 8px;
border: 1px solid transparent; border: 1px solid transparent;
font-weight: 500; font-weight: 500;
font-family: inherit; font-family: inherit;
transition: border-color 0.25s; transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
} }
@media only screen and (max-width: 600px) { @media only screen and (max-width: 600px) {
input, input,
button { button {
padding: 4px 8px; padding: 4px 8px;
font-size: 0.8em; font-size: 0.8em;
} }
} }
@media only screen and (min-width: 600px) and (max-width: 900px) { @media only screen and (min-width: 600px) and (max-width: 900px) {
input, input,
button { button {
padding: 5px 10px; padding: 5px 10px;
font-size: 0.9em; font-size: 0.9em;
} }
} }
@media only screen and (min-width: 900px) { @media only screen and (min-width: 900px) {
input, input,
button { button {
padding: 6.4px 12.8px; padding: 6.4px 12.8px;
font-size: 1em; font-size: 1em;
} }
} }
tr { tr {
width: 50%; width: 50%;
} }
input:not([readonly]){ input:not([readonly]){
color: var(--fg-color); color: var(--fg-color);
background-color: var(--text-color); background-color: var(--text-color);
} }
h1 { h1 {
margin-left: 2em; margin-left: 2em;
} }
button { button {
cursor: pointer; cursor: pointer;
} }
button:hover { button:hover {
border-color: #396cd8; border-color: #396cd8;
} }
input, input,
button { button {
outline: none; outline: none;
} }
#table_div { #table_div {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: center; justify-content: center;
} }
.entry_name,.entry_user,.entry_pass { .entry_name,.entry_user,.entry_pass {
width: 70%; width: 70%;
} }
.entry_name > input,.entry_user > input,.entry_pass > input { .entry_name > input,.entry_user > input,.entry_pass > input {
width: 100%; width: 100%;
} }
.table_actions>div>button { .table_actions>div>button {
height: 40%; height: 40%;
} }
input[type="password"] { input[type="password"] {
user-select: none; user-select: none;
} }
#password_prompt { #password_prompt {
background: white; background: white;
color: black; color: black;
border: 1px solid black; border: 1px solid black;
width: 50%; width: 50%;
height: 25%; height: 25%;
position: fixed; position: fixed;
left: 25%; left: 25%;
top: 25%; top: 25%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
border: 3px double var(--fg-color); border: 3px double var(--fg-color);
border-radius: 5%; border-radius: 5%;
} }
#table_actions > div { #table_actions > div {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
} }
#table_actions > div > button { #table_actions > div > button {
margin-left: 3px; margin-left: 3px;
} }
#table_div > div > div { #table_div > div > div {
margin-bottom: 5px; margin-bottom: 5px;
} }
#createEntry_actions > button { #createEntry_actions > button {
width: 100%; width: 100%;
} }
#title { #title {
cursor: pointer; cursor: pointer;
} }
.select { .select {
padding: 5px 10px; padding: 5px 10px;
border: none; border: none;
color: white; color: white;
cursor: pointer; cursor: pointer;
position: absolute; position: absolute;
right: 1em; right: 1em;
top: 1em; top: 1em;
height: 50px; height: 50px;
width: 50px; width: 50px;
/* hide the default dropdown arrow */ /* hide the default dropdown arrow */
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
appearance: none; appearance: none;
} }
.select > div{ .select > div{
display: none; display: none;
position: absolute; position: absolute;
top: 4em; top: 4em;
} }
.select > div > div{ .select > div > div{
width: 60px; width: 60px;
} }
a.nostyle:link { a.nostyle:link {
text-decoration: inherit; text-decoration: inherit;
color: inherit; color: inherit;
} }
a.nostyle:visited { a.nostyle:visited {
text-decoration: inherit; text-decoration: inherit;
color: inherit; color: inherit;
} }
.select > img { .select > img {
transform: rotate(0deg); transform: rotate(0deg);
transition: transform 0.25s linear; transition: transform 0.25s linear;
} }
.select.open > img { .select.open > img {
transform: rotate(180deg); transform: rotate(180deg);
transition: transform 0.25s linear; transition: transform 0.25s linear;
} }
/* .select.open > div { /* .select.open > div {
transition: 1s ease-in; transition: 1s ease-in;
height: 8em; height: 8em;
overflow: hidden; overflow: hidden;
} }
.select > div { .select > div {
transform: none; transform: none;
height: 0; height: 0;
transition: 1s ease-out; transition: 1s ease-out;
} */ } */