mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 14:10:52 +01:00
encryption of sqlite working
This commit is contained in:
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.nuxt
|
||||
.output
|
||||
10
.prettierrc.toml
Normal file
10
.prettierrc.toml
Normal file
@ -0,0 +1,10 @@
|
||||
# .prettierrc.toml
|
||||
|
||||
useTabs = false
|
||||
tabWidth = 2
|
||||
printWidth = 100
|
||||
endOfLine = "lf"
|
||||
|
||||
# Not supported yet
|
||||
# trailingComma = "es5"
|
||||
# embeddedLanguageFormatting = "auto"
|
||||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"Vue.volar",
|
||||
"tauri-apps.tauri-vscode",
|
||||
"rust-lang.rust-analyzer"
|
||||
]
|
||||
}
|
||||
@ -1,71 +1,71 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: '2024-11-01',
|
||||
compatibilityDate: "2024-11-01",
|
||||
|
||||
modules: [
|
||||
'nuxt-zod-i18n',
|
||||
'@nuxtjs/i18n',
|
||||
'@nuxtjs/tailwindcss',
|
||||
'@pinia/nuxt',
|
||||
'@vueuse/nuxt',
|
||||
'@nuxt/icon',
|
||||
'nuxt-snackbar',
|
||||
"nuxt-zod-i18n",
|
||||
"@nuxtjs/i18n",
|
||||
"@nuxtjs/tailwindcss",
|
||||
"@pinia/nuxt",
|
||||
"@vueuse/nuxt",
|
||||
"@nuxt/icon",
|
||||
"nuxt-snackbar",
|
||||
],
|
||||
|
||||
imports: {
|
||||
dirs: ['composables/**', 'stores/**', 'components/**', 'pages/**'],
|
||||
dirs: ["composables/**", "stores/**", "components/**", "pages/**"],
|
||||
},
|
||||
|
||||
i18n: {
|
||||
strategy: 'prefix_and_default',
|
||||
defaultLocale: 'de',
|
||||
vueI18n: '../src/i18n/i18n.config.ts',
|
||||
strategy: "prefix_and_default",
|
||||
defaultLocale: "de",
|
||||
vueI18n: "../src/i18n/i18n.config.ts",
|
||||
|
||||
locales: [
|
||||
{ code: 'de', language: 'de-DE', isCatchallLocale: true },
|
||||
{ code: 'en', language: 'en-EN' },
|
||||
{ code: "de", language: "de-DE", isCatchallLocale: true },
|
||||
{ code: "en", language: "en-EN" },
|
||||
],
|
||||
|
||||
detectBrowserLanguage: {
|
||||
useCookie: true,
|
||||
cookieKey: 'i18n_redirected',
|
||||
redirectOn: 'root', // recommended
|
||||
cookieKey: "i18n_redirected",
|
||||
redirectOn: "root", // recommended
|
||||
},
|
||||
types: 'composition',
|
||||
types: "composition",
|
||||
bundle: {
|
||||
optimizeTranslationDirective: false,
|
||||
},
|
||||
},
|
||||
|
||||
/* zodI18n: {
|
||||
zodI18n: {
|
||||
localeCodesMapping: {
|
||||
'en-GB': 'en',
|
||||
'de-DE': 'de',
|
||||
"en-GB": "en",
|
||||
"de-DE": "de",
|
||||
},
|
||||
}, */
|
||||
},
|
||||
|
||||
runtimeConfig: {
|
||||
public: {
|
||||
haexVault: {
|
||||
lastVaultFileName: 'lastVaults.json',
|
||||
lastVaultFileName: "lastVaults.json",
|
||||
//defaultDatabase: 'src/database/default.db',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
devtools: { enabled: true },
|
||||
srcDir: './src',
|
||||
srcDir: "./src",
|
||||
// Enable SSG
|
||||
ssr: false,
|
||||
// Enables the development server to be discoverable by other devices when running on iOS physical devices
|
||||
devServer: { host: process.env.TAURI_DEV_HOST || 'localhost' },
|
||||
devServer: { host: process.env.TAURI_DEV_HOST || "localhost", port: 3003 },
|
||||
vite: {
|
||||
// Better support for Tauri CLI output
|
||||
clearScreen: false,
|
||||
// Enable environment variables
|
||||
// Additional environment variables can be found at
|
||||
// https://v2.tauri.app/reference/environment-variables/
|
||||
envPrefix: ['VITE_', 'TAURI_'],
|
||||
envPrefix: ["VITE_", "TAURI_"],
|
||||
server: {
|
||||
// Tauri requires a consistent port
|
||||
strictPort: true,
|
||||
|
||||
32
package.json
32
package.json
@ -14,41 +14,41 @@
|
||||
"drizzle:migrate": "drizzle-kit migrate"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libsql/client": "^0.15.1",
|
||||
"@libsql/client": "^0.15.4",
|
||||
"@nuxt/icon": "1.11.0",
|
||||
"@nuxtjs/i18n": "^9.4.0",
|
||||
"@nuxtjs/i18n": "^9.5.3",
|
||||
"@pinia/nuxt": "^0.10.1",
|
||||
"@tauri-apps/api": "^2.4.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.0",
|
||||
"@tauri-apps/plugin-fs": "^2.2.0",
|
||||
"@tauri-apps/plugin-http": "~2.4.2",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.1",
|
||||
"@tauri-apps/plugin-fs": "^2.2.1",
|
||||
"@tauri-apps/plugin-http": "~2.4.3",
|
||||
"@tauri-apps/plugin-opener": "^2.2.6",
|
||||
"@tauri-apps/plugin-os": "^2.2.1",
|
||||
"@tauri-apps/plugin-sql": "~2.2.0",
|
||||
"@tauri-apps/plugin-store": "^2.2.0",
|
||||
"@vueuse/core": "^13.0.0",
|
||||
"@vueuse/nuxt": "^13.0.0",
|
||||
"@vueuse/core": "^13.1.0",
|
||||
"@vueuse/nuxt": "^13.1.0",
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"nuxt": "^3.16.1",
|
||||
"nuxt": "^3.17.0",
|
||||
"nuxt-snackbar": "1.3.0",
|
||||
"nuxt-zod-i18n": "^1.11.5",
|
||||
"vue": "^3.5.13",
|
||||
"zod": "^3.24.2"
|
||||
"zod": "^3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@egoist/tailwindcss-icons": "^1.9.0",
|
||||
"@iconify/json": "^2.2.321",
|
||||
"@iconify/json": "^2.2.332",
|
||||
"@iconify/tailwind": "^1.2.0",
|
||||
"@nuxtjs/tailwindcss": "^6.13.2",
|
||||
"@tauri-apps/cli": "^2.4.0",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@tauri-apps/cli": "^2.5.0",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"drizzle-kit": "^0.30.6",
|
||||
"flyonui": "^1.3.1",
|
||||
"typescript": "~5.6.3",
|
||||
"vite": "^6.2.3",
|
||||
"vue-tsc": "^2.2.8"
|
||||
"vite": "^6.3.3",
|
||||
"vue-tsc": "^2.2.10"
|
||||
},
|
||||
"packageManager": "pnpm@10.5.2+sha512.da9dc28cd3ff40d0592188235ab25d3202add8a207afbedc682220e4a0029ffbff4562102b9e6e46b4e3f9e8bd53e6d05de48544b0c57d4b0179e22c76d1199b",
|
||||
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
|
||||
"pnpm": {
|
||||
"ignoredBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
3798
pnpm-lock.yaml
generated
3798
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
168
src-tauri/Cargo.lock
generated
168
src-tauri/Cargo.lock
generated
@ -2107,9 +2107,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.32.0"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7"
|
||||
checksum = "947e6816f7825b2b45027c2c32e7085da9934defa535de4a6a46b10a4d5257fa"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
@ -3340,9 +3340,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.34.0"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143"
|
||||
checksum = "a22715a5d6deef63c637207afbe68d0c72c3f8d0022d7cf9714c442d6157606b"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"fallible-iterator",
|
||||
@ -3960,9 +3960,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tao"
|
||||
version = "0.32.8"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63c8b1020610b9138dd7b1e06cf259ae91aa05c30f3bd0d6b42a03997b92dec1"
|
||||
checksum = "1e59c1f38e657351a2e822eadf40d6a2ad4627b9c25557bc1180ec1b3295ef82"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"core-foundation 0.10.0",
|
||||
@ -3991,8 +3991,8 @@ dependencies = [
|
||||
"tao-macros",
|
||||
"unicode-segmentation",
|
||||
"url",
|
||||
"windows",
|
||||
"windows-core 0.60.1",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
"windows-version",
|
||||
"x11-dl",
|
||||
]
|
||||
@ -4016,9 +4016,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "2.4.0"
|
||||
version = "2.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "511dd38065a5d3b36c33cdba4362b99a40a5103bebcd4aebb930717e7c8ba292"
|
||||
checksum = "e7b0bc1aec81bda6bc455ea98fcaed26b3c98c1648c627ad6ff1c704e8bf8cbc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -4039,6 +4039,7 @@ dependencies = [
|
||||
"objc2 0.6.0",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation 0.3.0",
|
||||
"objc2-ui-kit",
|
||||
"percent-encoding",
|
||||
"plist",
|
||||
"raw-window-handle",
|
||||
@ -4061,14 +4062,14 @@ dependencies = [
|
||||
"webkit2gtk",
|
||||
"webview2-com",
|
||||
"window-vibrancy",
|
||||
"windows",
|
||||
"windows 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffa8732a66f90903f5a585215f3cf1e87988d0359bc88c18a502efe7572c1de"
|
||||
checksum = "d7a0350f0df1db385ca5c02888a83e0e66655c245b7443db8b78a70da7d7f8fc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_toml",
|
||||
@ -4088,9 +4089,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-codegen"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c266a247f14d63f40c6282c2653a8bac5cc3d482ca562a003a88513653ea817a"
|
||||
checksum = "f93f035551bf7b11b3f51ad9bc231ebbe5e085565527991c16cf326aa38cdf47"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"brotli",
|
||||
@ -4115,9 +4116,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-macros"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f47a1cf94b3bd6c4dc37dce1a43fc96120ff29a91757f0ab3cf713c7ad846e7c"
|
||||
checksum = "8db4df25e2d9d45de0c4c910da61cd5500190da14ae4830749fee3466dddd112"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
@ -4225,7 +4226,7 @@ dependencies = [
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.12",
|
||||
"url",
|
||||
"windows",
|
||||
"windows 0.60.0",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
@ -4265,29 +4266,31 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e9c7bce5153f1ca7bc45eba37349b31ba50e975e28edc8b5766c5ec02b0b63a"
|
||||
checksum = "00f004905d549854069e6774533d742b03cacfd6f03deb08940a8677586cbe39"
|
||||
dependencies = [
|
||||
"cookie",
|
||||
"dpi",
|
||||
"gtk",
|
||||
"http",
|
||||
"jni",
|
||||
"objc2 0.6.0",
|
||||
"objc2-ui-kit",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri-utils",
|
||||
"thiserror 2.0.12",
|
||||
"url",
|
||||
"windows",
|
||||
"windows 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "087188020fd6facb8578fe9b38e81fa0fe5fb85744c73da51a299f94a530a1e3"
|
||||
checksum = "f85d056f4d4b014fe874814034f3416d57114b617a493a4fe552580851a3f3a2"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http",
|
||||
@ -4306,15 +4309,15 @@ dependencies = [
|
||||
"url",
|
||||
"webkit2gtk",
|
||||
"webview2-com",
|
||||
"windows",
|
||||
"windows 0.61.1",
|
||||
"wry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-utils"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82dcced4014e59af9790cc22f5d271df3be09ecd6728ec68861642553c8d01b7"
|
||||
checksum = "b2900399c239a471bcff7f15c4399eb1a8c4fe511ba2853e07c996d771a5e0a4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"brotli",
|
||||
@ -5049,15 +5052,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webview2-com"
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0d606f600e5272b514dbb66539dd068211cc20155be8d3958201b4b5bd79ed3"
|
||||
checksum = "b542b5cfbd9618c46c2784e4d41ba218c336ac70d44c55e47b251033e7d85601"
|
||||
dependencies = [
|
||||
"webview2-com-macros",
|
||||
"webview2-com-sys",
|
||||
"windows",
|
||||
"windows-core 0.60.1",
|
||||
"windows-implement",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
"windows-implement 0.60.0",
|
||||
"windows-interface",
|
||||
]
|
||||
|
||||
@ -5074,13 +5077,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webview2-com-sys"
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfb27fccd3c27f68e9a6af1bcf48c2d82534b8675b83608a4d81446d095a17ac"
|
||||
checksum = "8ae2d11c4a686e4409659d7891791254cf9286d3cfe0eef54df1523533d22295"
|
||||
dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
"windows",
|
||||
"windows-core 0.60.1",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5135,11 +5138,24 @@ version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-collections 0.1.1",
|
||||
"windows-core 0.60.1",
|
||||
"windows-future",
|
||||
"windows-future 0.1.1",
|
||||
"windows-link",
|
||||
"windows-numerics",
|
||||
"windows-numerics 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
|
||||
dependencies = [
|
||||
"windows-collections 0.2.0",
|
||||
"windows-core 0.61.0",
|
||||
"windows-future 0.2.0",
|
||||
"windows-link",
|
||||
"windows-numerics 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5151,6 +5167,15 @@ dependencies = [
|
||||
"windows-core 0.60.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
@ -5166,11 +5191,24 @@ version = "0.60.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-implement 0.59.0",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
"windows-strings 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
|
||||
dependencies = [
|
||||
"windows-implement 0.60.0",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings 0.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5183,6 +5221,16 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
|
||||
dependencies = [
|
||||
"windows-core 0.61.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.59.0"
|
||||
@ -5194,6 +5242,17 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
@ -5221,6 +5280,16 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core 0.61.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.4.0"
|
||||
@ -5228,7 +5297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
"windows-strings 0.3.1",
|
||||
"windows-targets 0.53.0",
|
||||
]
|
||||
|
||||
@ -5250,6 +5319,15 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
@ -5588,9 +5666,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.50.5"
|
||||
version = "0.51.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b19b78efae8b853c6c817e8752fc1dbf9cab8a8ffe9c30f399bd750ccf0f0730"
|
||||
checksum = "c886a0a9d2a94fd90cfa1d929629b79cfefb1546e2c7430c63a47f0664c0e4e2"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"block2 0.6.0",
|
||||
@ -5624,8 +5702,8 @@ dependencies = [
|
||||
"webkit2gtk",
|
||||
"webkit2gtk-sys",
|
||||
"webview2-com",
|
||||
"windows",
|
||||
"windows-core 0.60.1",
|
||||
"windows 0.61.1",
|
||||
"windows-core 0.61.0",
|
||||
"windows-version",
|
||||
"x11-dl",
|
||||
]
|
||||
|
||||
@ -15,23 +15,24 @@ name = "haex_hub_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
tauri-build = { version = "2.2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
rusqlite = { version = "0.34.0", features = [
|
||||
"load_extension",
|
||||
"bundled-sqlcipher",
|
||||
rusqlite = { version = "0.35.0", features = [
|
||||
"load_extension",
|
||||
"bundled-sqlcipher",
|
||||
] }
|
||||
#libsqlite3-sys = { version = "0.32", features = ["bundled-sqlcipher"] }
|
||||
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
|
||||
#libsqlite3-sys = { version = "0.28.0", features = ["bundled-sqlcipher"] }
|
||||
#libsqlite3-sys = { version = "0.28", features = ["bundled-sqlcipher"] }
|
||||
#sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite"] }
|
||||
tokio = { version = "1.44", features = ["macros", "rt-multi-thread"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
sqlparser = { version = "0.55.0", features = [] }
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-dialog = "2"
|
||||
tauri-plugin-fs = "2"
|
||||
tauri-plugin-opener = "2"
|
||||
tauri = { version = "2.5", features = [] }
|
||||
tauri-plugin-dialog = "2.2"
|
||||
tauri-plugin-fs = "2.2.0"
|
||||
tauri-plugin-opener = "2.2"
|
||||
tauri-plugin-os = "2"
|
||||
tauri-plugin-store = "2"
|
||||
tauri-plugin-http = "2"
|
||||
tauri-plugin-http = "2.4"
|
||||
#tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"dialog:default",
|
||||
"fs:allow-read-file",
|
||||
"fs:allow-resource-read-recursive",
|
||||
"fs:default",
|
||||
"http:allow-fetch-send",
|
||||
"http:allow-fetch",
|
||||
"http:default",
|
||||
"opener:allow-open-url",
|
||||
"opener:default",
|
||||
"os:default",
|
||||
"store:default",
|
||||
"core:window:allow-create",
|
||||
"core:window:default",
|
||||
"core:window:allow-get-all-windows",
|
||||
"core:window:allow-show",
|
||||
"core:webview:allow-create-webview",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"core:webview:default",
|
||||
"core:webview:allow-webview-show"
|
||||
]
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"dialog:default",
|
||||
"fs:allow-read-file",
|
||||
"fs:allow-resource-read-recursive",
|
||||
"fs:default",
|
||||
"http:allow-fetch-send",
|
||||
"http:allow-fetch",
|
||||
"http:default",
|
||||
"opener:allow-open-url",
|
||||
"opener:default",
|
||||
"os:default",
|
||||
"store:default",
|
||||
"core:window:allow-create",
|
||||
"core:window:default",
|
||||
"core:window:allow-get-all-windows",
|
||||
"core:window:allow-show",
|
||||
"core:webview:allow-create-webview",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"core:webview:default",
|
||||
"core:webview:allow-webview-show"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,44 +1,51 @@
|
||||
import {
|
||||
integer,
|
||||
sqliteTable,
|
||||
text,
|
||||
type AnySQLiteColumn,
|
||||
unique,
|
||||
numeric,
|
||||
} from 'drizzle-orm/sqlite-core';
|
||||
integer,
|
||||
sqliteTable,
|
||||
text,
|
||||
type AnySQLiteColumn,
|
||||
unique,
|
||||
numeric,
|
||||
} from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const haexSettings = sqliteTable('haex_settings', {
|
||||
id: text().primaryKey(),
|
||||
key: text(),
|
||||
value_text: text(),
|
||||
value_json: text({ mode: 'json' }),
|
||||
value_number: numeric(),
|
||||
export function generateCreateStatements() {
|
||||
const tables = [haexSettings, haexExtensions, testTable, haexExtensionsPermissions];
|
||||
}
|
||||
|
||||
export const haexSettings = sqliteTable("haex_settings", {
|
||||
id: text().primaryKey(),
|
||||
key: text(),
|
||||
value_text: text(),
|
||||
value_json: text({ mode: "json" }),
|
||||
value_number: numeric(),
|
||||
});
|
||||
|
||||
export const haexExtensions = sqliteTable('haex_extensions', {
|
||||
id: text().primaryKey(),
|
||||
author: text(),
|
||||
enabled: integer(),
|
||||
name: text(),
|
||||
url: text(),
|
||||
version: text(),
|
||||
export const haexExtensions = sqliteTable("haex_extensions", {
|
||||
id: text().primaryKey(),
|
||||
author: text(),
|
||||
enabled: integer(),
|
||||
name: text(),
|
||||
url: text(),
|
||||
version: text(),
|
||||
});
|
||||
|
||||
export const testTable = sqliteTable("testTable", {
|
||||
id: text().primaryKey(),
|
||||
author: text(),
|
||||
test: text(),
|
||||
});
|
||||
|
||||
export const haexExtensionsPermissions = sqliteTable(
|
||||
'haex_extensions_permissions',
|
||||
{
|
||||
id: text().primaryKey(),
|
||||
extensionId: text('extension_id').references(
|
||||
(): AnySQLiteColumn => haexExtensions.id
|
||||
),
|
||||
resource: text({ enum: ['fs', 'http', 'database'] }),
|
||||
operation: text({ enum: ['read', 'write', 'create'] }),
|
||||
path: text(),
|
||||
},
|
||||
(table) => [
|
||||
unique().on(table.extensionId, table.resource, table.operation, table.path),
|
||||
]
|
||||
"haex_extensions_permissions",
|
||||
{
|
||||
id: text().primaryKey(),
|
||||
extensionId: text("extension_id").references((): AnySQLiteColumn => haexExtensions.id),
|
||||
resource: text({ enum: ["fs", "http", "database"] }),
|
||||
operation: text({ enum: ["read", "write", "create"] }),
|
||||
path: text(),
|
||||
},
|
||||
(table) => [unique().on(table.extensionId, table.resource, table.operation, table.path)]
|
||||
);
|
||||
console.log("table", haexExtensionsPermissions.getSQL());
|
||||
|
||||
export type InsertHaexSettings = typeof haexSettings.$inferInsert;
|
||||
export type SelectHaexSettings = typeof haexSettings.$inferSelect;
|
||||
@ -46,7 +53,5 @@ export type SelectHaexSettings = typeof haexSettings.$inferSelect;
|
||||
export type InsertHaexExtensions = typeof haexExtensions.$inferInsert;
|
||||
export type SelectHaexExtensions = typeof haexExtensions.$inferSelect;
|
||||
|
||||
export type InsertHaexExtensionsPermissions =
|
||||
typeof haexExtensionsPermissions.$inferInsert;
|
||||
export type SelectHaexExtensionsPermissions =
|
||||
typeof haexExtensionsPermissions.$inferSelect;
|
||||
export type InsertHaexExtensionsPermissions = typeof haexExtensionsPermissions.$inferInsert;
|
||||
export type SelectHaexExtensionsPermissions = typeof haexExtensionsPermissions.$inferSelect;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// database/mod.rs
|
||||
pub mod core;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use rusqlite::{Connection, OpenFlags};
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
use tauri::{path::BaseDirectory, AppHandle, Manager, State};
|
||||
@ -58,7 +58,60 @@ pub fn create_encrypted_database(
|
||||
}
|
||||
}
|
||||
|
||||
// Kopieren der Ressourcen-Datenbank zum Zielpfad
|
||||
// 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| {
|
||||
let version: String = row.get(0)?;
|
||||
Ok(version)
|
||||
}) {
|
||||
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!");
|
||||
eprintln!("Der Befehl 'PRAGMA cipher_version;' schlug fehl: {}", e);
|
||||
eprintln!("Die Datenbank wurde wahrscheinlich NICHT verschlüsselt.");
|
||||
// Optional: Hier die Verbindung schließen oder weitere Aktionen unterlassen
|
||||
// return Err(e); // Beende das Programm mit dem Fehler
|
||||
}
|
||||
}
|
||||
|
||||
/* // Kopieren der Ressourcen-Datenbank zum Zielpfad
|
||||
core::copy_file(&resource_path, &path)?;
|
||||
|
||||
// Öffnen der kopierten Datenbank ohne Verschlüsselung
|
||||
@ -90,16 +143,17 @@ pub fn create_encrypted_database(
|
||||
e.to_string()
|
||||
));
|
||||
}
|
||||
*/
|
||||
// Aktualisieren der Datenbankverbindung im State
|
||||
let mut db = state
|
||||
.0
|
||||
.lock()
|
||||
.map_err(|e| format!("Mutex-Fehler: {}", e.to_string()))?;
|
||||
*db = Some(encrypted_conn);
|
||||
*db = Some(conn);
|
||||
|
||||
Ok(format!(
|
||||
"Verschlüsselte CRDT-Datenbank erstellt unter: {} (kopiert aus Ressource)",
|
||||
path
|
||||
"Verschlüsselte CRDT-Datenbank erstellt unter: {} and password",
|
||||
key
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
mod permissions;
|
||||
use crate::database;
|
||||
use crate::database::DbConnection;
|
||||
//use crate::models::ExtensionState;
|
||||
use crate::models::ExtensionState;
|
||||
use tauri::{AppHandle, State};
|
||||
|
||||
// Extension-bezogene Funktionen mit extension_-Präfix
|
||||
@ -17,8 +17,8 @@ pub fn extension_load(
|
||||
app.state::<ExtensionState>()
|
||||
.add_extension(manifest_path.clone(), manifest.clone());
|
||||
Ok(manifest)
|
||||
} */
|
||||
|
||||
}
|
||||
*/
|
||||
/// Führt SQL-Leseoperationen mit Berechtigungsprüfung aus
|
||||
#[tauri::command]
|
||||
pub async fn extension_sql_select(
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
mod browser;
|
||||
//mod browser;
|
||||
mod database;
|
||||
mod extension;
|
||||
mod models;
|
||||
|
||||
use database::DbConnection;
|
||||
//use models::ExtensionState;
|
||||
use models::ExtensionState;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
@ -12,12 +12,13 @@ pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.manage(DbConnection(Mutex::new(None)))
|
||||
//.manage(ExtensionState::default())
|
||||
.manage(ExtensionState::default())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
//.plugin(tauri_plugin_sql::Builder::new().build())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
database::create_encrypted_database,
|
||||
database::open_encrypted_database,
|
||||
@ -25,7 +26,7 @@ pub fn run() {
|
||||
database::sql_select,
|
||||
extension::database::extension_sql_execute,
|
||||
extension::database::extension_sql_select,
|
||||
browser::create_tab
|
||||
//browser::create_tab
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// models.rs
|
||||
use serde::{Deserialize, Serialize};
|
||||
//use std::sync::Mutex;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ExtensionManifest {
|
||||
@ -23,7 +23,7 @@ pub struct DatabasePermissions {
|
||||
pub create: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/* #[derive(Default)]
|
||||
#[derive(Default)]
|
||||
pub struct ExtensionState {
|
||||
pub extensions: Mutex<std::collections::HashMap<String, ExtensionManifest>>,
|
||||
}
|
||||
@ -38,7 +38,7 @@ impl ExtensionState {
|
||||
let extensions = self.extensions.lock().unwrap();
|
||||
extensions.values().find(|p| p.name == addon_id).cloned()
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DbExtensionPermission {
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"identifier": "space.haex.hub",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
"devUrl": "http://localhost:3001",
|
||||
"devUrl": "http://localhost:3003",
|
||||
"beforeBuildCommand": "pnpm generate",
|
||||
"frontendDist": "../dist"
|
||||
},
|
||||
|
||||
@ -3,45 +3,22 @@
|
||||
class="flex shrink-0 transition-[width] ease-in duration-300 z-30 h-full overflow-hidden fixed sm:relative left-0 shadow border-r border-base-300"
|
||||
>
|
||||
<div class="sm:flex flex-col w-14 bg-base-200 shrink-0 h-full hidden">
|
||||
<img
|
||||
src="/logo.svg"
|
||||
class="bg-primary p-3 size-16"
|
||||
/>
|
||||
<img src="/logo.svg" class="bg-primary p-3 size-16" />
|
||||
|
||||
<div class="flex flex-col justify-between h-full overflow-y-scroll z-10">
|
||||
<div class="flex flex-col space-y-2 text-base-content/90">
|
||||
<template v-for="item in menu.top">
|
||||
<UiSidebarLink
|
||||
v-if="item.to"
|
||||
:to="item.to ?? ''"
|
||||
:icon="item.icon"
|
||||
:label="$t(item.label)"
|
||||
/>
|
||||
<UiSidebarLink v-if="item.to" v-bind="item" />
|
||||
|
||||
<UiSidebarButton
|
||||
v-else
|
||||
:icon="item.icon"
|
||||
:label="$t(item.label)"
|
||||
@click="item.click"
|
||||
/>
|
||||
<UiSidebarButton v-else :icon="item.icon" :label="$t(item.label)" @click="item.click" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-2 text-base-content/90">
|
||||
<template v-for="item in menu.bottom">
|
||||
<UiSidebarLink
|
||||
v-if="item.to"
|
||||
:to="item.to ?? ''"
|
||||
:icon="item.icon"
|
||||
:label="$t(item.label)"
|
||||
/>
|
||||
<UiSidebarLink v-if="item.to" v-bind="item" />
|
||||
|
||||
<UiSidebarButton
|
||||
v-else
|
||||
:icon="item.icon"
|
||||
:label="$t(item.label)"
|
||||
@click="item.click"
|
||||
/>
|
||||
<UiSidebarButton v-else :icon="item.icon" :label="$t(item.label)" @click="item.click" />
|
||||
</template>
|
||||
<!-- <UiSidebarLink
|
||||
v-for="item in menu.bottom"
|
||||
|
||||
@ -1,50 +1,37 @@
|
||||
<template>
|
||||
<li
|
||||
@click="triggerNavigate"
|
||||
class="hover:text-primary"
|
||||
class="hover:text-primary rounded"
|
||||
:class="{ ['bg-base-300']: isActive }"
|
||||
>
|
||||
<UiTooltip
|
||||
:tooltip="tooltip ?? name"
|
||||
direction="right-end"
|
||||
>
|
||||
<UiTooltip :tooltip="tooltip ?? name" direction="right-start">
|
||||
<NuxtLinkLocale
|
||||
:class="{ ['bg-base-300']: isActive }"
|
||||
:to="{
|
||||
name: type === 'browser' ? 'haexBrowser' : 'haexExtension',
|
||||
params: type === 'browser' ? {} : { extensionId: id },
|
||||
}"
|
||||
:to
|
||||
class="flex items-center justify-center cursor-pointer tooltip-toogle"
|
||||
ref="link"
|
||||
>
|
||||
<Icon
|
||||
:name="icon"
|
||||
class="shrink-0 size-6"
|
||||
/>
|
||||
<Icon :name="icon" class="shrink-0 size-6" />
|
||||
</NuxtLinkLocale>
|
||||
</UiTooltip>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type ISidebarItem } from '#imports';
|
||||
import { type ISidebarItem } from "#imports";
|
||||
|
||||
const props = defineProps<ISidebarItem>();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const isActive = computed(() => {
|
||||
if (props.type === 'browser') {
|
||||
return router.currentRoute.value.name === 'haexBrowser';
|
||||
} else if (props.type === 'extension') {
|
||||
return (
|
||||
router.currentRoute.value.name === 'haexExtension' &&
|
||||
getSingleRouteParam(router.currentRoute.value.params.extensionId) ===
|
||||
props.id
|
||||
);
|
||||
if (props.to?.name === "haexExtension") {
|
||||
return getSingleRouteParam(router.currentRoute.value.params.extensionId) === props.id;
|
||||
} else {
|
||||
return props.to?.name === router.currentRoute.value.meta.name;
|
||||
}
|
||||
});
|
||||
|
||||
const link = useTemplateRef('link');
|
||||
const link = useTemplateRef("link");
|
||||
|
||||
const triggerNavigate = () => link.value?.$el.click();
|
||||
|
||||
|
||||
@ -1,63 +1,52 @@
|
||||
<template>
|
||||
<UiDialog
|
||||
:title="t('title')"
|
||||
v-model:open="open"
|
||||
>
|
||||
<template #trigger="{ id }">
|
||||
<button
|
||||
class="btn btn-primary btn-outline shadow-md md:btn-lg shrink-0 flex-1 whitespace-nowrap flex-nowrap"
|
||||
@click="open = true"
|
||||
>
|
||||
<Icon name="mdi:plus" />
|
||||
{{ t('database.create') }}
|
||||
</button>
|
||||
</template>
|
||||
<UiDialog :title="t('title')" v-model:open="open">
|
||||
<template #trigger="{ id }">
|
||||
<button
|
||||
class="btn btn-primary btn-outline shadow-md md:btn-lg shrink-0 flex-1 whitespace-nowrap flex-nowrap"
|
||||
@click="open = true"
|
||||
>
|
||||
<Icon name="mdi:plus" />
|
||||
{{ t("database.create") }}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<form
|
||||
class="flex flex-col gap-4"
|
||||
@submit="onCreateAsync"
|
||||
>
|
||||
<!-- @keyup.enter="onCreateAsync" -->
|
||||
<UiInput
|
||||
:check-input="check"
|
||||
:label="t('database.label')"
|
||||
:placeholder="t('database.placeholder')"
|
||||
:rules="vaultDatabaseSchema.name"
|
||||
autofocus
|
||||
prepend-icon="mdi:safe"
|
||||
v-model="database.name"
|
||||
/>
|
||||
<form class="flex flex-col gap-4" @submit="onCreateAsync">
|
||||
<!-- @keyup.enter="onCreateAsync" -->
|
||||
<UiInput
|
||||
:check-input="check"
|
||||
:label="t('database.label')"
|
||||
:placeholder="t('database.placeholder')"
|
||||
:rules="vaultDatabaseSchema.name"
|
||||
autofocus
|
||||
prepend-icon="mdi:safe"
|
||||
v-model="database.name"
|
||||
/>
|
||||
|
||||
<UiInputPassword
|
||||
:check-input="check"
|
||||
:rules="vaultDatabaseSchema.password"
|
||||
prepend-icon="mdi:key-outline"
|
||||
v-model="database.password"
|
||||
/>
|
||||
</form>
|
||||
<UiInputPassword
|
||||
:check-input="check"
|
||||
:rules="vaultDatabaseSchema.password"
|
||||
prepend-icon="mdi:key-outline"
|
||||
v-model="database.password"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<template #buttons>
|
||||
<UiButton
|
||||
class="btn-error"
|
||||
@click="onClose"
|
||||
>
|
||||
{{ t('abort') }}
|
||||
</UiButton>
|
||||
<template #buttons>
|
||||
<UiButton class="btn-error" @click="onClose">
|
||||
{{ t("abort") }}
|
||||
</UiButton>
|
||||
|
||||
<UiButton
|
||||
class="btn-primary"
|
||||
@click="onCreateAsync"
|
||||
>
|
||||
{{ t('create') }}
|
||||
</UiButton>
|
||||
</template>
|
||||
</UiDialog>
|
||||
<UiButton class="btn-primary" @click="onCreateAsync">
|
||||
{{ t("create") }}
|
||||
</UiButton>
|
||||
</template>
|
||||
</UiDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { save } from '@tauri-apps/plugin-dialog';
|
||||
import { useVaultStore } from '~/stores/vault';
|
||||
import { vaultDatabaseSchema } from './schema';
|
||||
import { save } from "@tauri-apps/plugin-dialog";
|
||||
import { useVaultStore } from "~/stores/vault";
|
||||
import { vaultDatabaseSchema } from "./schema";
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
|
||||
const check = ref(false);
|
||||
const open = ref();
|
||||
@ -65,101 +54,93 @@ const open = ref();
|
||||
const { t } = useI18n();
|
||||
|
||||
const database = reactive<{
|
||||
name: string;
|
||||
password: string;
|
||||
path: string | null;
|
||||
type: 'password' | 'text';
|
||||
name: string;
|
||||
password: string;
|
||||
path: string | null;
|
||||
type: "password" | "text";
|
||||
}>({
|
||||
name: '',
|
||||
password: '',
|
||||
path: '',
|
||||
type: 'password',
|
||||
name: "",
|
||||
password: "",
|
||||
path: "",
|
||||
type: "password",
|
||||
});
|
||||
|
||||
const initDatabase = () => {
|
||||
database.name = t('database.name');
|
||||
database.password = '';
|
||||
database.path = '';
|
||||
database.type = 'password';
|
||||
database.name = t("database.name");
|
||||
database.password = "";
|
||||
database.path = "";
|
||||
database.type = "password";
|
||||
};
|
||||
|
||||
initDatabase();
|
||||
|
||||
const { add } = useSnackbar();
|
||||
const { createAsync } = useVaultStore();
|
||||
//const { show } = storeToRefs(useSidebarStore());
|
||||
|
||||
const onCreateAsync = async () => {
|
||||
check.value = true;
|
||||
check.value = true;
|
||||
|
||||
const nameCheck = vaultDatabaseSchema.name.safeParse(database.name);
|
||||
const passwordCheck = vaultDatabaseSchema.password.safeParse(
|
||||
database.password
|
||||
);
|
||||
const nameCheck = vaultDatabaseSchema.name.safeParse(database.name);
|
||||
const passwordCheck = vaultDatabaseSchema.password.safeParse(database.password);
|
||||
|
||||
console.log(
|
||||
'checks',
|
||||
database.name,
|
||||
nameCheck,
|
||||
database.password,
|
||||
passwordCheck
|
||||
);
|
||||
if (!nameCheck.success || !passwordCheck.success) return;
|
||||
console.log("checks", database.name, nameCheck, database.password, passwordCheck);
|
||||
if (!nameCheck.success || !passwordCheck.success) return;
|
||||
|
||||
open.value = false;
|
||||
try {
|
||||
database.path = await save({ defaultPath: `${database.name}.db` });
|
||||
open.value = false;
|
||||
try {
|
||||
database.path = await save({
|
||||
defaultPath: database.name.endsWith(".db") ? database.name : `${database.name}.db`,
|
||||
});
|
||||
|
||||
console.log('data', database);
|
||||
if (database.path && database.password) {
|
||||
const vaultId = await createAsync({
|
||||
path: database.path,
|
||||
password: database.password,
|
||||
});
|
||||
//show.value = true;
|
||||
console.log("data", database);
|
||||
|
||||
await navigateTo(
|
||||
useLocaleRoute()({ name: 'vault', params: { vaultId } })
|
||||
);
|
||||
if (database.path && database.password) {
|
||||
const vaultId = await createAsync({
|
||||
path: database.path,
|
||||
password: database.password,
|
||||
});
|
||||
|
||||
console.log("vaultId", vaultId);
|
||||
await navigateTo(useLocaleRoute()({ name: "vaultOverview", params: { vaultId } }));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
add({ type: "error", text: JSON.stringify(error) });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
add({ type: 'error', text: JSON.stringify(error) });
|
||||
}
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
open.value = false;
|
||||
initDatabase();
|
||||
open.value = false;
|
||||
initDatabase();
|
||||
};
|
||||
</script>
|
||||
|
||||
<i18n lang="json">
|
||||
{
|
||||
"de": {
|
||||
"database": {
|
||||
"label": "Datenbankname",
|
||||
"placeholder": "Passwörter",
|
||||
"create": "Neue Vault anlegen",
|
||||
"name": "Passwörter"
|
||||
"de": {
|
||||
"database": {
|
||||
"label": "Datenbankname",
|
||||
"placeholder": "Passwörter",
|
||||
"create": "Neue Vault anlegen",
|
||||
"name": "Passwörter"
|
||||
},
|
||||
"title": "Neue Datenbank anlegen",
|
||||
"create": "Erstellen",
|
||||
"abort": "Abbrechen",
|
||||
"description": "Haex Vault für deine geheimsten Geheimnisse"
|
||||
},
|
||||
"title": "Neue Datenbank anlegen",
|
||||
"create": "Erstellen",
|
||||
"abort": "Abbrechen",
|
||||
"description": "Haex Vault für deine geheimsten Geheimnisse"
|
||||
},
|
||||
|
||||
"en": {
|
||||
"database": {
|
||||
"label": "Databasename",
|
||||
"placeholder": "Databasename",
|
||||
"create": "Create new Vault",
|
||||
"name": "Passwords"
|
||||
},
|
||||
"title": "Create New Database",
|
||||
"create": "Create",
|
||||
"abort": "Abort",
|
||||
"description": "Haex Vault for your most secret secrets"
|
||||
}
|
||||
"en": {
|
||||
"database": {
|
||||
"label": "Databasename",
|
||||
"placeholder": "Databasename",
|
||||
"create": "Create new Vault",
|
||||
"name": "Passwords"
|
||||
},
|
||||
"title": "Create New Database",
|
||||
"create": "Create",
|
||||
"abort": "Abort",
|
||||
"description": "Haex Vault for your most secret secrets"
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
@click="onLoadDatabase"
|
||||
>
|
||||
<Icon name="mdi:folder-open-outline" />
|
||||
{{ t('database.open') }}
|
||||
{{ t("database.open") }}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@ -21,31 +21,24 @@
|
||||
/>
|
||||
|
||||
<template #buttons>
|
||||
<UiButton
|
||||
class="btn-error"
|
||||
@click="onClose"
|
||||
>
|
||||
{{ t('abort') }}
|
||||
<UiButton class="btn-error" @click="onClose">
|
||||
{{ t("abort") }}
|
||||
</UiButton>
|
||||
|
||||
<UiButton
|
||||
type="submit"
|
||||
class="btn-primary"
|
||||
@click="onOpenDatabase"
|
||||
>
|
||||
{{ t('open') }}
|
||||
<UiButton type="submit" class="btn-primary" @click="onOpenDatabase">
|
||||
{{ t("open") }}
|
||||
</UiButton>
|
||||
</template>
|
||||
</UiDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { vaultDatabaseSchema } from './schema';
|
||||
import { open } from "@tauri-apps/plugin-dialog";
|
||||
import { vaultDatabaseSchema } from "./schema";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const isOpen = defineModel('isOpen', { type: Boolean });
|
||||
const isOpen = defineModel("isOpen", { type: Boolean });
|
||||
|
||||
const props = defineProps({
|
||||
path: String,
|
||||
@ -57,19 +50,19 @@ const database = reactive<{
|
||||
name: string;
|
||||
password: string;
|
||||
path: string | null;
|
||||
type: 'password' | 'text';
|
||||
type: "password" | "text";
|
||||
}>({
|
||||
name: '',
|
||||
password: '',
|
||||
path: '',
|
||||
type: 'password',
|
||||
name: "",
|
||||
password: "",
|
||||
path: "",
|
||||
type: "password",
|
||||
});
|
||||
|
||||
const initDatabase = () => {
|
||||
database.name = '';
|
||||
database.password = '';
|
||||
database.path = '';
|
||||
database.type = 'password';
|
||||
database.name = "";
|
||||
database.password = "";
|
||||
database.path = "";
|
||||
database.type = "password";
|
||||
};
|
||||
|
||||
initDatabase();
|
||||
@ -78,7 +71,7 @@ const { add } = useSnackbar();
|
||||
|
||||
const handleError = (error: unknown) => {
|
||||
isOpen.value = false;
|
||||
add({ type: 'error', text: JSON.stringify(error) });
|
||||
add({ type: "error", text: JSON.stringify(error) });
|
||||
//console.error(error);
|
||||
};
|
||||
|
||||
@ -92,8 +85,8 @@ const onLoadDatabase = async () => {
|
||||
directory: false,
|
||||
filters: [
|
||||
{
|
||||
name: 'HaexVault',
|
||||
extensions: ['db'],
|
||||
name: "HaexVault",
|
||||
extensions: ["db"],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -112,16 +105,14 @@ const onOpenDatabase = async () => {
|
||||
check.value = true;
|
||||
const path = database.path || props.path;
|
||||
const pathCheck = vaultDatabaseSchema.path.safeParse(path);
|
||||
const passwordCheck = vaultDatabaseSchema.password.safeParse(
|
||||
database.password
|
||||
);
|
||||
const passwordCheck = vaultDatabaseSchema.password.safeParse(database.password);
|
||||
|
||||
if (!pathCheck.success || !passwordCheck.success || !path) {
|
||||
add({ type: 'error', text: 'params falsch' });
|
||||
add({ type: "error", text: "params falsch" });
|
||||
return;
|
||||
}
|
||||
|
||||
//console.log('try to open', path);
|
||||
console.log("try to open", path);
|
||||
|
||||
const vaultId = await openAsync({
|
||||
path,
|
||||
@ -129,23 +120,23 @@ const onOpenDatabase = async () => {
|
||||
});
|
||||
|
||||
if (!vaultId) {
|
||||
add({ type: 'error', text: 'Vault konnte nicht geöffnet werden' });
|
||||
add({ type: "error", text: "Vault konnte nicht geöffnet werden" });
|
||||
return;
|
||||
}
|
||||
|
||||
onClose();
|
||||
|
||||
/* await navigateTo(
|
||||
await navigateTo(
|
||||
localePath({
|
||||
name: 'vaultGroup',
|
||||
name: "vaultOverview",
|
||||
params: {
|
||||
vaultId,
|
||||
},
|
||||
query: {
|
||||
showSidebar: 'true',
|
||||
showSidebar: "true",
|
||||
},
|
||||
})
|
||||
); */
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
handleError(error);
|
||||
|
||||
@ -1,27 +1,34 @@
|
||||
<template>
|
||||
<div class="w-full h-full flex flex-col">
|
||||
<nav
|
||||
class="navbar bg-base-100 max-sm:rounded-box max-sm:shadow sm:border-b border-base-content/25 sm:z-20 relative"
|
||||
class="navbar bg-base-100 max-sm:rounded-box max-sm:shadow sm:border-b border-base-content/25 sm:z-20 relative px-2"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-text max-sm:btn-square sm:hidden me-2"
|
||||
class="btn btn-text btn-square me-2"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded="false"
|
||||
aria-controls="sidebar"
|
||||
data-overlay="#sidebar"
|
||||
>
|
||||
<Icon name="mage:dash-menu" size="28" />
|
||||
</button>
|
||||
<!-- <button
|
||||
type="button"
|
||||
class="btn btn-text max-sm:btn-square me-2"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded="false"
|
||||
aria-controls="sidebar"
|
||||
data-overlay="#sidebar"
|
||||
>
|
||||
<span class="icon-[tabler--menu-2] size-5"></span>
|
||||
</button>
|
||||
</button> -->
|
||||
<div class="flex flex-1 items-center">
|
||||
<a
|
||||
class="link text-base-content link-neutral text-xl font-semibold no-underline"
|
||||
href="#"
|
||||
>
|
||||
<a class="link text-base-content link-neutral text-xl font-semibold no-underline" href="#">
|
||||
<UiTextGradient>Haex Hub</UiTextGradient>
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-end flex items-center gap-4">
|
||||
<div class="navbar-end flex items-center gap-4 me-4">
|
||||
<div
|
||||
class="dropdown relative inline-flex [--auto-close:inside] [--offset:8] [--placement:bottom-end]"
|
||||
>
|
||||
@ -38,9 +45,7 @@
|
||||
v-show="notifications.length"
|
||||
class="indicator-item bg-error size-2 rounded-full text-sm"
|
||||
></span>
|
||||
<span
|
||||
class="icon-[tabler--bell] text-base-content size-[1.375rem]"
|
||||
></span>
|
||||
<span class="icon-[tabler--bell] text-base-content size-[1.375rem]"></span>
|
||||
</div>
|
||||
</button>
|
||||
<div
|
||||
@ -51,16 +56,13 @@
|
||||
>
|
||||
<div class="dropdown-header justify-center">
|
||||
<h6 class="text-base-content text-base">
|
||||
{{ t('notifications.label') }}
|
||||
{{ t("notifications.label") }}
|
||||
</h6>
|
||||
</div>
|
||||
<div
|
||||
class="vertical-scrollbar horizontal-scrollbar rounded-scrollbar text-base-content/80 max-h-56 overflow-auto max-md:max-w-60"
|
||||
>
|
||||
<div
|
||||
class="dropdown-item"
|
||||
v-for="notification in notifications"
|
||||
>
|
||||
<div class="dropdown-item" v-for="notification in notifications">
|
||||
<div class="avatar">
|
||||
<div class="w-10 rounded-full">
|
||||
<img
|
||||
@ -68,10 +70,7 @@
|
||||
:src="notification.image"
|
||||
:alt="notification.alt ?? 'notification avatar'"
|
||||
/>
|
||||
<Icon
|
||||
v-else-if="notification.icon"
|
||||
:name="notification.icon"
|
||||
/>
|
||||
<Icon v-else-if="notification.icon" :name="notification.icon" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-60">
|
||||
@ -84,12 +83,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="#"
|
||||
class="dropdown-footer justify-center gap-1"
|
||||
>
|
||||
<a href="#" class="dropdown-footer justify-center gap-1">
|
||||
<span class="icon-[tabler--eye] size-4"></span>
|
||||
{{ t('notifications.view_all') }}
|
||||
{{ t("notifications.view_all") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -106,10 +102,7 @@
|
||||
>
|
||||
<div class="avatar">
|
||||
<div class="size-9.5 rounded-full">
|
||||
<img
|
||||
src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png"
|
||||
alt="avatar 1"
|
||||
/>
|
||||
<img src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png" alt="avatar 1" />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@ -122,62 +115,42 @@
|
||||
<li class="dropdown-header gap-2">
|
||||
<div class="avatar">
|
||||
<div class="w-10 rounded-full">
|
||||
<img
|
||||
src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png"
|
||||
alt="avatar"
|
||||
/>
|
||||
<img src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png" alt="avatar" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-base-content text-base font-semibold">
|
||||
John Doe
|
||||
</h6>
|
||||
<h6 class="text-base-content text-base font-semibold">John Doe</h6>
|
||||
<small class="text-base-content/50">Admin</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="#"
|
||||
>
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="icon-[tabler--user]"></span>
|
||||
My Profile
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="#"
|
||||
>
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="icon-[tabler--settings]"></span>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="#"
|
||||
>
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="icon-[tabler--receipt-rupee]"></span>
|
||||
Billing
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="#"
|
||||
>
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="icon-[tabler--help-triangle]"></span>
|
||||
FAQs
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-footer gap-2">
|
||||
<button
|
||||
class="btn btn-error btn-soft btn-block"
|
||||
@click="onVaultCloseAsync"
|
||||
>
|
||||
<button class="btn btn-error btn-soft btn-block" @click="onVaultCloseAsync">
|
||||
<span class="icon-[tabler--logout]"></span>
|
||||
{{ t('vault.close') }}
|
||||
{{ t("vault.close") }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@ -187,7 +160,7 @@
|
||||
|
||||
<aside
|
||||
id="sidebar"
|
||||
class="overlay sm:shadow-none overlay-open:translate-x-0 drawer drawer-start hidden sm:absolute max-w-14 sm:flex sm:translate-x-0 sm:pt-16 z-10"
|
||||
class="overlay sm:shadow-none overlay-open:translate-x-0 drawer drawer-start hidden sm:absolute max-w-14 sm:flex sm:translate-x-0 sm:pt-12 z-10"
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
@ -198,11 +171,7 @@
|
||||
|
||||
|
||||
> -->
|
||||
<UiSidebarLink
|
||||
v-bind="item"
|
||||
v-for="item in menu"
|
||||
:key="item.id"
|
||||
/>
|
||||
<UiSidebarLink v-bind="item" v-for="item in menu" :key="item.id" />
|
||||
<!-- <UiTooltip
|
||||
:tooltip="item.tooltip || item.name"
|
||||
direction="right-start"
|
||||
@ -232,7 +201,7 @@
|
||||
|
||||
<div class="overflow-hidden transition-all relative w-full">
|
||||
<div class="h-full overflow-scroll sm:pl-14">
|
||||
<NuxtPage />
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -249,10 +218,13 @@ const { notifications } = storeToRefs(useNotificationStore());
|
||||
|
||||
const { menu } = storeToRefs(useSidebarStore());
|
||||
const { isActive } = useExtensionsStore();
|
||||
|
||||
const { closeAsync } = useVaultStore();
|
||||
const onExtensionSelectAsync = async (id: string) => {};
|
||||
|
||||
const onVaultCloseAsync = async () => {};
|
||||
const onVaultCloseAsync = async () => {
|
||||
await closeAsync();
|
||||
await navigateTo(useLocalePath()({ name: "vaultOpen" }));
|
||||
};
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
|
||||
@ -1,17 +1,11 @@
|
||||
<template>
|
||||
<div class="items-center justify-center min-h-full flex w-full">
|
||||
<div class="flex flex-col justify-center items-center gap-4 max-w-3xl">
|
||||
<img
|
||||
src="/logo.svg"
|
||||
class="bg-primary p-3 size-16 rounded-full"
|
||||
alt="HaexVault Logo"
|
||||
/>
|
||||
<img src="/logo.svg" class="bg-primary p-3 size-16 rounded-full" alt="HaexVault Logo" />
|
||||
|
||||
<span
|
||||
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
||||
>
|
||||
<span class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center">
|
||||
<p class="whitespace-nowrap">
|
||||
{{ t('welcome') }}
|
||||
{{ t("welcome") }}
|
||||
</p>
|
||||
<UiTextGradient>Haex Hub</UiTextGradient>
|
||||
</span>
|
||||
@ -19,17 +13,14 @@
|
||||
<div class="flex flex-col md:flex-row gap-4 w-full">
|
||||
<VaultButtonCreate />
|
||||
|
||||
<!-- <VaultButtonOpen
|
||||
v-model:isOpen="passwordPromptOpen"
|
||||
:path="vaultPath"
|
||||
/> -->
|
||||
<NuxtLinkLocale
|
||||
<VaultButtonOpen v-model:isOpen="passwordPromptOpen" :path="vaultPath" />
|
||||
<!-- <NuxtLinkLocale
|
||||
:to="{
|
||||
name: 'haexBrowser',
|
||||
params: { vaultId: 'test' },
|
||||
}"
|
||||
>test link</NuxtLinkLocale
|
||||
>
|
||||
> -->
|
||||
<!-- <button @click="test">test</button>
|
||||
<NuxtLinkLocale
|
||||
:to="{ name: 'vaultGroup', params: { vaultId: 'test' } }"
|
||||
@ -47,12 +38,9 @@
|
||||
/> -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="lastVaults.length"
|
||||
class="w-full"
|
||||
>
|
||||
<div v-show="lastVaults.length" class="w-full">
|
||||
<div class="font-thin text-sm justify-start px-2 pb-1">
|
||||
{{ t('lastUsed') }}
|
||||
{{ t("lastUsed") }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -80,17 +68,14 @@
|
||||
<button
|
||||
class="absolute right-2 btn btn-square btn-error btn-xs hidden group-hover:flex min-w-6"
|
||||
>
|
||||
<Icon
|
||||
name="mdi:trash-can-outline"
|
||||
@click="removeVaultAsync(vault.path)"
|
||||
/>
|
||||
<Icon name="mdi:trash-can-outline" @click="removeVaultAsync(vault.path)" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<h4>{{ t('sponsors') }}</h4>
|
||||
<h4>{{ t("sponsors") }}</h4>
|
||||
<div>
|
||||
<button @click="openUrl('https://itemis.com')">
|
||||
<UiLogoItemis class="text-[#00457C]" />
|
||||
@ -102,13 +87,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { openUrl } from '@tauri-apps/plugin-opener';
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
|
||||
const passwordPromptOpen = ref(false);
|
||||
const vaultPath = ref('');
|
||||
const vaultPath = ref("");
|
||||
|
||||
definePageMeta({
|
||||
name: 'vaultOpen',
|
||||
name: "vaultOpen",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<NuxtLayout name="app">
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
<div class="text-white">
|
||||
<NuxtLayout name="app">
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { createTable } = useVaultStore();
|
||||
</script>
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
<template>
|
||||
<div>
|
||||
browser
|
||||
<HaexBrowser
|
||||
:tabs="tabs"
|
||||
:activeTabId="activeTabId"
|
||||
@createTab="createNewTab"
|
||||
@closeTab="closeTab"
|
||||
@navigate="navigateToUrl"
|
||||
@goBack="goBack"
|
||||
@goForward="goForward"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
browser {{ useRouter().currentRoute.value.meta.name }}
|
||||
<HaexBrowser
|
||||
:tabs="tabs"
|
||||
:activeTabId="activeTabId"
|
||||
@createTab="createNewTab"
|
||||
@closeTab="closeTab"
|
||||
@navigate="navigateToUrl"
|
||||
@goBack="goBack"
|
||||
@goForward="goForward"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { listen, type UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { Window, getCurrentWindow } from '@tauri-apps/api/window';
|
||||
import { Webview } from '@tauri-apps/api/webview';
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { Window, getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import { Webview } from "@tauri-apps/api/webview";
|
||||
|
||||
definePageMeta({
|
||||
name: 'haexBrowser',
|
||||
name: "haexBrowser",
|
||||
});
|
||||
|
||||
interface Tab {
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
isLoading: boolean;
|
||||
isActive: boolean;
|
||||
window_label: string;
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
isLoading: boolean;
|
||||
isActive: boolean;
|
||||
window_label: string;
|
||||
}
|
||||
|
||||
const tabs = ref<Tab[]>([]);
|
||||
@ -39,43 +39,43 @@ let unlistenTabCreated: UnlistenFn | null = null;
|
||||
let unlistenTabClosed: UnlistenFn | null = null;
|
||||
|
||||
onMounted(async () => {
|
||||
// Erstelle einen ersten Tab beim Start
|
||||
createNewTab('https://www.google.com');
|
||||
// Erstelle einen ersten Tab beim Start
|
||||
//createNewTab("https://www.google.com");
|
||||
|
||||
// Höre auf Tab-Events
|
||||
unlistenTabCreated = await listen('tab-created', (event) => {
|
||||
const newTab = event.payload as Tab;
|
||||
// Höre auf Tab-Events
|
||||
unlistenTabCreated = await listen("tab-created", (event) => {
|
||||
const newTab = event.payload as Tab;
|
||||
|
||||
tabs.value = tabs.value.map((tab) => ({
|
||||
...tab,
|
||||
isActive: tab.id === newTab.id,
|
||||
}));
|
||||
tabs.value = tabs.value.map((tab) => ({
|
||||
...tab,
|
||||
isActive: tab.id === newTab.id,
|
||||
}));
|
||||
|
||||
if (!tabs.value.some((tab) => tab.id === newTab.id)) {
|
||||
tabs.value.push(newTab);
|
||||
}
|
||||
if (!tabs.value.some((tab) => tab.id === newTab.id)) {
|
||||
tabs.value.push(newTab);
|
||||
}
|
||||
|
||||
activeTabId.value = newTab.id;
|
||||
});
|
||||
activeTabId.value = newTab.id;
|
||||
});
|
||||
|
||||
unlistenTabClosed = await listen('tab-closed', (event) => {
|
||||
const closedTabId = event.payload as string;
|
||||
tabs.value = tabs.value.filter((tab) => tab.id !== closedTabId);
|
||||
});
|
||||
unlistenTabClosed = await listen("tab-closed", (event) => {
|
||||
const closedTabId = event.payload as string;
|
||||
tabs.value = tabs.value.filter((tab) => tab.id !== closedTabId);
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (unlistenTabCreated) unlistenTabCreated();
|
||||
if (unlistenTabClosed) unlistenTabClosed();
|
||||
if (unlistenTabCreated) unlistenTabCreated();
|
||||
if (unlistenTabClosed) unlistenTabClosed();
|
||||
});
|
||||
|
||||
const createNewTab = async (url: string = 'about:blank') => {
|
||||
try {
|
||||
/* const appWindow = new Window('uniqueLabel111', {
|
||||
const createNewTab = async (url: string = "about:blank") => {
|
||||
try {
|
||||
/* const appWindow = new Window('uniqueLabel111', {
|
||||
fullscreen: true,
|
||||
});
|
||||
*/
|
||||
/* const appWindow = getCurrentWindow();
|
||||
/* const appWindow = getCurrentWindow();
|
||||
|
||||
const webview = new Webview(appWindow, 'theUniqueLabel', {
|
||||
url: 'https://github.com/tauri-apps/tauri',
|
||||
@ -85,43 +85,43 @@ const createNewTab = async (url: string = 'about:blank') => {
|
||||
y: 0,
|
||||
});
|
||||
await webview.show(); */
|
||||
//console.log('create webview', webview);
|
||||
const tab_id = 'foo';
|
||||
await invoke('create_tab', { url, tabId: 'foo' });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Erstellen des Tabs:', error);
|
||||
}
|
||||
//console.log('create webview', webview);
|
||||
const tab_id = "foo";
|
||||
await invoke("create_tab", { url, tabId: "foo" });
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Erstellen des Tabs:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const closeTab = async (tabId: string) => {
|
||||
try {
|
||||
//await invoke('close_tab', { tabId });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Schließen des Tabs:', error);
|
||||
}
|
||||
try {
|
||||
//await invoke('close_tab', { tabId });
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Schließen des Tabs:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const navigateToUrl = async (tabId: string, url: string) => {
|
||||
try {
|
||||
//await invoke('navigate_to_url', { tabId, url });
|
||||
} catch (error) {
|
||||
console.error('Fehler bei der Navigation:', error);
|
||||
}
|
||||
try {
|
||||
//await invoke('navigate_to_url', { tabId, url });
|
||||
} catch (error) {
|
||||
console.error("Fehler bei der Navigation:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const goBack = async (tabId: string | null) => {
|
||||
try {
|
||||
//await invoke('go_back', { tabId });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Zurückgehen:', error);
|
||||
}
|
||||
try {
|
||||
//await invoke('go_back', { tabId });
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Zurückgehen:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const goForward = async (tabId: string | null) => {
|
||||
try {
|
||||
//await invoke('go_forward', { tabId });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Vorwärtsgehen:', error);
|
||||
}
|
||||
try {
|
||||
//await invoke('go_forward', { tabId });
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Vorwärtsgehen:", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,13 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
hier kommt die erweiterung
|
||||
{{ useRouter().currentRoute.value.params.extensionId }}
|
||||
<iframe></iframe>
|
||||
<div class="w-full h-full">
|
||||
<iframe class="w-full h-full" @load="" ref="iFrameRef"> </iframe>
|
||||
<p>{{ t("loading") }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
name: 'haexExtension',
|
||||
name: "haexExtension",
|
||||
});
|
||||
|
||||
const iframeRef = useTemplateRef("iFrameRef");
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
de:
|
||||
loading: Erweiterung wird geladen
|
||||
en:
|
||||
loading: Extension is loading
|
||||
</i18n>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>ad extension</div>
|
||||
<div>add extension</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
name: 'extensionAdd',
|
||||
name: "haexExtensionAdd",
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>vault</div>
|
||||
<div class="h-screen bg-blue-200"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
name: 'vaultOverview',
|
||||
name: "vaultOverview",
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1,57 +1,221 @@
|
||||
import { getSingleRouteParam } from '~/composables/helper';
|
||||
import type { RouteLocationRaw } from 'vue-router';
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { join, resourceDir } from "@tauri-apps/api/path";
|
||||
import { readTextFile, readDir } from "@tauri-apps/plugin-fs";
|
||||
import { convertFileSrc } from "@tauri-apps/api/core";
|
||||
|
||||
export interface IExtensionLink {
|
||||
const manifestFileName = "manifest.json";
|
||||
|
||||
export interface IHaexHubExtensionLink {
|
||||
name: string;
|
||||
icon: string;
|
||||
tooltip?: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
const extensions = ref<IExtensionLink[]>([
|
||||
export interface IHaexHubExtensionManifest {
|
||||
name: string;
|
||||
entry: string;
|
||||
permissions: {
|
||||
database?: {
|
||||
read?: string[];
|
||||
write?: string[];
|
||||
create?: string[];
|
||||
};
|
||||
http?: string[];
|
||||
filesystem?: {
|
||||
read?: string[];
|
||||
write?: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const useExtensionsStore = defineStore("extensionsStore", () => {
|
||||
const availableExtensions = ref<IHaexHubExtensionLink[]>([
|
||||
{
|
||||
id: 'haex-browser',
|
||||
name: 'Haex Browser',
|
||||
icon: 'solar:global-outline',
|
||||
id: "haex-browser",
|
||||
name: "Haex Browser",
|
||||
icon: "solar:global-outline",
|
||||
},
|
||||
|
||||
{
|
||||
id: 'extensions',
|
||||
name: 'sidebar.extensions',
|
||||
icon: 'gg:extension',
|
||||
id: "extensions",
|
||||
name: "sidebar.extensions",
|
||||
icon: "gg:extension",
|
||||
},
|
||||
|
||||
{
|
||||
id: 'settings',
|
||||
name: 'sidebar.settings',
|
||||
icon: 'ph:gear-six',
|
||||
id: "settings",
|
||||
name: "sidebar.settings",
|
||||
icon: "ph:gear-six",
|
||||
},
|
||||
]);
|
||||
|
||||
const currentRoute = useRouter().currentRoute.value;
|
||||
const currentRoute = useRouter().currentRoute;
|
||||
|
||||
const isActive = (id: string) =>
|
||||
computed(
|
||||
() =>
|
||||
currentRoute.name === 'extension' &&
|
||||
currentRoute.params.extensionId === id
|
||||
currentRoute.value.name === "extension" &&
|
||||
currentRoute.value.params.extensionId === id
|
||||
);
|
||||
|
||||
const loadAsync = async (id: string) => {
|
||||
extensions.value.some(async (extension) => {
|
||||
if (extension.id === id) {
|
||||
await navigateTo(
|
||||
useLocalePath()({ name: 'extension', params: { extensionId: id } })
|
||||
);
|
||||
} else {
|
||||
const currentExtension = computed(() => {
|
||||
if (currentRoute.value.name !== "haexExtension") return;
|
||||
|
||||
const extensionId = getSingleRouteParam(
|
||||
currentRoute.value.params.extensionId
|
||||
);
|
||||
|
||||
if (!extensionId) return;
|
||||
|
||||
return availableExtensions.value.find(
|
||||
(extension) => extension.id === extensionId
|
||||
);
|
||||
});
|
||||
|
||||
const checkExtensionDirectoryAsync = async (extensionDirectory: string) => {
|
||||
try {
|
||||
const dir = await readDir(extensionDirectory);
|
||||
const manifest = dir.find(
|
||||
(entry) => entry.name === manifestFileName && entry.isFile
|
||||
);
|
||||
if (!manifest) throw new Error("Kein Manifest für Erweiterung gefunden");
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Keine Leseberechtigung für Ordner ${extensionDirectory}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const installAsync = async (
|
||||
extensionDirectory: string | null,
|
||||
global: boolean = true
|
||||
): Promise<void> => {
|
||||
try {
|
||||
if (!extensionDirectory)
|
||||
throw new Error("Kein Ordner für Erweiterung angegeben");
|
||||
const checkDirectory = await checkExtensionDirectoryAsync(
|
||||
extensionDirectory
|
||||
);
|
||||
|
||||
const manifestPath = await join(extensionDirectory, "manifest.json");
|
||||
const manifest = await JSON.parse(await readTextFile(manifestPath));
|
||||
|
||||
console.log("manifest", manifest);
|
||||
return;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
/*
|
||||
const resourcePath = await resourceDir();
|
||||
//const manifestPath = await join(extensionDirectory, 'manifest.json');
|
||||
const manifestPath = await join(
|
||||
resourcePath,
|
||||
'extension',
|
||||
'demo-addon',
|
||||
'manifest.json'
|
||||
);
|
||||
const regex = /((href|src)=["'])([^"']+)(["'])/g;
|
||||
let htmlContent = await readTextFile(
|
||||
await join(resourcePath, 'extension', 'demo-addon', 'index.html')
|
||||
);
|
||||
|
||||
const replacements = [];
|
||||
let match;
|
||||
while ((match = regex.exec(htmlContent)) !== null) {
|
||||
const [fullMatch, prefix, attr, resource, suffix] = match;
|
||||
if (!resource.startsWith('http')) {
|
||||
replacements.push({ match: fullMatch, resource, prefix, suffix });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const { match, resource, prefix, suffix } of replacements) {
|
||||
const fileContent = await readTextFile(
|
||||
await join(resourcePath, 'extension', 'demo-addon', resource)
|
||||
);
|
||||
const blob = new Blob([fileContent], { type: getMimeType(resource) });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
console.log('blob', resource, blobUrl);
|
||||
htmlContent = htmlContent.replace(
|
||||
match,
|
||||
`${prefix}${blobUrl}${suffix}`
|
||||
);
|
||||
}
|
||||
|
||||
console.log('htmlContent', htmlContent);
|
||||
|
||||
const blob = new Blob([htmlContent], { type: 'text/html' });
|
||||
const iframeSrc = URL.createObjectURL(blob);
|
||||
|
||||
const manifestContent = await readTextFile(manifestPath);
|
||||
console.log('iframeSrc', iframeSrc);
|
||||
const manifest: PluginManifest = JSON.parse(manifestContent);
|
||||
//const entryPath = await join(extensionDirectory, manifest.entry);
|
||||
const entryPath = await join(
|
||||
resourcePath,
|
||||
'extension',
|
||||
'demo-addon',
|
||||
manifest.entry
|
||||
);
|
||||
console.log('extensionDirectory', extensionDirectory, entryPath);
|
||||
const path = convertFileSrc(extensionDirectory, manifest.entry);
|
||||
console.log('final path', path);
|
||||
manifest.entry = iframeSrc;
|
||||
/* await join(
|
||||
path, //`file:/${extensionDirectory}`,
|
||||
manifest.entry
|
||||
); */
|
||||
// Modul-Datei laden
|
||||
//const modulePathFull = await join(basePath, manifest.main);
|
||||
/* const manifest: PluginManifest = await invoke('load_plugin', {
|
||||
manifestPath,
|
||||
}); */
|
||||
/* const iframe = document.createElement('iframe');
|
||||
iframe.src = manifest.entry;
|
||||
iframe.setAttribute('sandbox', 'allow-scripts');
|
||||
iframe.style.width = '100%';
|
||||
iframe.style.height = '100%';
|
||||
iframe.style.border = 'none'; */
|
||||
/* const addonApi = {
|
||||
db_execute: async (sql: string, params: string[] = []) => {
|
||||
return invoke('db_execute', {
|
||||
addonId: manifest.name,
|
||||
sql,
|
||||
params,
|
||||
});
|
||||
},
|
||||
db_select: async (sql: string, params: string[] = []) => {
|
||||
return invoke('db_select', {
|
||||
addonId: manifest.name,
|
||||
sql,
|
||||
params,
|
||||
});
|
||||
},
|
||||
}; */
|
||||
/* iframe.onload = () => {
|
||||
iframe.contentWindow?.postMessage(
|
||||
{ type: 'init', payload: addonApi },
|
||||
'*'
|
||||
);
|
||||
};
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.source === iframe.contentWindow) {
|
||||
const { type } = event.data;
|
||||
if (type === 'ready') {
|
||||
console.log(`Plugin ${manifest.name} ist bereit`);
|
||||
}
|
||||
}
|
||||
}); */
|
||||
/* plugins.value.push({ name: manifest.name, entry: manifest.entry });
|
||||
|
||||
console.log(`Plugin ${manifest.name} geladen.`); */
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
extensions,
|
||||
loadAsync,
|
||||
availableExtensions,
|
||||
currentExtension,
|
||||
isActive,
|
||||
};
|
||||
});
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
import { getSingleRouteParam } from '~/composables/helper';
|
||||
import type { RouteLocationRaw } from 'vue-router';
|
||||
import { getSingleRouteParam } from "~/composables/helper";
|
||||
import type { RouteLocationRaw, RouteLocationAsRelativeGeneric } from "vue-router";
|
||||
|
||||
export interface ISidebarItem {
|
||||
name: string;
|
||||
icon: string;
|
||||
tooltip?: string;
|
||||
id: string;
|
||||
type: 'browser' | 'extension';
|
||||
name: string;
|
||||
icon: string;
|
||||
tooltip?: string;
|
||||
id: string;
|
||||
to?: RouteLocationAsRelativeGeneric;
|
||||
}
|
||||
|
||||
export const useSidebarStore = defineStore('sidebarStore', () => {
|
||||
const menu = ref<ISidebarItem[]>([
|
||||
{
|
||||
id: 'haex-browser',
|
||||
name: 'Haex Browser',
|
||||
icon: 'solar:global-outline',
|
||||
type: 'browser',
|
||||
},
|
||||
export const useSidebarStore = defineStore("sidebarStore", () => {
|
||||
const menu = ref<ISidebarItem[]>([
|
||||
{
|
||||
id: "haex-browser",
|
||||
name: "Haex Browser",
|
||||
icon: "solar:global-outline",
|
||||
to: { name: "haexBrowser" },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'haex-vault',
|
||||
name: 'Haex Vault',
|
||||
icon: 'gg:extension',
|
||||
type: 'extension',
|
||||
},
|
||||
]);
|
||||
{
|
||||
id: "haex-extensions-add",
|
||||
name: "Haex Extensions",
|
||||
icon: "gg:extension",
|
||||
to: { name: "haexExtensionAdd" },
|
||||
},
|
||||
]);
|
||||
|
||||
/* const loadAsync = async (id: string) => {
|
||||
/* const loadAsync = async (id: string) => {
|
||||
extensions.value.some(async (extension) => {
|
||||
if (extension.id === id) {
|
||||
await navigateTo(
|
||||
@ -37,8 +37,8 @@ export const useSidebarStore = defineStore('sidebarStore', () => {
|
||||
});
|
||||
}; */
|
||||
|
||||
return {
|
||||
menu,
|
||||
//loadAsync,
|
||||
};
|
||||
return {
|
||||
menu,
|
||||
//loadAsync,
|
||||
};
|
||||
});
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
//import Database from '@tauri-apps/plugin-sql';
|
||||
import { drizzle, SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy';
|
||||
import { drizzle, SqliteRemoteDatabase } from "drizzle-orm/sqlite-proxy";
|
||||
//import Database from "tauri-plugin-sql-api";
|
||||
import * as schema from '@/../src-tauri/database/schemas/vault';
|
||||
import * as schema from "@/../src-tauri/database/schemas/vault";
|
||||
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { count } from 'drizzle-orm';
|
||||
import { platform } from '@tauri-apps/plugin-os';
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { count } from "drizzle-orm";
|
||||
import { platform } from "@tauri-apps/plugin-os";
|
||||
|
||||
interface IVault {
|
||||
//database: Database;
|
||||
@ -18,24 +18,19 @@ interface IOpenVaults {
|
||||
[vaultPath: string]: IVault;
|
||||
}
|
||||
|
||||
export const useVaultStore = defineStore('vaultStore', () => {
|
||||
export const useVaultStore = defineStore("vaultStore", () => {
|
||||
const currentVaultId = computed<string | undefined>({
|
||||
get: () =>
|
||||
getSingleRouteParam(useRouter().currentRoute.value.params.vaultId),
|
||||
get: () => getSingleRouteParam(useRouter().currentRoute.value.params.vaultId),
|
||||
set: (newVaultId) => {
|
||||
useRouter().currentRoute.value.params.vaultId = newVaultId ?? '';
|
||||
useRouter().currentRoute.value.params.vaultId = newVaultId ?? "";
|
||||
},
|
||||
});
|
||||
|
||||
const read_only = computed<boolean>({
|
||||
get: () => {
|
||||
console.log(
|
||||
'query showSidebar',
|
||||
useRouter().currentRoute.value.query.readonly
|
||||
);
|
||||
console.log("query showSidebar", useRouter().currentRoute.value.query.readonly);
|
||||
return JSON.parse(
|
||||
getSingleRouteParam(useRouter().currentRoute.value.query.readonly) ||
|
||||
'false'
|
||||
getSingleRouteParam(useRouter().currentRoute.value.query.readonly) || "false"
|
||||
);
|
||||
},
|
||||
set: (readonly) => {
|
||||
@ -53,51 +48,32 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
|
||||
const currentVault = ref<IVault | undefined>();
|
||||
|
||||
/* computed(() => {
|
||||
console.log('compute currentVault', currentVaultId.value, openVaults.value);
|
||||
return openVaults.value?.[currentVaultId.value ?? ''];
|
||||
}); */
|
||||
|
||||
watch(
|
||||
currentVaultId,
|
||||
async () => {
|
||||
/* if (!openVaults.value?.[currentVaultId.value ?? '']) {
|
||||
console.log(
|
||||
'no vaultId',
|
||||
currentVault.value,
|
||||
openVaults.value?.[currentVaultId.value ?? '']
|
||||
);
|
||||
return await navigateTo(useLocalePath()({ name: 'vaultOpen' }));
|
||||
} else */
|
||||
currentVault.value = openVaults.value?.[currentVaultId.value ?? ''];
|
||||
currentVault.value = openVaults.value?.[currentVaultId.value ?? ""];
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const openAsync = async ({
|
||||
path = '',
|
||||
password,
|
||||
}: {
|
||||
path: string;
|
||||
password: string;
|
||||
}) => {
|
||||
//const sqlitePath = path?.startsWith('sqlite:') ? path : `sqlite:${path}`;
|
||||
const openAsync = async ({ path = "", password }: { path: string; password: string }) => {
|
||||
const sqlitePath = path?.startsWith("sqlite:") ? path : `sqlite:${path}`;
|
||||
|
||||
console.log('try to open db', path, password);
|
||||
console.log("try to open db", path, password);
|
||||
|
||||
const result = await invoke<string>('open_encrypted_database', {
|
||||
const result = await invoke<string>("open_encrypted_database", {
|
||||
path,
|
||||
key: password,
|
||||
});
|
||||
|
||||
console.log('open vault from store', result);
|
||||
if (!(await testDatabaseReadAsync())) throw new Error('Passwort falsch');
|
||||
console.log("open vault from store", result);
|
||||
if (!(await testDatabaseReadAsync())) throw new Error("Passwort falsch");
|
||||
//const db = await Database.load(sqlitePath);
|
||||
|
||||
const vaultId = await getVaultIdAsync(path);
|
||||
const seperator = platform() === 'windows' ? '\\' : '/';
|
||||
const seperator = platform() === "windows" ? "\\" : "/";
|
||||
const fileName = path.split(seperator).pop();
|
||||
console.log('opened db fileName', fileName, vaultId);
|
||||
console.log("opened db fileName", fileName, vaultId);
|
||||
|
||||
openVaults.value = {
|
||||
...openVaults.value,
|
||||
@ -113,14 +89,14 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
|
||||
// If the query is a SELECT, use the select method
|
||||
if (isSelectQuery(sql)) {
|
||||
rows = await invoke('db_select', { sql, params }).catch((e) => {
|
||||
console.error('SQL Error:', e);
|
||||
rows = await invoke("db_select", { sql, params }).catch((e) => {
|
||||
console.error("SQL Error:", e);
|
||||
return [];
|
||||
});
|
||||
} else {
|
||||
// Otherwise, use the execute method
|
||||
rows = await invoke('db_execute', { sql, params }).catch((e) => {
|
||||
console.error('SQL Error:', e);
|
||||
rows = await invoke("db_execute", { sql, params }).catch((e) => {
|
||||
console.error("SQL Error:", e);
|
||||
return [];
|
||||
});
|
||||
return { rows: [] };
|
||||
@ -131,7 +107,7 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
});
|
||||
|
||||
// If the method is "all", return all rows
|
||||
results = method === 'all' ? rows : rows[0];
|
||||
results = method === "all" ? rows : rows[0];
|
||||
|
||||
return { rows: results };
|
||||
},
|
||||
@ -147,11 +123,18 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
return vaultId;
|
||||
};
|
||||
|
||||
const createTable = () => {
|
||||
console.log("ddd", schema.testTable.getSQL().queryChunks);
|
||||
|
||||
schema.testTable.getSQL().queryChunks.forEach((chunk) => {
|
||||
const res = currentVault.value?.drizzle.run(chunk);
|
||||
console.log("create table", res);
|
||||
});
|
||||
};
|
||||
|
||||
const testDatabaseReadAsync = async () => {
|
||||
try {
|
||||
currentVault.value?.drizzle
|
||||
.select({ count: count() })
|
||||
.from(schema.haexExtensions);
|
||||
currentVault.value?.drizzle.select({ count: count() }).from(schema.haexExtensions);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
@ -159,19 +142,13 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
};
|
||||
|
||||
const refreshDatabaseAsync = async () => {
|
||||
console.log('refreshDatabaseAsync');
|
||||
console.log("refreshDatabaseAsync");
|
||||
/* if (!currentVault.value?.database.close) {
|
||||
return navigateTo(useLocaleRoute()({ name: 'vaultOpen' }));
|
||||
} */
|
||||
};
|
||||
|
||||
const createAsync = async ({
|
||||
path,
|
||||
password,
|
||||
}: {
|
||||
path: string;
|
||||
password: string;
|
||||
}) => {
|
||||
const createAsync = async ({ path, password }: { path: string; password: string }) => {
|
||||
/* const existDb = await exists('default.db', {
|
||||
baseDir: BaseDirectory.Resource,
|
||||
}); */
|
||||
@ -179,12 +156,12 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
/* const existDb = await resolveResource('resources/default.db');
|
||||
if (!existDb) throw new Error('Keine Datenbank da');
|
||||
await copyFile(existDb, path); */
|
||||
const result = await invoke('create_encrypted_database', {
|
||||
const result = await invoke("create_encrypted_database", {
|
||||
path,
|
||||
key: password,
|
||||
});
|
||||
console.log('create_encrypted_database', result);
|
||||
return 'aaaaa'; //await openAsync({ path, password });
|
||||
console.log("create_encrypted_database", result);
|
||||
return await openAsync({ path, password });
|
||||
};
|
||||
|
||||
const closeAsync = async () => {
|
||||
@ -209,6 +186,7 @@ export const useVaultStore = defineStore('vaultStore', () => {
|
||||
openVaults,
|
||||
refreshDatabaseAsync,
|
||||
read_only,
|
||||
createTable,
|
||||
};
|
||||
});
|
||||
|
||||
@ -216,12 +194,10 @@ const getVaultIdAsync = async (path: string) => {
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(path);
|
||||
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
|
||||
const hashHex = hashArray
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join(''); // convert bytes to hex string
|
||||
console.log('vaultId', hashHex);
|
||||
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); // convert bytes to hex string
|
||||
console.log("vaultId", hashHex);
|
||||
return hashHex;
|
||||
};
|
||||
|
||||
|
||||
16
src/types/haexhub.d.ts
vendored
Normal file
16
src/types/haexhub.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
export interface IHaexHubExtensionManifest {
|
||||
name: string;
|
||||
entry: string;
|
||||
permissions: {
|
||||
database?: {
|
||||
read?: string[];
|
||||
write?: string[];
|
||||
create?: string[];
|
||||
};
|
||||
http?: string[];
|
||||
filesystem?: {
|
||||
read?: string[];
|
||||
write?: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -40,13 +40,10 @@
|
||||
const originalFetch = window.__TAURI__.http.fetch;
|
||||
window.__TAURI__.http.fetch = async function (options) {
|
||||
// Prüfe, ob die Ressource blockiert werden soll
|
||||
const shouldBlock = await window.__TAURI__.invoke(
|
||||
'block_resource_request',
|
||||
{
|
||||
url: options.url,
|
||||
resourceType: 'tauri-fetch',
|
||||
}
|
||||
);
|
||||
const shouldBlock = await invoke('block_resource_request', {
|
||||
url: options.url,
|
||||
resourceType: 'tauri-fetch',
|
||||
});
|
||||
|
||||
if (shouldBlock) {
|
||||
throw new Error(`Ressourcenanfrage blockiert: ${options.url}`);
|
||||
|
||||
Reference in New Issue
Block a user