Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
Improved encryption and tray handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Levminer committed Sep 2, 2022
1 parent 981293c commit b82c7f2
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 50 deletions.
5 changes: 3 additions & 2 deletions core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ argon2 = "0.4"
rand_core = { version = "0.6", features = ["std"] }
magic-crypt = "3.1.10"
keyring = "1.2.0"
once_cell = "1.14.0"

[features]
# by default Tauri runs in production mode
Expand Down
28 changes: 22 additions & 6 deletions core/src/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
};

use magic_crypt::{new_magic_crypt, MagicCryptTrait};

use once_cell::sync::Lazy;
use std::sync::Mutex;
extern crate keyring;

static ENCRYPTION_KEY: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new("".to_owned()));

#[tauri::command]
pub fn encrypt_password(password: String) -> String {
let salt = SaltString::generate(&mut OsRng);
Expand Down Expand Up @@ -41,7 +43,8 @@ pub fn verify_password(password: String, hash: String) -> bool {
}

#[tauri::command]
pub fn encrypt_data(key: String, data: String) -> String {
pub fn encrypt_data(data: String) -> String {
let key = ENCRYPTION_KEY.lock().unwrap().to_string();
let mc = new_magic_crypt!(key, 256);

let encrypted_string = mc.encrypt_str_to_base64(data);
Expand All @@ -50,10 +53,13 @@ pub fn encrypt_data(key: String, data: String) -> String {
}

#[tauri::command]
pub fn decrypt_data(key: String, data: String) -> String {
pub fn decrypt_data(data: String) -> String {
let key = ENCRYPTION_KEY.lock().unwrap().to_string();
let mc = new_magic_crypt!(key, 256);

let decrypted_string = mc.decrypt_base64_to_string(data).unwrap();
let decrypted_string = mc
.decrypt_base64_to_string(data)
.unwrap_or_else(|error| "error".into());

decrypted_string.into()
}
Expand All @@ -63,7 +69,7 @@ pub fn set_entry(name: String, data: String) {
let service = "authme_dev";
let entry = keyring::Entry::new(&service, &name);

entry.set_password(data.as_str());
entry.set_password(data.as_str()).unwrap();
}

#[tauri::command]
Expand All @@ -75,3 +81,13 @@ pub fn get_entry(name: String) -> String {

item.into()
}

#[tauri::command]
pub fn receive_encryption_key(key: String) {
*ENCRYPTION_KEY.lock().unwrap() = key
}

#[tauri::command]
pub fn set_encryption_key() {
*ENCRYPTION_KEY.lock().unwrap() = get_entry("encryptionKey".to_string())
}
18 changes: 18 additions & 0 deletions core/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ fn main() {
encryption::decrypt_data,
encryption::set_entry,
encryption::get_entry,
encryption::receive_encryption_key,
encryption::set_encryption_key,
])
.system_tray(make_tray())
.on_system_tray_event(handle_tray_event)
Expand Down Expand Up @@ -118,6 +120,22 @@ fn main() {
Ok(())
})
.on_window_event(|event| match event.event() {
tauri::WindowEvent::CloseRequested { api, .. } => {
api.prevent_close();
let app = event.window().app_handle();

let window = app.get_window("main").unwrap();
let menu_item = app.tray_handle().get_item("toggle");

if window.is_visible().unwrap() {
window.hide().unwrap();
menu_item.set_title("Show Authme").unwrap();
} else {
window.show().unwrap();
menu_item.set_title("Hide Authme").unwrap();
}
}

tauri::WindowEvent::Focused(focused) => {
let app = event.window().app_handle();

Expand Down
15 changes: 1 addition & 14 deletions interface/layout/app.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
import App from "./app.svelte"
import "../styles/index.css"
import { fs, path, os, event, window } from "@tauri-apps/api"
import { os, event, window } from "@tauri-apps/api"
import { getSettings } from "../stores/settings"
import { navigate } from "../libraries/navigate"

const settings = getSettings()

const getSettingsPath = async () => {
const folderPath = await path.join(await path.configDir(), "Levminer", "Authme 4")
fs.createDir(folderPath, { recursive: true })

const settingsPath = await path.join(folderPath, "settings")
fs.createDir(settingsPath, { recursive: true })

const codesPath = await path.join(folderPath, "codes")
fs.createDir(codesPath, { recursive: true })
}

getSettingsPath()

const setBackground = async () => {
const system = await os.type()
const build = await os.version()
Expand Down
22 changes: 18 additions & 4 deletions interface/libraries/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,27 @@ export const getEntry = async (name: string): Promise<string> => {
/**
* Encrypts a string with the encryption key
*/
export const encryptData = async (key: string, data: string): Promise<string> => {
return await invoke("encrypt_data", { key, data })
export const encryptData = async (data: string): Promise<string> => {
return await invoke("encrypt_data", { data })
}

/**
* Decrypts a string with the encryption key
*/
export const decryptData = async (key: string, data: string): Promise<string> => {
return await invoke("decrypt_data", { key, data })
export const decryptData = async (data: string): Promise<string> => {
return await invoke("decrypt_data", { data })
}

/**
* Set the encryption key on the backend
*/
export const setEncryptionKey = async () => {
return await invoke("set_encryption_key")
}

/**
* Set the encryption key on the backend
*/
export const sendEncryptionKey = async (key: string) => {
return await invoke("receive_encryption_key", { key })
}
1 change: 0 additions & 1 deletion interface/libraries/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ declare global {
interface LibState {
authenticated: boolean
importData: null | string
encryptionKey: null | string
}

interface LibSearchQuery {
Expand Down
1 change: 0 additions & 1 deletion interface/stores/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { writable, get } from "svelte/store"
const defaultState: LibState = {
authenticated: false,
importData: null,
encryptionKey: null,
}

export const state = writable<LibState>(sessionStorage.state ? JSON.parse(sessionStorage.state) : defaultState)
Expand Down
6 changes: 2 additions & 4 deletions interface/windows/codes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ export const chooseImportFile = async () => {
}

const saveCodes = async () => {
const encryptionKey = state.encryptionKey
const encryptedText = await encryptData(encryptionKey, saveText)
const encryptedText = await encryptData(saveText)

state.importData = null
settings.vault.codes = encryptedText
Expand All @@ -297,8 +296,7 @@ export const loadCodes = async () => {
}

if (savedCodes === true) {
const encryptionKey = state.encryptionKey
const decryptedText = await decryptData(encryptionKey, settings.vault.codes)
const decryptedText = await decryptData(settings.vault.codes)

if (state.importData !== null) {
// There are saved and new codes
Expand Down
4 changes: 3 additions & 1 deletion interface/windows/confirm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { navigate } from "../../libraries/navigate"
import { getSettings } from "../../stores/settings"
import { dialog, invoke } from "@tauri-apps/api"
import { getState, setState } from "../../stores/state"
import { sendEncryptionKey } from "interface/libraries/encryption"

export const confirmPassword = async () => {
const settings = getSettings()
Expand All @@ -12,7 +13,8 @@ export const confirmPassword = async () => {
if (result === true) {
const state = getState()

state.encryptionKey = input
await sendEncryptionKey(input)

state.authenticated = true
setState(state)

Expand Down
8 changes: 2 additions & 6 deletions interface/windows/edit/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { textConverter } from "../../libraries/convert"
import { dialog, fs, path } from "@tauri-apps/api"
import { getSettings, setSettings } from "../../stores/settings"
import { getState } from "../../stores/state"
import { navigate } from "../../libraries/navigate"
import { decryptData, encryptData } from "interface/libraries/encryption"

const state = getState()
const settings = getSettings()
let names: string[] = []
let issuers: string[] = []
Expand Down Expand Up @@ -73,13 +71,12 @@ const generateEditElements = () => {
*/
export const loadSavedCodes = async () => {
const codes = settings.vault.codes
const encryptionKey = state.encryptionKey

if (codes === null) {
return dialog.message("No save file found. \n\nGo to the codes or the import page and import your codes!", { type: "error" })
}

const decryptedText = await decryptData(encryptionKey, codes)
const decryptedText = await decryptData(codes)
const data = textConverter(decryptedText, 0)

names = data.names
Expand All @@ -106,8 +103,7 @@ export const saveChanges = async () => {
saveText += string
}

const encryptionKey = state.encryptionKey
const encryptedText = await encryptData(encryptionKey, saveText)
const encryptedText = await encryptData(saveText)

settings.vault.codes = encryptedText
setSettings(settings)
Expand Down
4 changes: 1 addition & 3 deletions interface/windows/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ let codesText: string
*/
export const exportCodes = async () => {
const settings = getSettings()
const state = getState()

const codes = settings.vault.codes
const encryptionKey = state.encryptionKey

if (codes !== null) {
document.querySelector(".saveExportedCodes").style.display = "block"
document.querySelector(".exportCodes").style.display = "none"

const decryptedText = await decryptData(encryptionKey, codes)
const decryptedText = await decryptData(codes)

codesArray = textConverter(decryptedText, 0)
codesText = decryptedText
Expand Down
9 changes: 4 additions & 5 deletions interface/windows/landing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { navigate } from "../../libraries/navigate"
import { getSettings, setSettings } from "../../stores/settings"
import { getState, setState } from "../../stores/state"
import { dialog, invoke } from "@tauri-apps/api"
import { getEntry, setEntry, generateRandomKey } from "interface/libraries/encryption"
import { setEntry, generateRandomKey, setEncryptionKey } from "interface/libraries/encryption"

export const noPassword = async () => {
const settings = getSettings()
Expand All @@ -11,10 +11,9 @@ export const noPassword = async () => {
const key = await generateRandomKey()

await setEntry("encryptionKey", key.toString("base64"))
await setEncryptionKey()

settings.security.requireAuthentication = false

state.encryptionKey = key.toString("base64")
state.authenticated = true

setSettings(settings)
Expand Down Expand Up @@ -59,9 +58,9 @@ export const appController = async () => {
const state = getState()

if (settings.security.requireAuthentication === false) {
state.authenticated = true
state.encryptionKey = await getEntry("encryptionKey")
await setEncryptionKey()

state.authenticated = true
setState(state)

navigate("codes")
Expand Down
3 changes: 0 additions & 3 deletions interface/windows/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ export const clearData = async () => {
localStorage.clear()
sessionStorage.clear()

const folderPath = await path.join(await path.configDir(), "Levminer", "Authme 4")
await fs.removeDir(folderPath, { recursive: true })

resetState()
resetSettings()

Expand Down

0 comments on commit b82c7f2

Please sign in to comment.