From 624b69d6d13c06b7f013dadd2bbccc950d32f847 Mon Sep 17 00:00:00 2001 From: Code002Lover Arch Laptop Date: Tue, 7 Mar 2023 13:11:29 +0100 Subject: [PATCH] add simple ISync authentication --- .gitignore | 6 +- .gitmodules | 6 +- README.md | 2 +- src-tauri/Cargo.lock | 117 ++++--- src-tauri/Cargo.toml | 2 + src-tauri/build.rs | 6 +- src-tauri/src/main.rs | 160 +++++---- src-tauri/tauri.conf.json | 144 ++++----- src/enableISync.html | 40 +++ src/index.html | 82 ++--- src/main.js | 658 +++++++++++++++++++------------------- src/pwprompt.js | 126 ++++---- src/settings.html | 42 ++- src/style.css | 420 ++++++++++++------------ 14 files changed, 970 insertions(+), 841 deletions(-) create mode 100644 src/enableISync.html diff --git a/.gitignore b/.gitignore index 1864a66..bf24ef1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/src-tauri/target -*_backup -*ignore* +/src-tauri/target +*_backup +*ignore* msi/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 7051d49..18c6a68 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "library"] - path = library - url = https://github.com/002Hub/IPass-library +[submodule "library"] + path = library + url = https://github.com/002Hub/IPass-library diff --git a/README.md b/README.md index 59b7a86..ff78382 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# IPass +# IPass diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c3a4ba0..608b907 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -617,7 +617,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -672,24 +672,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" dependencies = [ "futures-core", "futures-task", @@ -698,15 +698,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", @@ -715,15 +715,15 @@ dependencies = [ [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-core", "futures-macro", @@ -1215,6 +1215,8 @@ name = "ipass-gui" version = "0.1.0" dependencies = [ "ip_lib", + "open", + "rand 0.8.5", "serde", "serde_json", "tauri", @@ -1593,6 +1595,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "open" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ecf2487e799604735754d2c5896106785987b441b5aee58f242e4d4963179a" +dependencies = [ + "pathdiff", +] + [[package]] name = "overload" version = "0.1.1" @@ -1644,7 +1655,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1653,6 +1664,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "percent-encoding" version = "2.2.0" @@ -2752,16 +2769,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.24.1" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" dependencies = [ "autocfg", "bytes", "memchr", "num_cpus", "pin-project-lite", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3225,12 +3242,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "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.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]] @@ -3241,9 +3282,9 @@ checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" @@ -3259,9 +3300,9 @@ checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" @@ -3277,9 +3318,9 @@ checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" @@ -3295,9 +3336,9 @@ checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" @@ -3313,15 +3354,15 @@ checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" @@ -3337,9 +3378,9 @@ checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winres" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4aa46de..ef1707c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -13,6 +13,8 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.2", features = ["dialog-confirm"] } ip_lib = { path = "../library/" } +rand="0.8.5" +open="3.4.0" [features] # by default Tauri runs in production mode diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 795b9b7..50c721e 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,3 @@ -fn main() { - tauri_build::build() -} +fn main() { + tauri_build::build() +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fb766e1..0842225 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,65 +1,95 @@ -#![cfg_attr( - all(not(debug_assertions), target_os = "linux"), - windows_subsystem = "windows" -)] - -extern crate ip_lib; - -// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command - -#[tauri::command] -fn get_version() -> String { - return 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 { - ip_lib::create_entry(&name, username+";"+pw, mpw) -} - -#[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(";"); - return Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string())); - } else { - return Err(binding.expect_err("expected error")); - } -} - -#[tauri::command] -fn get_entries() -> Vec { - let mut vector: Vec = Vec::default(); - for entry in ip_lib::get_entries() { - let entry_filename = entry.unwrap().file_name(); - let ent =entry_filename.to_str().unwrap(); - vector.insert(0, ent[..ent.len()-6].to_string()); - } - - vector.sort(); - - return 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(); - return true; - } - return false; -} - -fn main() { - tauri::Builder::default() - .invoke_handler(tauri::generate_handler![get_version,create_entry,random_password,get_entry,get_entries,remove_entry]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} +#![cfg_attr( + all(not(debug_assertions), target_os = "linux"), + windows_subsystem = "windows" +)] + +use std::fs::File; +use std::io::Write; + +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 { + return 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 { + ip_lib::create_entry(&name, username+";"+pw, mpw) +} + +#[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(";"); + return Ok((split.next().unwrap().to_string(),split.next().unwrap().to_string())); + } else { + return Err(binding.expect_err("expected error")); + } +} + +#[tauri::command] +fn get_entries() -> Vec { + let mut vector: Vec = 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(); + + return 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(); + return true; + } + 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"); +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 31a55c0..25566af 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,72 +1,72 @@ -{ - "build": { - "beforeDevCommand": "", - "beforeBuildCommand": "", - "devPath": "../src", - "distDir": "../src", - "withGlobalTauri": true - }, - "package": { - "productName": "ipass", - "version": "0.1.0" - }, - "tauri": { - "allowlist": { - "all": false, - "dialog": { - "all": false, - "open": false, - "save": false, - "ask": false, - "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" - } - ] - } -} +{ + "build": { + "beforeDevCommand": "", + "beforeBuildCommand": "", + "devPath": "../src", + "distDir": "../src", + "withGlobalTauri": true + }, + "package": { + "productName": "ipass", + "version": "0.1.0" + }, + "tauri": { + "allowlist": { + "all": false, + "dialog": { + "all": false, + "open": false, + "save": false, + "ask": false, + "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" + } + ] + } +} diff --git a/src/enableISync.html b/src/enableISync.html new file mode 100644 index 0000000..3883265 --- /dev/null +++ b/src/enableISync.html @@ -0,0 +1,40 @@ + + + + + + + Document + + + + Please authorise the Application in your browser! + + + \ No newline at end of file diff --git a/src/index.html b/src/index.html index 2eda5b8..962de7b 100644 --- a/src/index.html +++ b/src/index.html @@ -1,41 +1,41 @@ - - - - - - - IPass - x.x.x - - - - - -

IPass

-
- -
-
Locked
-
Lock
-
-
-
-
-
-
Entry name
-
-
-
-
Username
-
-
-
-
Password
-
-
-
-
Action
-
-
-
- - + + + + + + + IPass - x.x.x + + + + + +

IPass

+
+ +
+
Locked
+
Lock
+
+
+
+
+
+
Entry name
+
+
+
+
Username
+
+
+
+
Password
+
+
+
+
Action
+
+
+
+ + diff --git a/src/main.js b/src/main.js index 5940d65..5e430ff 100644 --- a/src/main.js +++ b/src/main.js @@ -1,330 +1,330 @@ -const { invoke } = window.__TAURI__.tauri; - -let master_pw; -let lock_status = true; - -// async function greet() { -// // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command -// greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); -// } - -window.addEventListener("DOMContentLoaded", () => { - document.getElementById("lockImg").addEventListener("click",toggleLock); - startup(); -}); - -async function startup() { - - let select = document.querySelector(".select"); - select.addEventListener("click", function(){ - this.enabled = !this.enabled - if(this.enabled) { - this.classList.add("open") - } else { - this.classList.remove("open") - } - - for(let cont of document.querySelectorAll(".select > div")) { - cont.style.display=(this.enabled && "block") || "none" - } - document.querySelector('#table_div').style.marginTop=(this.enabled && "8em") || "0px"; - }); - - - document.querySelector("#createEntry_actions > button").addEventListener("click",createEntry); - - let entries = await invoke("get_entries"); - - for(let i = 0; i < entries.length; i++) { - buildEntry(entries[i]); - } - - for (let input of document.querySelectorAll('input[readonly]')) { - input.addEventListener('click', async function() { - if(!input.hasAttribute("readonly"))return - if(input.getAttribute("type")!="text" && lock_status)return - - let to_copy = input.value - - if(!lock_status) { - let isUsername = input.parentElement.classList.contains("entry_user") - let entry_name = input.parentElement.id.slice(0,input.parentElement.id.length-5) - console.log(entry_name,input.parentElement.id) - - let info = await invoke("get_entry",{ - name: entry_name, - mpw: await get_pw() - }) - - if(isUsername) { - to_copy = info[0] - } else { - if(input.parentElement.classList.contains("entry_name")) { - to_copy = entry_name - } else { - to_copy = info[1] - } - } - } - - navigator.clipboard.writeText(to_copy).then(function() { - let originalColor = input.style.borderColor; - input.style.borderColor = "lightgreen"; - setTimeout(function(){ - input.style.borderColor = originalColor; - },250) - - console.log('Text copied to clipboard'); - }, function(err) { - - let originalColor = input.style.borderColor; - input.style.borderColor = "red"; - setTimeout(function(){ - input.style.borderColor = originalColor; - },500) - - console.error('Failed to copy text: ', err); - }); - }); - - } -} - -let entry_priority = 1 - -function buildEntry(entry) { - - entry_priority++; - - let nameDiv = document.createElement("div"); - nameDiv.setAttribute("class", "entry_name"); - nameDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_name`) - - let nameInput = document.createElement("input"); - nameInput.setAttribute("type", "text"); - nameInput.setAttribute("placeholder", "New Entry Name"); - nameInput.setAttribute("value", entry); - nameInput.setAttribute("readonly", true); - nameInput.setAttribute("unselectable", "on") - nameInput.setAttribute("tabindex",entry_priority) - nameDiv.appendChild(nameInput); - - let userDiv = document.createElement("div"); - userDiv.setAttribute("class", "entry_user"); - userDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_user`) - - let userInput = document.createElement("input"); - userInput.setAttribute("type", "password"); - userInput.setAttribute("placeholder", "New Username"); - userInput.setAttribute("value", "PLACEHOLDER"); - userInput.setAttribute("readonly", true); - userInput.setAttribute("unselectable", "on") - userInput.setAttribute("tabindex",entry_priority) - userDiv.appendChild(userInput); - - let passDiv = document.createElement("div"); - passDiv.setAttribute("class", "entry_pass"); - passDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_pass`) - - let passInput = document.createElement("input"); - passInput.setAttribute("type", "password"); - passInput.setAttribute("placeholder", "New Password"); - passInput.setAttribute("value", "PLACEHOLDER!"); - passInput.setAttribute("readonly", true); - passInput.setAttribute("unselectable", "on") - userInput.setAttribute("tabindex",entry_priority) - passDiv.appendChild(passInput); - - let showButton = document.createElement("button"); - showButton.innerText = "Show"; - showButton.addEventListener("click",showEntry.bind(showButton, entry),false); - showButton.setAttribute("class", "showbutton"); - showButton.setAttribute("tabindex",entry_priority) - - let editButton = document.createElement("button"); - editButton.innerText = "Edit"; - editButton.addEventListener("click", editEntry.bind(editButton, entry), false); - editButton.setAttribute("class", "editbutton"); - editButton.setAttribute("tabindex",entry_priority) - - let deleteButton = document.createElement("button"); - deleteButton.innerText = "Delete"; - deleteButton.addEventListener("click", deleteEntry.bind(deleteButton, entry), false); - deleteButton.setAttribute("class", "deletebutton"); - deleteButton.setAttribute("tabindex",entry_priority) - - let actionDiv = document.createElement("div") - actionDiv.appendChild(showButton) - actionDiv.appendChild(editButton) - actionDiv.appendChild(deleteButton) - - actionDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_actions`) - - document.getElementById("table_entries").appendChild(nameDiv) - document.getElementById("table_users").appendChild(userDiv) - document.getElementById("table_pwds").appendChild(passDiv) - document.getElementById("table_actions").appendChild(actionDiv) - -} - -function deleteEntry(entry) { - let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user`); - let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass`); - let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name`); - let actions = document.querySelector(`#${entry.replaceAll(" ","-")}_actions`); - - entry_user.remove() - entry_pass.remove() - entry_name.remove() - actions.remove() - invoke("remove_entry",{name: entry}) -} - -async function editEntry(entry) { - let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user > input`); - let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass > input`); - let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name > input`); - let show_button = document.querySelector(`#${entry.replaceAll(" ","-")}_actions > .showbutton`); - if(this.innerText == "Edit") { - - let info = await invoke("get_entry",{ - name: entry_name.value, - mpw: await get_pw() - }) - - entry_user.value = info[0]; - entry_pass.value = info[1]; - - entry_user.removeAttribute("readonly"); - entry_user.setAttribute("unselectable", "off") - entry_user.type = "text"; - entry_pass.removeAttribute("readonly"); - entry_pass.setAttribute("unselectable", "off") - entry_pass.type = "text"; - entry_name.removeAttribute("readonly"); - entry_name.setAttribute("unselectable", "off") - show_button.disabled = true; - this.innerText = "Save"; - - this.Name = entry_name.value - } else { - - //To Delete: this.Name - - let isDeleted = await invoke("remove_entry", {name: this.Name}) - if(!isDeleted) { - alert("Could not edit entry!") - return; - } - - let success = await invoke("create_entry", {name: entry_name.value, username: entry_user.value, pw: entry_pass.value, mpw: await get_pw()}); - if(!success) { - alert("Could not edit entry!") - return; - } - - - entry_user.setAttribute("readonly", true); - entry_user.setAttribute("unselectable", "off") - entry_user.type = "password" - entry_user.value = "PLACEHOLDER" - entry_pass.setAttribute("readonly", true); - entry_pass.setAttribute("unselectable", "off") - entry_pass.type = "password" - entry_pass.value = "PLACEHOLDER!" - entry_name.setAttribute("readonly", true); - entry_name.setAttribute("unselectable", "off") - show_button.disabled = false; - this.innerText = "Edit"; - } -} - -async function ask_pw() { - return await password_prompt("Enter your master password to proceed") -} - -async function get_pw() { - let mpw = master_pw; - - if(lock_status){ - mpw = await ask_pw(); - } - - return mpw; -} - -async function showEntry(entry_name) { - let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-")}_user > input`); - let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-")}_pass > input`); - - if(this.innerText == "Show"){ - let info = await invoke("get_entry",{ - name: entry_name, - mpw: await get_pw() - }) - entry_user.value = info[0]; - entry_pass.value = info[1]; - entry_user.type = "text"; - entry_pass.type = "text"; - this.innerText = "Hide"; - } else { - entry_user.value = "PLACEHOLDER"; - entry_pass.value = "PLACEHOLDER!"; - entry_user.type = "password"; - entry_pass.type = "password"; - this.innerText = "Show"; - } -} - - - -async function createEntry() { - let entryNameField = document.querySelector("#createEntry_name > input"); - let entryUserField = document.querySelector("#createEntry_user > input"); - let entryPassField = document.querySelector("#createEntry_pass > input"); - - if(entryNameField.value == "" || entryUserField.value == "") { - alert("Not all needed fields filled out!"); - return; - } - - if(entryPassField.value == "") { - if(!(confirm("No password provided, do you want to generate a secure password?"))) { - alert("Cant create entry without password!"); - return; - } - entryPassField.value = await invoke("random_password"); - } - - let mpw = await get_pw() - - let success = await invoke("create_entry", {name: entryNameField.value, username: entryUserField.value, pw: entryPassField.value, mpw: mpw}); - - if(success) { - alert("Successfully created entry!"); - buildEntry(entryNameField.value) - entryNameField.value = "" - entryUserField.value = "" - entryPassField.value = "" - } else { - alert("A critical error occured during entry creation"); - } - -} - -async function toggleLock() { - let txt = (lock_status && "Unlocked") || "Locked"; - let src = (lock_status && "/images/security_lock_unlocked.png") || "/images/security_lock_locked.png"; - - if(lock_status){ - master_pw = await ask_pw(); - console.log(master_pw) - if(master_pw == "" || master_pw == null)return; - } - - document.getElementById("lockImg").title = txt; - document.getElementById("lockImg").alt = txt; - document.getElementById("lockImg").src = src; - - lock_status = !lock_status; +const { invoke } = window.__TAURI__.tauri; + +let master_pw; +let lock_status = true; + +// async function greet() { +// // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command +// greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); +// } + +window.addEventListener("DOMContentLoaded", () => { + document.getElementById("lockImg").addEventListener("click",toggleLock); + startup(); +}); + +async function startup() { + + let select = document.querySelector(".select"); + select.addEventListener("click", function(){ + this.enabled = !this.enabled + if(this.enabled) { + this.classList.add("open") + } else { + this.classList.remove("open") + } + + for(let cont of document.querySelectorAll(".select > div")) { + cont.style.display=(this.enabled && "block") || "none" + } + document.querySelector('#table_div').style.marginTop=(this.enabled && "8em") || "0px"; + }); + + + document.querySelector("#createEntry_actions > button").addEventListener("click",createEntry); + + let entries = await invoke("get_entries"); + + for(let i = 0; i < entries.length; i++) { + buildEntry(entries[i]); + } + + for (let input of document.querySelectorAll('input[readonly]')) { + input.addEventListener('click', async function() { + if(!input.hasAttribute("readonly"))return + if(input.getAttribute("type")!="text" && lock_status)return + + let to_copy = input.value + + if(!lock_status) { + let isUsername = input.parentElement.classList.contains("entry_user") + let entry_name = input.parentElement.id.slice(0,input.parentElement.id.length-5) + console.log(entry_name,input.parentElement.id) + + let info = await invoke("get_entry",{ + name: entry_name, + mpw: await get_pw() + }) + + if(isUsername) { + to_copy = info[0] + } else { + if(input.parentElement.classList.contains("entry_name")) { + to_copy = entry_name + } else { + to_copy = info[1] + } + } + } + + navigator.clipboard.writeText(to_copy).then(function() { + let originalColor = input.style.borderColor; + input.style.borderColor = "lightgreen"; + setTimeout(function(){ + input.style.borderColor = originalColor; + },250) + + console.log('Text copied to clipboard'); + }, function(err) { + + let originalColor = input.style.borderColor; + input.style.borderColor = "red"; + setTimeout(function(){ + input.style.borderColor = originalColor; + },500) + + console.error('Failed to copy text: ', err); + }); + }); + + } +} + +let entry_priority = 1 + +function buildEntry(entry) { + + entry_priority++; + + let nameDiv = document.createElement("div"); + nameDiv.setAttribute("class", "entry_name"); + nameDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_name`) + + let nameInput = document.createElement("input"); + nameInput.setAttribute("type", "text"); + nameInput.setAttribute("placeholder", "New Entry Name"); + nameInput.setAttribute("value", entry); + nameInput.setAttribute("readonly", true); + nameInput.setAttribute("unselectable", "on") + nameInput.setAttribute("tabindex",entry_priority) + nameDiv.appendChild(nameInput); + + let userDiv = document.createElement("div"); + userDiv.setAttribute("class", "entry_user"); + userDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_user`) + + let userInput = document.createElement("input"); + userInput.setAttribute("type", "password"); + userInput.setAttribute("placeholder", "New Username"); + userInput.setAttribute("value", "PLACEHOLDER"); + userInput.setAttribute("readonly", true); + userInput.setAttribute("unselectable", "on") + userInput.setAttribute("tabindex",entry_priority) + userDiv.appendChild(userInput); + + let passDiv = document.createElement("div"); + passDiv.setAttribute("class", "entry_pass"); + passDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_pass`) + + let passInput = document.createElement("input"); + passInput.setAttribute("type", "password"); + passInput.setAttribute("placeholder", "New Password"); + passInput.setAttribute("value", "PLACEHOLDER!"); + passInput.setAttribute("readonly", true); + passInput.setAttribute("unselectable", "on") + userInput.setAttribute("tabindex",entry_priority) + passDiv.appendChild(passInput); + + let showButton = document.createElement("button"); + showButton.innerText = "Show"; + showButton.addEventListener("click",showEntry.bind(showButton, entry),false); + showButton.setAttribute("class", "showbutton"); + showButton.setAttribute("tabindex",entry_priority) + + let editButton = document.createElement("button"); + editButton.innerText = "Edit"; + editButton.addEventListener("click", editEntry.bind(editButton, entry), false); + editButton.setAttribute("class", "editbutton"); + editButton.setAttribute("tabindex",entry_priority) + + let deleteButton = document.createElement("button"); + deleteButton.innerText = "Delete"; + deleteButton.addEventListener("click", deleteEntry.bind(deleteButton, entry), false); + deleteButton.setAttribute("class", "deletebutton"); + deleteButton.setAttribute("tabindex",entry_priority) + + let actionDiv = document.createElement("div") + actionDiv.appendChild(showButton) + actionDiv.appendChild(editButton) + actionDiv.appendChild(deleteButton) + + actionDiv.setAttribute("id",`${entry.replaceAll(" ","-")}_actions`) + + document.getElementById("table_entries").appendChild(nameDiv) + document.getElementById("table_users").appendChild(userDiv) + document.getElementById("table_pwds").appendChild(passDiv) + document.getElementById("table_actions").appendChild(actionDiv) + +} + +function deleteEntry(entry) { + let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user`); + let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass`); + let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name`); + let actions = document.querySelector(`#${entry.replaceAll(" ","-")}_actions`); + + entry_user.remove() + entry_pass.remove() + entry_name.remove() + actions.remove() + invoke("remove_entry",{name: entry}) +} + +async function editEntry(entry) { + let entry_user = document.querySelector(`#${entry.replaceAll(" ","-")}_user > input`); + let entry_pass = document.querySelector(`#${entry.replaceAll(" ","-")}_pass > input`); + let entry_name = document.querySelector(`#${entry.replaceAll(" ","-")}_name > input`); + let show_button = document.querySelector(`#${entry.replaceAll(" ","-")}_actions > .showbutton`); + if(this.innerText == "Edit") { + + let info = await invoke("get_entry",{ + name: entry_name.value, + mpw: await get_pw() + }) + + entry_user.value = info[0]; + entry_pass.value = info[1]; + + entry_user.removeAttribute("readonly"); + entry_user.setAttribute("unselectable", "off") + entry_user.type = "text"; + entry_pass.removeAttribute("readonly"); + entry_pass.setAttribute("unselectable", "off") + entry_pass.type = "text"; + entry_name.removeAttribute("readonly"); + entry_name.setAttribute("unselectable", "off") + show_button.disabled = true; + this.innerText = "Save"; + + this.Name = entry_name.value + } else { + + //To Delete: this.Name + + let isDeleted = await invoke("remove_entry", {name: this.Name}) + if(!isDeleted) { + alert("Could not edit entry!") + return; + } + + let success = await invoke("create_entry", {name: entry_name.value, username: entry_user.value, pw: entry_pass.value, mpw: await get_pw()}); + if(!success) { + alert("Could not edit entry!") + return; + } + + + entry_user.setAttribute("readonly", true); + entry_user.setAttribute("unselectable", "off") + entry_user.type = "password" + entry_user.value = "PLACEHOLDER" + entry_pass.setAttribute("readonly", true); + entry_pass.setAttribute("unselectable", "off") + entry_pass.type = "password" + entry_pass.value = "PLACEHOLDER!" + entry_name.setAttribute("readonly", true); + entry_name.setAttribute("unselectable", "off") + show_button.disabled = false; + this.innerText = "Edit"; + } +} + +async function ask_pw() { + return await password_prompt("Enter your master password to proceed") +} + +async function get_pw() { + let mpw = master_pw; + + if(lock_status){ + mpw = await ask_pw(); + } + + return mpw; +} + +async function showEntry(entry_name) { + let entry_user = document.querySelector(`#${entry_name.replaceAll(" ","-")}_user > input`); + let entry_pass = document.querySelector(`#${entry_name.replaceAll(" ","-")}_pass > input`); + + if(this.innerText == "Show"){ + let info = await invoke("get_entry",{ + name: entry_name, + mpw: await get_pw() + }) + entry_user.value = info[0]; + entry_pass.value = info[1]; + entry_user.type = "text"; + entry_pass.type = "text"; + this.innerText = "Hide"; + } else { + entry_user.value = "PLACEHOLDER"; + entry_pass.value = "PLACEHOLDER!"; + entry_user.type = "password"; + entry_pass.type = "password"; + this.innerText = "Show"; + } +} + + + +async function createEntry() { + let entryNameField = document.querySelector("#createEntry_name > input"); + let entryUserField = document.querySelector("#createEntry_user > input"); + let entryPassField = document.querySelector("#createEntry_pass > input"); + + if(entryNameField.value == "" || entryUserField.value == "") { + alert("Not all needed fields filled out!"); + return; + } + + if(entryPassField.value == "") { + if(!(confirm("No password provided, do you want to generate a secure password?"))) { + alert("Cant create entry without password!"); + return; + } + entryPassField.value = await invoke("random_password"); + } + + let mpw = await get_pw() + + let success = await invoke("create_entry", {name: entryNameField.value, username: entryUserField.value, pw: entryPassField.value, mpw: mpw}); + + if(success) { + alert("Successfully created entry!"); + buildEntry(entryNameField.value) + entryNameField.value = "" + entryUserField.value = "" + entryPassField.value = "" + } else { + alert("A critical error occured during entry creation"); + } + +} + +async function toggleLock() { + let txt = (lock_status && "Unlocked") || "Locked"; + let src = (lock_status && "/images/security_lock_unlocked.png") || "/images/security_lock_locked.png"; + + if(lock_status){ + master_pw = await ask_pw(); + console.log(master_pw) + if(master_pw == "" || master_pw == null)return; + } + + document.getElementById("lockImg").title = txt; + document.getElementById("lockImg").alt = txt; + document.getElementById("lockImg").src = src; + + lock_status = !lock_status; } \ No newline at end of file diff --git a/src/pwprompt.js b/src/pwprompt.js index b4040b7..4ad468f 100644 --- a/src/pwprompt.js +++ b/src/pwprompt.js @@ -1,64 +1,64 @@ -window.password_prompt = async function(label_message, submitbutton_message, cancelbutton_message) { - return new Promise((res,rej) => { - let width = 200,height = 100; - if (typeof label_message !== "string") label_message = "Password:"; - if (typeof submitbutton_message !== "string") submitbutton_message = "Submit"; - if (typeof cancelbutton_message !== "string") cancelbutton_message = "Cancel"; - - let submit = function() { - document.body.removeChild(div); - window.removeEventListener("resize", resize, false); - res(input.value) - }; - let cancel = function() { - document.body.removeChild(div) - window.removeEventListener("resize", resize, false) - rej() - } - let resize = function() { - div.style.left = ((window.innerWidth / 2) - (width / 2)) + "px"; - div.style.top = ((window.innerHeight / 2) - (height / 2)) + "px"; - }; - - let div = document.createElement("div"); - div.id = "password_prompt"; - - - let label = document.createElement("label"); - label.id = "password_prompt_label"; - label.innerHTML = label_message; - label.for = "password_prompt_input"; - div.appendChild(label); - - div.appendChild(document.createElement("br")); - - let input = document.createElement("input"); - input.id = "password_prompt_input"; - input.type = "password"; - input.addEventListener("keyup", function(event) { - if (event.key == "Enter") submit(); - }, false); - div.appendChild(input); - - div.appendChild(document.createElement("br")); - - let actionDiv = document.createElement("div") - - let submitbutton = document.createElement("button"); - submitbutton.innerHTML = submitbutton_message; - submitbutton.style.display = "inline-block" - submitbutton.addEventListener("click", submit, false); - actionDiv.appendChild(submitbutton); - - let cancelbutton = document.createElement("button"); - cancelbutton.innerHTML = cancelbutton_message; - cancelbutton.style.display = "inline-block" - cancelbutton.addEventListener("click", cancel, false); - actionDiv.appendChild(cancelbutton); - - div.appendChild(actionDiv) - - document.body.appendChild(div); - window.addEventListener("resize", resize, false); - }) +window.password_prompt = async function(label_message, submitbutton_message, cancelbutton_message) { + return new Promise((res,rej) => { + let width = 200,height = 100; + if (typeof label_message !== "string") label_message = "Password:"; + if (typeof submitbutton_message !== "string") submitbutton_message = "Submit"; + if (typeof cancelbutton_message !== "string") cancelbutton_message = "Cancel"; + + let submit = function() { + document.body.removeChild(div); + window.removeEventListener("resize", resize, false); + res(input.value) + }; + let cancel = function() { + document.body.removeChild(div) + window.removeEventListener("resize", resize, false) + rej() + } + let resize = function() { + div.style.left = ((window.innerWidth / 2) - (width / 2)) + "px"; + div.style.top = ((window.innerHeight / 2) - (height / 2)) + "px"; + }; + + let div = document.createElement("div"); + div.id = "password_prompt"; + + + let label = document.createElement("label"); + label.id = "password_prompt_label"; + label.innerHTML = label_message; + label.for = "password_prompt_input"; + div.appendChild(label); + + div.appendChild(document.createElement("br")); + + let input = document.createElement("input"); + input.id = "password_prompt_input"; + input.type = "password"; + input.addEventListener("keyup", function(event) { + if (event.key == "Enter") submit(); + }, false); + div.appendChild(input); + + div.appendChild(document.createElement("br")); + + let actionDiv = document.createElement("div") + + let submitbutton = document.createElement("button"); + submitbutton.innerHTML = submitbutton_message; + submitbutton.style.display = "inline-block" + submitbutton.addEventListener("click", submit, false); + actionDiv.appendChild(submitbutton); + + let cancelbutton = document.createElement("button"); + cancelbutton.innerHTML = cancelbutton_message; + cancelbutton.style.display = "inline-block" + cancelbutton.addEventListener("click", cancel, false); + actionDiv.appendChild(cancelbutton); + + div.appendChild(actionDiv) + + document.body.appendChild(div); + window.addEventListener("resize", resize, false); + }) }; \ No newline at end of file diff --git a/src/settings.html b/src/settings.html index 750cbd9..565a217 100644 --- a/src/settings.html +++ b/src/settings.html @@ -1,14 +1,30 @@ - - - - - - - - Settings - - -

IPass

- - + + + + + + + + Settings + + +

IPass

+
+

ISync

+

Keep your passwords up-to-date on multiple devices

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