mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 14:10:52 +01:00
implemented device name
This commit is contained in:
1
src-tauri/database/migrations/0009_curved_selene.sql
Normal file
1
src-tauri/database/migrations/0009_curved_selene.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `haex_settings` ADD `type` text;
|
||||
634
src-tauri/database/migrations/meta/0009_snapshot.json
Normal file
634
src-tauri/database/migrations/meta/0009_snapshot.json
Normal file
@ -0,0 +1,634 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "c3a688c3-9537-4aa8-be95-a8f55546caf1",
|
||||
"prevId": "c4edecb8-6aef-49e2-8498-0c4b74653c75",
|
||||
"tables": {
|
||||
"haex_extensions": {
|
||||
"name": "haex_extensions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"author": {
|
||||
"name": "author",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"enabled": {
|
||||
"name": "enabled",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"version": {
|
||||
"name": "version",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_extensions_permissions": {
|
||||
"name": "haex_extensions_permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"extension_id": {
|
||||
"name": "extension_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"resource": {
|
||||
"name": "resource",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"operation": {
|
||||
"name": "operation",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"path": {
|
||||
"name": "path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_TIMESTAMP)"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"haex_extensions_permissions_extension_id_resource_operation_path_unique": {
|
||||
"name": "haex_extensions_permissions_extension_id_resource_operation_path_unique",
|
||||
"columns": [
|
||||
"extension_id",
|
||||
"resource",
|
||||
"operation",
|
||||
"path"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"haex_extensions_permissions_extension_id_haex_extensions_id_fk": {
|
||||
"name": "haex_extensions_permissions_extension_id_haex_extensions_id_fk",
|
||||
"tableFrom": "haex_extensions_permissions",
|
||||
"tableTo": "haex_extensions",
|
||||
"columnsFrom": [
|
||||
"extension_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_notifications": {
|
||||
"name": "haex_notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"alt": {
|
||||
"name": "alt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"date": {
|
||||
"name": "date",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"read": {
|
||||
"name": "read",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"text": {
|
||||
"name": "text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_passwords_group_items": {
|
||||
"name": "haex_passwords_group_items",
|
||||
"columns": {
|
||||
"group_id": {
|
||||
"name": "group_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"item_id": {
|
||||
"name": "item_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"haex_passwords_group_items_group_id_haex_passwords_groups_id_fk": {
|
||||
"name": "haex_passwords_group_items_group_id_haex_passwords_groups_id_fk",
|
||||
"tableFrom": "haex_passwords_group_items",
|
||||
"tableTo": "haex_passwords_groups",
|
||||
"columnsFrom": [
|
||||
"group_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"haex_passwords_group_items_item_id_haex_passwords_item_details_id_fk": {
|
||||
"name": "haex_passwords_group_items_item_id_haex_passwords_item_details_id_fk",
|
||||
"tableFrom": "haex_passwords_group_items",
|
||||
"tableTo": "haex_passwords_item_details",
|
||||
"columnsFrom": [
|
||||
"item_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"haex_passwords_group_items_item_id_group_id_pk": {
|
||||
"columns": [
|
||||
"item_id",
|
||||
"group_id"
|
||||
],
|
||||
"name": "haex_passwords_group_items_item_id_group_id_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_passwords_groups": {
|
||||
"name": "haex_passwords_groups",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"order": {
|
||||
"name": "order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"parent_id": {
|
||||
"name": "parent_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_TIMESTAMP)"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"haex_passwords_groups_parent_id_haex_passwords_groups_id_fk": {
|
||||
"name": "haex_passwords_groups_parent_id_haex_passwords_groups_id_fk",
|
||||
"tableFrom": "haex_passwords_groups",
|
||||
"tableTo": "haex_passwords_groups",
|
||||
"columnsFrom": [
|
||||
"parent_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_passwords_item_details": {
|
||||
"name": "haex_passwords_item_details",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"note": {
|
||||
"name": "note",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"tags": {
|
||||
"name": "tags",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_TIMESTAMP)"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_passwords_item_history": {
|
||||
"name": "haex_passwords_item_history",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"item_id": {
|
||||
"name": "item_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"changed_property": {
|
||||
"name": "changed_property",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"old_value": {
|
||||
"name": "old_value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"new_value": {
|
||||
"name": "new_value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_TIMESTAMP)"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"haex_passwords_item_history_item_id_haex_passwords_item_details_id_fk": {
|
||||
"name": "haex_passwords_item_history_item_id_haex_passwords_item_details_id_fk",
|
||||
"tableFrom": "haex_passwords_item_history",
|
||||
"tableTo": "haex_passwords_item_details",
|
||||
"columnsFrom": [
|
||||
"item_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_passwords_item_key_values": {
|
||||
"name": "haex_passwords_item_key_values",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"item_id": {
|
||||
"name": "item_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"haex_passwords_item_key_values_item_id_haex_passwords_item_details_id_fk": {
|
||||
"name": "haex_passwords_item_key_values_item_id_haex_passwords_item_details_id_fk",
|
||||
"tableFrom": "haex_passwords_item_key_values",
|
||||
"tableTo": "haex_passwords_item_details",
|
||||
"columnsFrom": [
|
||||
"item_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_settings": {
|
||||
"name": "haex_settings",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@ -64,6 +64,13 @@
|
||||
"when": 1749727958231,
|
||||
"tag": "0008_faulty_mercury",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "6",
|
||||
"when": 1750158916787,
|
||||
"tag": "0009_curved_selene",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -11,6 +11,7 @@ import {
|
||||
export const haexSettings = sqliteTable('haex_settings', {
|
||||
id: text().primaryKey(),
|
||||
key: text(),
|
||||
type: text(),
|
||||
value: text(),
|
||||
})
|
||||
export type InsertHaexSettings = typeof haexSettings.$inferInsert
|
||||
|
||||
Binary file not shown.
@ -88,7 +88,6 @@ pub fn create_encrypted_database(
|
||||
} else {
|
||||
println!("Datei '{}' existiert nicht.", target.display());
|
||||
}
|
||||
//core::copy_file(&resource_path, &path)?;
|
||||
|
||||
println!(
|
||||
"Öffne unverschlüsselte Datenbank: {}",
|
||||
@ -102,8 +101,6 @@ pub fn create_encrypted_database(
|
||||
)
|
||||
})?;
|
||||
|
||||
//let conn = Connection::open(&resource_path)?;
|
||||
|
||||
println!("Hänge neue, verschlüsselte Datenbank an unter '{}'", &path);
|
||||
// ATTACH DATABASE 'Dateiname' AS Alias KEY 'Passwort';
|
||||
conn.execute("ATTACH DATABASE ?1 AS encrypted KEY ?2;", [&path, &key])
|
||||
@ -124,14 +121,6 @@ pub fn create_encrypted_database(
|
||||
return Err(e.to_string()); // Gib den Fehler zurück
|
||||
}
|
||||
}
|
||||
// sqlcipher_export('Alias') kopiert Schema und Daten von 'main' zur Alias-DB
|
||||
/* conn.execute("SELECT sqlcipher_export('encrypted');", [])
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Fehler bei SELECT sqlcipher_export('encrypted'): {}",
|
||||
e.to_string()
|
||||
)
|
||||
})?; */
|
||||
|
||||
println!("Löse die verschlüsselte Datenbank vom Handle...");
|
||||
conn.execute("DETACH DATABASE encrypted;", [])
|
||||
@ -143,27 +132,6 @@ pub fn create_encrypted_database(
|
||||
resource_path.as_path().display()
|
||||
);
|
||||
|
||||
/* // Neue Datenbank erstellen
|
||||
let conn = Connection::open_with_flags(
|
||||
&path,
|
||||
OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE,
|
||||
)
|
||||
.map_err(|e| format!("Fehler beim Erstellen der Datenbank: {}", e.to_string()))?;
|
||||
|
||||
// Datenbank mit dem angegebenen Passwort verschlüsseln
|
||||
conn.pragma_update(None, "key", &key)
|
||||
.map_err(|e| format!("Fehler beim Verschlüsseln der Datenbank: {}", e.to_string()))?;
|
||||
|
||||
println!("Datenbank verschlüsselt mit key {}", &key);
|
||||
// Überprüfen, ob die Datenbank korrekt verschlüsselt wurde
|
||||
let validation_result: Result<i32, _> = conn.query_row("SELECT 1", [], |row| row.get(0));
|
||||
if let Err(e) = validation_result {
|
||||
return Err(format!(
|
||||
"Fehler beim Testen der verschlüsselten Datenbank: {}",
|
||||
e.to_string()
|
||||
));
|
||||
} */
|
||||
|
||||
// 2. VERSUCHEN, EINE SQLCIPHER-SPEZIFISCHE OPERATION AUSZUFÜHREN
|
||||
println!("Prüfe SQLCipher-Aktivität mit 'PRAGMA cipher_version;'...");
|
||||
match conn.query_row("PRAGMA cipher_version;", [], |row| {
|
||||
@ -172,20 +140,6 @@ pub fn create_encrypted_database(
|
||||
}) {
|
||||
Ok(version) => {
|
||||
println!("SQLCipher ist aktiv! Version: {}", version);
|
||||
|
||||
/* // Fahre mit normalen Operationen fort
|
||||
println!("Erstelle Tabelle 'benutzer'...");
|
||||
conn.execute(
|
||||
"CREATE TABLE benutzer (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
|
||||
[],
|
||||
)
|
||||
.map_err(|e| format!("Fehler beim Verschlüsseln der Datenbank: {}", e.to_string()))?;
|
||||
println!("Füge Benutzer 'Bob' hinzu...");
|
||||
conn.execute("INSERT INTO benutzer (name) VALUES ('Bob')", [])
|
||||
.map_err(|e| {
|
||||
format!("Fehler beim Verschlüsseln der Datenbank: {}", e.to_string())
|
||||
})?;
|
||||
println!("Benutzer hinzugefügt."); */
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("FEHLER: SQLCipher scheint NICHT aktiv zu sein!");
|
||||
@ -236,10 +190,7 @@ pub fn create_encrypted_database(
|
||||
.map_err(|e| format!("Mutex-Fehler: {}", e.to_string()))?;
|
||||
*db = Some(conn);
|
||||
|
||||
Ok(format!(
|
||||
"Verschlüsselte CRDT-Datenbank erstellt unter: {} and password",
|
||||
key
|
||||
))
|
||||
Ok(format!("Verschlüsselte CRDT-Datenbank erstellt",))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@ -249,11 +200,11 @@ pub fn open_encrypted_database(
|
||||
state: State<'_, DbConnection>,
|
||||
) -> Result<String, String> {
|
||||
if !std::path::Path::new(&path).exists() {
|
||||
return Err("Datenbankdatei nicht gefunden".into());
|
||||
return Err("File not found ".into());
|
||||
}
|
||||
|
||||
let conn = core::open_and_init_db(&path, &key, false)
|
||||
.map_err(|e| format!("Fehler beim öffnen: {}", e));
|
||||
let conn =
|
||||
core::open_and_init_db(&path, &key, false).map_err(|e| format!("Error during open: {}", e));
|
||||
let mut db = state.0.lock().map_err(|e| e.to_string())?;
|
||||
*db = Some(conn.unwrap());
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<button
|
||||
id="dropdown-scrollable"
|
||||
type="button"
|
||||
class="dropdown-toggle btn btn-text btn-circle dropdown-open:bg-base-content/10 size-10"
|
||||
class="dropdown-toggle btn btn-text btn-circle dropdown-open:bg-base-content/10"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded="false"
|
||||
aria-label="Dropdown"
|
||||
|
||||
@ -20,13 +20,15 @@
|
||||
class="btn-error btn-outline w-full sm:w-auto"
|
||||
@click="onAbort"
|
||||
>
|
||||
<Icon name="mdi:close" /> {{ abortLabel ?? t('abort') }}
|
||||
<Icon :name="abortIcon || 'mdi:close'" />
|
||||
{{ abortLabel ?? t('abort') }}
|
||||
</UiButton>
|
||||
<UiButton
|
||||
class="btn-primary w-full sm:w-auto"
|
||||
@click="onConfirm"
|
||||
>
|
||||
<Icon name="mdi:check" /> {{ confirmLabel ?? t('confirm') }}
|
||||
<Icon :name="confirmIcon || 'mdi:check'" />
|
||||
{{ confirmLabel ?? t('confirm') }}
|
||||
</UiButton>
|
||||
</slot>
|
||||
</template>
|
||||
@ -34,7 +36,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ confirmLabel?: string; abortLabel?: string; title?: string }>()
|
||||
defineProps<{
|
||||
confirmLabel?: string
|
||||
abortLabel?: string
|
||||
title?: string
|
||||
abortIcon?: string
|
||||
confirmIcon?: string
|
||||
}>()
|
||||
|
||||
const open = defineModel<boolean>('open', { default: false })
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
class="overlay-animation-target overlay-open:duration-300 overlay-open:opacity-100 transition-all ease-out modal-dialog"
|
||||
>
|
||||
<div class="modal-content justify-between">
|
||||
<div class="modal-header">
|
||||
<div class="modal-header py-0 sm:py-4">
|
||||
<div
|
||||
v-if="title || $slots.title"
|
||||
class="modal-title py-4 break-all"
|
||||
@ -49,7 +49,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body text-sm sm:text-base grow">
|
||||
<div class="modal-body text-sm sm:text-base grow mt-0 pt-0">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
|
||||
@ -73,13 +73,13 @@
|
||||
<script setup lang="ts">
|
||||
import type { ZodSchema } from 'zod'
|
||||
|
||||
const input = defineModel<string | number | undefined | null>({
|
||||
required: true,
|
||||
})
|
||||
|
||||
const inputRef = useTemplateRef('inputRef')
|
||||
defineExpose({ inputRef })
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
@ -131,11 +131,6 @@ const props = defineProps({
|
||||
read_only: Boolean,
|
||||
})
|
||||
|
||||
const input = defineModel<string | number | undefined | null>({
|
||||
default: '',
|
||||
required: true,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.autofocus && inputRef.value) inputRef.value.focus()
|
||||
})
|
||||
|
||||
7
src/components/ui/test.vue
Normal file
7
src/components/ui/test.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<input v-model="value" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const value = defineModel()
|
||||
</script>
|
||||
@ -28,12 +28,12 @@
|
||||
</template>
|
||||
|
||||
<UiInputPassword
|
||||
v-model="database.password"
|
||||
:check-input="check"
|
||||
:rules="vaultDatabaseSchema.password"
|
||||
@keyup.enter="onOpenDatabase"
|
||||
autofocus
|
||||
prepend-icon="mdi:key-outline"
|
||||
@keyup.enter="onOpenDatabase"
|
||||
v-model="database.password"
|
||||
/>
|
||||
</UiDialogConfirm>
|
||||
</template>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="h-full w-full flex flex-col overflow-hidden">
|
||||
<div class="h-full flex-1 flex flex-col overflow-auto">
|
||||
<nav
|
||||
class="navbar rounded-b max-sm:shadow border-b border-base-content/25 sm:z-20 relative px-2 py-0 sm:py-2"
|
||||
>
|
||||
@ -35,13 +35,13 @@
|
||||
</NuxtLinkLocale>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4 me-4">
|
||||
<div class="flex items-center gap-x-4">
|
||||
<HaexMenuNotifications />
|
||||
<HaexMenuMain />
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="flex h-full w-full overflow-hidden">
|
||||
<div class="flex h-full w-full overflow-auto">
|
||||
<aside
|
||||
id="sidebar"
|
||||
class="sm:shadow-none transition-all h-full overflow-hidden border-r border-base-300"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="w-screen h-screen bg-base-200 min-w-52">
|
||||
<div class="w-screen h-dvh bg-base-200 min-w-52 overflow-auto">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="items-center justify-center h-full flex w-full relative">
|
||||
<div class="fixed top-2 right-2">
|
||||
<div class="items-center justify-center flex w-full relative min-h-full">
|
||||
<div class="absolute top-2 right-2">
|
||||
<UiDropdownLocale @select="setLocale" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center gap-5 max-w-3xl">
|
||||
<UiLogoHaexhub class="bg-primary p-3 size-16 rounded-full" />
|
||||
<UiLogoHaexhub class="bg-primary p-3 size-16 rounded-full shrink-0" />
|
||||
<span
|
||||
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
||||
>
|
||||
@ -98,12 +98,12 @@ await syncLastVaultsAsync()
|
||||
"de": {
|
||||
"welcome": "Viel Spass mit",
|
||||
"lastUsed": "Zuletzt verwendete Vaults",
|
||||
"sponsors": "Powered by"
|
||||
"sponsors": "Supported by"
|
||||
},
|
||||
"en": {
|
||||
"welcome": "Have fun with",
|
||||
"lastUsed": "Last used Vaults",
|
||||
"sponsors": "Powered by"
|
||||
"sponsors": "Supported by"
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
|
||||
@ -1,15 +1,32 @@
|
||||
<template>
|
||||
<div class="h-full w-full">
|
||||
<div class="h-full">
|
||||
<NuxtLayout name="app">
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
|
||||
<UiDialog v-model:open="showInstanceDialog">
|
||||
<div>
|
||||
Das scheint das erste Mal zu sein, dass du auf diesem Gerät diese Vault
|
||||
öffnest. Bitte gib diesem Gerät einen Namen
|
||||
</div>
|
||||
</UiDialog>
|
||||
<div class="hidden">
|
||||
<UiDialogConfirm
|
||||
:confirm-label="t('newDevice.save')"
|
||||
:title="t('newDevice.title')"
|
||||
@abort="showNewDeviceDialog = false"
|
||||
@confirm="onSetDeviceNameAsync"
|
||||
confirm-icon="mdi:content-save-outline"
|
||||
v-model:open="showNewDeviceDialog"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<p>{{ t('newDevice.intro') }}</p>
|
||||
<p>
|
||||
{{ t('newDevice.setName') }}
|
||||
</p>
|
||||
{{ deviceId }}
|
||||
<UiInput
|
||||
v-model="newDeviceName"
|
||||
:label="t('newDevice.label')"
|
||||
:rules="vaultDeviceNameSchema"
|
||||
/>
|
||||
</div>
|
||||
</UiDialogConfirm>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -18,20 +35,68 @@ definePageMeta({
|
||||
middleware: 'database',
|
||||
})
|
||||
|
||||
const showInstanceDialog = ref(false)
|
||||
const { t } = useI18n()
|
||||
|
||||
const showNewDeviceDialog = ref(false)
|
||||
|
||||
const { hostname } = storeToRefs(useDeviceStore())
|
||||
|
||||
const newDeviceName = ref<string>('unknown')
|
||||
|
||||
const { readNotificationsAsync } = useNotificationStore()
|
||||
const { isFirstTimeAsync } = useVaultInstanceStore()
|
||||
const { isKnownDeviceAsync } = useDeviceStore()
|
||||
const { loadExtensionsAsync } = useExtensionsStore()
|
||||
const { setDeviceIdIfNotExistsAsync, addDeviceNameAsync } = useDeviceStore()
|
||||
const { deviceId } = storeToRefs(useDeviceStore())
|
||||
|
||||
onMounted(async () => {
|
||||
await setDeviceIdIfNotExistsAsync()
|
||||
await loadExtensionsAsync()
|
||||
await readNotificationsAsync()
|
||||
|
||||
if (await isFirstTimeAsync()) {
|
||||
showInstanceDialog.value = true
|
||||
if (!(await isKnownDeviceAsync())) {
|
||||
console.log('not known device')
|
||||
newDeviceName.value = hostname.value ?? 'unknown'
|
||||
showNewDeviceDialog.value = true
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {})
|
||||
const { add } = useSnackbar()
|
||||
const onSetDeviceNameAsync = async () => {
|
||||
try {
|
||||
const check = vaultDeviceNameSchema.safeParse(newDeviceName.value)
|
||||
if (!check.success) {
|
||||
console.log('check failed', check.error)
|
||||
return
|
||||
}
|
||||
|
||||
await addDeviceNameAsync({ name: newDeviceName.value })
|
||||
showNewDeviceDialog.value = false
|
||||
add({ type: 'success', text: t('newDevice.success') })
|
||||
} catch (error) {
|
||||
add({ type: 'error', text: t('newDevice.error') })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
de:
|
||||
newDevice:
|
||||
title: Neues Gerät erkannt
|
||||
save: Speichern
|
||||
label: Name
|
||||
intro: Offenbar öffnest du das erste Mal diese Vault auf diesem Gerät.
|
||||
setName: Bitte gib diesem Gerät einen für dich sprechenden Namen. Dadurch kannst du später besser nachverfolgen, welche Änderungen von welchem Gerät erfolgt sind.
|
||||
success: Name erfolgreich gespeichert
|
||||
error: Name konnt nicht gespeichert werden
|
||||
|
||||
en:
|
||||
newDevice:
|
||||
title: New device recognized
|
||||
save: Save
|
||||
label: Name
|
||||
intro: This is obviously your first time with this Vault on this device.
|
||||
setName: Please give this device a name that is meaningful to you. This will make it easier for you to track which changes have been made by which device.
|
||||
success: Name successfully saved
|
||||
error: Name could not be saved
|
||||
</i18n>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="h-full text-base-content flex bg-base-200 p-4">
|
||||
aaaa
|
||||
<div class="h-full text-base-content flex bg-base-200">
|
||||
<HaexExtensionCard
|
||||
v-for="extension in extensionStore.availableExtensions"
|
||||
v-bind="extension"
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
{{ group }}
|
||||
<HaexPassGroup
|
||||
v-model="group"
|
||||
mode="edit"
|
||||
@ -43,16 +44,15 @@ const onClose = () => {
|
||||
|
||||
const { add } = useSnackbar()
|
||||
|
||||
const { updateAsync } = usePasswordGroupStore()
|
||||
|
||||
const onSaveAsync = async () => {
|
||||
try {
|
||||
check.value = true
|
||||
if (!group.value) return
|
||||
|
||||
console.log('onSave', errors.value)
|
||||
if (errors.value.name.length || errors.value.description.length) return
|
||||
|
||||
const { updateAsync } = usePasswordGroupStore()
|
||||
|
||||
await updateAsync(group.value)
|
||||
|
||||
add({ type: 'success', text: t('change.success') })
|
||||
|
||||
@ -163,14 +163,16 @@ const { currentItem } = storeToRefs(usePasswordItemStore())
|
||||
|
||||
watch(
|
||||
currentItem,
|
||||
(newItem) => {
|
||||
item.details = JSON.parse(JSON.stringify(newItem?.details))
|
||||
item.keyValues = JSON.parse(JSON.stringify(newItem?.keyValues))
|
||||
item.history = JSON.parse(JSON.stringify(newItem?.history))
|
||||
() => {
|
||||
console.log('watch currentItem', currentItem.value)
|
||||
if (!currentItem.value) return
|
||||
item.details = JSON.parse(JSON.stringify(currentItem.value?.details))
|
||||
item.keyValues = JSON.parse(JSON.stringify(currentItem.value?.keyValues))
|
||||
item.history = JSON.parse(JSON.stringify(currentItem.value?.history))
|
||||
item.keyValuesAdd = []
|
||||
item.keyValuesDelete = []
|
||||
item.originalDetails = JSON.stringify(newItem?.details)
|
||||
item.originalKeyValues = JSON.stringify(newItem?.keyValues)
|
||||
item.originalDetails = JSON.stringify(currentItem.value?.details)
|
||||
item.originalKeyValues = JSON.stringify(currentItem.value?.keyValues)
|
||||
ignoreChanges.value = false
|
||||
},
|
||||
{ immediate: true },
|
||||
|
||||
@ -40,9 +40,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { Locale } from 'vue-i18n'
|
||||
import { haexSettings } from '~~/src-tauri/database/schemas/vault'
|
||||
|
||||
definePageMeta({
|
||||
name: 'settings',
|
||||
@ -50,24 +48,19 @@ definePageMeta({
|
||||
|
||||
const { t, setLocale } = useI18n()
|
||||
|
||||
const { currentVault, currentVaultName } = storeToRefs(useVaultStore())
|
||||
const { updateVaultNameAsync } = useVaultSettingsStore()
|
||||
const { currentVaultName } = storeToRefs(useVaultStore())
|
||||
const { updateVaultNameAsync, updateLocaleAsync, updateThemeAsync } =
|
||||
useVaultSettingsStore()
|
||||
|
||||
const onSelectLocaleAsync = async (locale: Locale) => {
|
||||
await currentVault.value?.drizzle
|
||||
.update(haexSettings)
|
||||
.set({ key: 'locale', value: locale })
|
||||
.where(eq(haexSettings.key, 'locale'))
|
||||
await updateLocaleAsync(locale)
|
||||
await setLocale(locale)
|
||||
}
|
||||
|
||||
const { currentTheme } = storeToRefs(useUiStore())
|
||||
|
||||
const onSelectThemeAsync = async (theme: ITheme) => {
|
||||
await currentVault.value?.drizzle
|
||||
.update(haexSettings)
|
||||
.set({ key: 'theme', value: theme.name })
|
||||
.where(eq(haexSettings.key, 'theme'))
|
||||
await updateThemeAsync(theme.value)
|
||||
currentTheme.value = theme
|
||||
}
|
||||
|
||||
@ -82,9 +75,7 @@ const onSetVaultNameAsync = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const { isNotificationAllowed } = storeToRefs(useNotificationStore())
|
||||
const { requestNotificationPermissionAsync } = useNotificationStore()
|
||||
//const { test } = useLastVaultStore()
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
|
||||
@ -21,9 +21,7 @@ export const usePasswordItemStore = defineStore('passwordItemStore', () => {
|
||||
},
|
||||
})
|
||||
|
||||
const currentItem = computedAsync(
|
||||
async () => await readAsync(currentItemId.value),
|
||||
)
|
||||
const currentItem = computedAsync(() => readAsync(currentItemId.value))
|
||||
|
||||
return {
|
||||
currentItemId,
|
||||
@ -179,6 +177,8 @@ const readAsync = async (itemId: string | null) => {
|
||||
where: eq(haexPasswordsItemDetails.id, itemId),
|
||||
})
|
||||
|
||||
console.log('readAsync details', details)
|
||||
|
||||
if (!details) return null
|
||||
|
||||
const history = (await usePasswordHistoryStore().getAsync(itemId)) ?? []
|
||||
|
||||
98
src/stores/vault/device.ts
Normal file
98
src/stores/vault/device.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { load } from '@tauri-apps/plugin-store'
|
||||
import { hostname as tauriHostname } from '@tauri-apps/plugin-os'
|
||||
|
||||
export const useDeviceStore = defineStore('vaultInstanceStore', () => {
|
||||
const deviceId = ref<string>()
|
||||
|
||||
const hostname = computedAsync(() => tauriHostname())
|
||||
|
||||
const deviceName = ref<string>()
|
||||
|
||||
const getDeviceIdAsync = async () => {
|
||||
const store = await getStoreAsync()
|
||||
return store.get<string>('id')
|
||||
}
|
||||
|
||||
const getStoreAsync = async () => {
|
||||
const {
|
||||
public: { haexVault },
|
||||
} = useRuntimeConfig()
|
||||
|
||||
return await load(haexVault.instanceFileName || 'instance.json')
|
||||
}
|
||||
|
||||
const setDeviceIdAsync = async (id?: string) => {
|
||||
const store = await getStoreAsync()
|
||||
const _id = id || crypto.randomUUID()
|
||||
await store.set('id', _id)
|
||||
deviceId.value = _id
|
||||
return _id
|
||||
}
|
||||
|
||||
const setDeviceIdIfNotExistsAsync = async () => {
|
||||
const _deviceId = await getDeviceIdAsync()
|
||||
if (_deviceId) {
|
||||
deviceId.value = _deviceId
|
||||
return deviceId.value
|
||||
}
|
||||
return await setDeviceIdAsync()
|
||||
}
|
||||
|
||||
const isKnownDeviceAsync = async () => {
|
||||
const { readDeviceNameAsync } = useVaultSettingsStore()
|
||||
const deviceId = await getDeviceIdAsync()
|
||||
return deviceId ? (await readDeviceNameAsync(deviceId)) || false : false
|
||||
}
|
||||
|
||||
const readDeviceNameAsync = async (id: string) => {
|
||||
const { readDeviceNameAsync } = useVaultSettingsStore()
|
||||
deviceName.value = (await readDeviceNameAsync(id))?.value ?? ''
|
||||
return deviceName.value
|
||||
}
|
||||
|
||||
const updateDeviceNameAsync = async ({
|
||||
id,
|
||||
name,
|
||||
}: {
|
||||
id?: string
|
||||
name?: string
|
||||
}) => {
|
||||
const { updateDeviceNameAsync } = useVaultSettingsStore()
|
||||
const _id = id ?? deviceId.value
|
||||
if (!_id || !name) return
|
||||
|
||||
deviceName.value = name
|
||||
|
||||
return updateDeviceNameAsync({
|
||||
deviceId: _id,
|
||||
deviceName: name,
|
||||
})
|
||||
}
|
||||
|
||||
const addDeviceNameAsync = async ({
|
||||
id,
|
||||
name,
|
||||
}: {
|
||||
id?: string
|
||||
name: string
|
||||
}) => {
|
||||
const { addDeviceNameAsync } = useVaultSettingsStore()
|
||||
const _id = id ?? deviceId.value
|
||||
if (!_id || !name) throw new Error('Id oder Name fehlen')
|
||||
|
||||
return addDeviceNameAsync({
|
||||
deviceId: _id,
|
||||
deviceName: name,
|
||||
})
|
||||
}
|
||||
return {
|
||||
addDeviceNameAsync,
|
||||
hostname,
|
||||
deviceId,
|
||||
isKnownDeviceAsync,
|
||||
readDeviceNameAsync,
|
||||
setDeviceIdAsync,
|
||||
setDeviceIdIfNotExistsAsync,
|
||||
updateDeviceNameAsync,
|
||||
}
|
||||
})
|
||||
@ -1,47 +0,0 @@
|
||||
import { load } from '@tauri-apps/plugin-store'
|
||||
|
||||
export const useVaultInstanceStore = defineStore('vaultInstanceStore', () => {
|
||||
const instanceId = ref<string>()
|
||||
|
||||
const getInstanceIdAsync = async () => {
|
||||
const store = await getStoreAsync()
|
||||
instanceId.value = await store.get<string>('id')
|
||||
|
||||
return instanceId.value
|
||||
}
|
||||
|
||||
const getStoreAsync = async () => {
|
||||
const {
|
||||
public: { haexVault },
|
||||
} = useRuntimeConfig()
|
||||
|
||||
return await load(haexVault.instanceFileName || 'instance.json')
|
||||
}
|
||||
|
||||
const setInstanceIdAsync = async (id?: string) => {
|
||||
const store = await getStoreAsync()
|
||||
const _id = id || crypto.randomUUID()
|
||||
await store.set('id', _id)
|
||||
|
||||
return _id
|
||||
}
|
||||
|
||||
const setInstanceIdIfNotExistsAsync = async () => {
|
||||
const id = await getInstanceIdAsync()
|
||||
return id ?? (await setInstanceIdAsync())
|
||||
}
|
||||
|
||||
const isFirstTimeAsync = async () => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
currentVault.drizzle.select
|
||||
return !(await getInstanceIdAsync())
|
||||
}
|
||||
|
||||
return {
|
||||
instanceId,
|
||||
isFirstTimeAsync,
|
||||
setInstanceIdAsync,
|
||||
setInstanceIdIfNotExistsAsync,
|
||||
}
|
||||
})
|
||||
@ -1,5 +1,20 @@
|
||||
import { and, eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import * as schema from '@/../src-tauri/database/schemas/vault'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { Locale } from 'vue-i18n'
|
||||
|
||||
export enum VaultSettingsTypeEnum {
|
||||
deviceName = 'deviceName',
|
||||
settings = 'settings',
|
||||
}
|
||||
|
||||
export enum VaultSettingsKeyEnum {
|
||||
locale = 'locale',
|
||||
theme = 'theme',
|
||||
vaultName = 'vaultName',
|
||||
}
|
||||
|
||||
export const vaultDeviceNameSchema = z.string().min(3).max(255)
|
||||
|
||||
export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
|
||||
const { currentVault, currentVaultName } = storeToRefs(useVaultStore())
|
||||
@ -12,20 +27,21 @@ export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
|
||||
try {
|
||||
const app = useNuxtApp()
|
||||
|
||||
const currentLocaleRow = await currentVault.value?.drizzle
|
||||
.select()
|
||||
.from(schema.haexSettings)
|
||||
.where(eq(schema.haexSettings.key, 'locale'))
|
||||
const currentLocaleRow =
|
||||
await currentVault.value?.drizzle.query.haexSettings.findFirst({
|
||||
where: eq(schema.haexSettings.key, VaultSettingsKeyEnum.locale),
|
||||
})
|
||||
|
||||
if (currentLocaleRow?.[0]?.value) {
|
||||
if (currentLocaleRow?.value) {
|
||||
const currentLocale = app.$i18n.availableLocales.find(
|
||||
(locale) => locale === currentLocaleRow[0].value,
|
||||
(locale) => locale === currentLocaleRow.value,
|
||||
)
|
||||
await app.$i18n.setLocale(currentLocale ?? app.$i18n.defaultLocale)
|
||||
} else {
|
||||
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
|
||||
id: crypto.randomUUID(),
|
||||
key: 'locale',
|
||||
key: VaultSettingsKeyEnum.locale,
|
||||
type: VaultSettingsTypeEnum.settings,
|
||||
value: app.$i18n.locale.value,
|
||||
})
|
||||
}
|
||||
@ -34,44 +50,62 @@ export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const updateLocaleAsync = async (locale: Locale) => {
|
||||
await currentVault.value?.drizzle
|
||||
.update(schema.haexSettings)
|
||||
.set({ key: VaultSettingsKeyEnum.locale, value: locale })
|
||||
.where(
|
||||
and(
|
||||
eq(schema.haexSettings.key, VaultSettingsKeyEnum.locale),
|
||||
eq(schema.haexSettings.type, VaultSettingsTypeEnum.settings),
|
||||
),
|
||||
)
|
||||
}
|
||||
const syncThemeAsync = async () => {
|
||||
const { availableThemes, defaultTheme, currentTheme } = storeToRefs(
|
||||
useUiStore(),
|
||||
)
|
||||
const currentThemeRow = await currentVault.value?.drizzle
|
||||
.select()
|
||||
.from(schema.haexSettings)
|
||||
.where(eq(schema.haexSettings.key, 'theme'))
|
||||
const currentThemeRow =
|
||||
await currentVault.value?.drizzle.query.haexSettings.findFirst({
|
||||
where: eq(schema.haexSettings.key, VaultSettingsKeyEnum.theme),
|
||||
})
|
||||
|
||||
if (currentThemeRow?.[0]?.value) {
|
||||
if (currentThemeRow?.value) {
|
||||
const theme = availableThemes.value.find(
|
||||
(theme) => theme.name === currentThemeRow[0].value,
|
||||
(theme) => theme.value === currentThemeRow.value,
|
||||
)
|
||||
currentTheme.value = theme ?? defaultTheme.value
|
||||
} else {
|
||||
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
|
||||
id: crypto.randomUUID(),
|
||||
key: 'theme',
|
||||
key: VaultSettingsKeyEnum.theme,
|
||||
type: VaultSettingsTypeEnum.settings,
|
||||
value: currentTheme.value.value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const syncVaultNameAsync = async () => {
|
||||
const currentVaultNameRow = await currentVault.value?.drizzle
|
||||
.select()
|
||||
.from(schema.haexSettings)
|
||||
.where(eq(schema.haexSettings.key, 'vaultName'))
|
||||
const updateThemeAsync = async (theme: string) => {
|
||||
return await currentVault.value?.drizzle
|
||||
.update(schema.haexSettings)
|
||||
.set({ key: VaultSettingsKeyEnum.theme, value: theme })
|
||||
.where(eq(schema.haexSettings.key, VaultSettingsKeyEnum.theme))
|
||||
}
|
||||
|
||||
if (currentVaultNameRow?.[0]?.value) {
|
||||
const syncVaultNameAsync = async () => {
|
||||
const currentVaultNameRow =
|
||||
await currentVault.value?.drizzle.query.haexSettings.findFirst({
|
||||
where: eq(schema.haexSettings.key, VaultSettingsKeyEnum.vaultName),
|
||||
})
|
||||
|
||||
if (currentVaultNameRow?.value) {
|
||||
currentVaultName.value =
|
||||
currentVaultNameRow.at(0)?.value ||
|
||||
haexVault.defaultVaultName ||
|
||||
'HaexHub'
|
||||
currentVaultNameRow.value || haexVault.defaultVaultName || 'HaexHub'
|
||||
} else {
|
||||
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
|
||||
id: crypto.randomUUID(),
|
||||
key: 'vaultName',
|
||||
key: VaultSettingsKeyEnum.vaultName,
|
||||
type: VaultSettingsTypeEnum.settings,
|
||||
value: currentVaultName.value,
|
||||
})
|
||||
}
|
||||
@ -84,10 +118,76 @@ export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
|
||||
.where(eq(schema.haexSettings.key, 'vaultName'))
|
||||
}
|
||||
|
||||
const readDeviceNameAsync = async (id: string) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const deviceName = await currentVault.drizzle.query.haexSettings.findFirst({
|
||||
where: and(
|
||||
eq(schema.haexSettings.type, VaultSettingsTypeEnum.deviceName),
|
||||
eq(schema.haexSettings.key, id),
|
||||
),
|
||||
})
|
||||
console.log('readDeviceNameAsync', deviceName)
|
||||
return deviceName
|
||||
}
|
||||
|
||||
const addDeviceNameAsync = async ({
|
||||
deviceId,
|
||||
deviceName,
|
||||
}: {
|
||||
deviceId: string
|
||||
deviceName: string
|
||||
}) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const isNameOk = vaultDeviceNameSchema.safeParse(deviceName)
|
||||
if (!isNameOk.success) {
|
||||
console.log('deviceName not OK', isNameOk.error)
|
||||
return
|
||||
}
|
||||
|
||||
return currentVault.drizzle.insert(schema.haexSettings).values({
|
||||
id: crypto.randomUUID(),
|
||||
type: VaultSettingsTypeEnum.deviceName,
|
||||
key: deviceId,
|
||||
value: deviceName,
|
||||
})
|
||||
}
|
||||
|
||||
const updateDeviceNameAsync = async ({
|
||||
deviceId,
|
||||
deviceName,
|
||||
}: {
|
||||
deviceId: string
|
||||
deviceName: string
|
||||
}) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const isNameOk = vaultDeviceNameSchema.safeParse(deviceName)
|
||||
if (!isNameOk.success) return
|
||||
|
||||
return currentVault.drizzle
|
||||
.update(schema.haexSettings)
|
||||
.set({
|
||||
value: deviceName,
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(schema.haexSettings.key, deviceId),
|
||||
eq(schema.haexSettings.type, VaultSettingsTypeEnum.deviceName),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
addDeviceNameAsync,
|
||||
readDeviceNameAsync,
|
||||
syncLocaleAsync,
|
||||
syncThemeAsync,
|
||||
syncVaultNameAsync,
|
||||
updateDeviceNameAsync,
|
||||
updateLocaleAsync,
|
||||
updateThemeAsync,
|
||||
updateVaultNameAsync,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user