21 Commits

Author SHA1 Message Date
4fa3515e32 Bump version to 0.1.3
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 20:21:37 +01:00
c5c30fd4c4 Fix Vite 7.x TDZ error in __vite__mapDeps with post-build script
- Add post-build script to fix Temporal Dead Zone error in generated code
- Remove debug logging from stores and composables
- Simplify init-logger plugin to essential error handling
- Fix circular store dependency in useUiStore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 20:21:12 +01:00
8c7a02a019 Sync version numbers across all package files
Update Cargo.toml and tauri.conf.json to version 0.1.2 to match package.json
2025-11-01 19:33:42 +01:00
465fe19542 Clean up unused code and dependencies
- Remove commented-out code in Rust and TypeScript files
- Remove unused npm dependencies (@tauri-apps/plugin-http, @tauri-apps/plugin-sql, fuse.js)
- Remove commented imports in nuxt.config.ts
- Remove commented dependencies in Cargo.toml
2025-11-01 19:32:34 +01:00
d2d0f8996b Fix runtime CSP error by allowing inline scripts
Added 'unsafe-inline' to script-src CSP directive to fix JavaScript
initialization errors in production builds. Nuxt's generated modules
require inline script execution.

- Fixes: "Cannot access uninitialized variable" error
- Fixes: CSP script execution blocking
- Version bump to 0.1.2
2025-11-01 19:00:36 +01:00
f727d00639 Bump version to 0.1.1 2025-11-01 17:21:10 +01:00
a946b14f69 Fix Android assets upload to correct release
Use gh CLI to upload Android APK and AAB to the tagged release.
2025-11-01 17:20:13 +01:00
471baec284 Simplify Android build: use default command for APK and AAB
tauri android build creates both APK and AAB by default.
2025-11-01 16:44:32 +01:00
8298d807f3 Fix Android build commands: use --apk and --aab flags
Changed from incorrect --bundle aab to correct --aab flag.
2025-11-01 16:34:15 +01:00
42e6459fbf Prevent duplicate builds on tag pushes
Build workflow now ignores all tags to avoid running alongside release workflow.
2025-11-01 16:06:35 +01:00
6ae87fc694 Fix Android OpenSSL build by adding NDK toolchain to PATH
Set proper CC, AR, and RANLIB environment variables for all Android targets
to enable OpenSSL cross-compilation with SQLCipher encryption.
2025-11-01 16:03:46 +01:00
f7867a5bde Restore SQLCipher encryption for Android and fix CI build
- Re-enable bundled-sqlcipher-vendored-openssl for Android
- Add NDK environment variables for OpenSSL compilation
- Install perl and make for OpenSSL build in CI
- Ensures encryption works on all platforms including Android
2025-11-01 15:39:44 +01:00
d82599f588 Fix Android build by using platform-specific rusqlite features
- Use bundled-sqlcipher-vendored-openssl for non-Android platforms
- Use bundled (standard SQLite) for Android to avoid OpenSSL compilation issues
- Resolves OpenSSL build errors on Android targets
2025-11-01 15:36:20 +01:00
72bb211a76 Fix secrets access in workflow conditional
- Move secrets to env block instead of if condition
- Use bash conditional to check if keystore is available
- Provide clear logging for signed vs unsigned builds
2025-11-01 15:28:06 +01:00
f14ce0d6ad Add Android signing configuration to Gradle
- Configure signingConfigs to read from environment variables
- Apply signing to release builds when keystore is available
- Support both signed and unsigned builds
2025-11-01 15:26:21 +01:00
af09f4524d Remove iOS builds from CI/CD workflows 2025-11-01 15:21:58 +01:00
102832675d Fix Android build commands syntax
- Change from --apk to default build (produces APK)
- Change from --aab to --bundle aab for AAB generation
2025-11-01 15:20:49 +01:00
3490de2f51 Configure Android signing and disable iOS builds
- Add optional Android signing for build workflow (unsigned for testing)
- Require Android signing for release workflow
- Disable iOS builds (commented out) until Apple Developer Account is available
2025-11-01 15:06:56 +01:00
7c3af10938 Add Android and iOS builds to CI/CD pipelines 2025-11-01 15:00:33 +01:00
5c5d0785b9 Fix pnpm version conflict in CI workflows 2025-11-01 14:48:58 +01:00
121dd9dd00 Add GitHub Actions CI/CD pipelines
- Add build pipeline for Windows, macOS, and Linux
- Add release pipeline for automated releases
- Remove CLAUDE.md from git tracking
2025-11-01 14:46:01 +01:00
23 changed files with 1507 additions and 834 deletions

228
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,228 @@
name: Build
on:
push:
branches:
- main
- develop
tags-ignore:
- '**'
pull_request:
branches:
- main
- develop
workflow_dispatch:
jobs:
build-desktop:
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
- platform: 'ubuntu-22.04'
args: ''
- platform: 'windows-latest'
args: ''
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Install dependencies (Ubuntu)
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: ${{ matrix.args }}
- name: Upload artifacts (macOS)
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v4
with:
name: macos-${{ contains(matrix.args, 'aarch64') && 'aarch64' || 'x86_64' }}
path: |
src-tauri/target/*/release/bundle/dmg/*.dmg
src-tauri/target/*/release/bundle/macos/*.app
- name: Upload artifacts (Ubuntu)
if: matrix.platform == 'ubuntu-22.04'
uses: actions/upload-artifact@v4
with:
name: linux
path: |
src-tauri/target/release/bundle/deb/*.deb
src-tauri/target/release/bundle/appimage/*.AppImage
src-tauri/target/release/bundle/rpm/*.rpm
- name: Upload artifacts (Windows)
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v4
with:
name: windows
path: |
src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/nsis/*.exe
build-android:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install Rust Android targets
run: |
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
- name: Setup NDK
uses: nttld/setup-ndk@v1
with:
ndk-version: r26d
id: setup-ndk
- name: Setup Android NDK environment for OpenSSL
run: |
echo "ANDROID_NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >> $GITHUB_ENV
echo "NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >> $GITHUB_ENV
# Add all Android toolchains to PATH for OpenSSL cross-compilation
echo "${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH
# Set CC, AR, RANLIB for each target
echo "CC_aarch64_linux_android=aarch64-linux-android24-clang" >> $GITHUB_ENV
echo "AR_aarch64_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_aarch64_linux_android=llvm-ranlib" >> $GITHUB_ENV
echo "CC_armv7_linux_androideabi=armv7a-linux-androideabi24-clang" >> $GITHUB_ENV
echo "AR_armv7_linux_androideabi=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_armv7_linux_androideabi=llvm-ranlib" >> $GITHUB_ENV
echo "CC_i686_linux_android=i686-linux-android24-clang" >> $GITHUB_ENV
echo "AR_i686_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_i686_linux_android=llvm-ranlib" >> $GITHUB_ENV
echo "CC_x86_64_linux_android=x86_64-linux-android24-clang" >> $GITHUB_ENV
echo "AR_x86_64_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_x86_64_linux_android=llvm-ranlib" >> $GITHUB_ENV
- name: Install build dependencies for OpenSSL
run: |
sudo apt-get update
sudo apt-get install -y perl make
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Setup Keystore (if secrets available)
env:
ANDROID_KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: |
if [ -n "$ANDROID_KEYSTORE" ]; then
echo "$ANDROID_KEYSTORE" | base64 -d > $HOME/keystore.jks
echo "ANDROID_KEYSTORE_PATH=$HOME/keystore.jks" >> $GITHUB_ENV
echo "ANDROID_KEYSTORE_PASSWORD=$ANDROID_KEYSTORE_PASSWORD" >> $GITHUB_ENV
echo "ANDROID_KEY_ALIAS=$ANDROID_KEY_ALIAS" >> $GITHUB_ENV
echo "ANDROID_KEY_PASSWORD=$ANDROID_KEY_PASSWORD" >> $GITHUB_ENV
echo "Keystore configured for signing"
else
echo "No keystore configured, building unsigned APK"
fi
- name: Build Android APK and AAB (unsigned if no keystore)
run: pnpm tauri android build
- name: Upload Android artifacts
uses: actions/upload-artifact@v4
with:
name: android
path: |
src-tauri/gen/android/app/build/outputs/apk/**/*.apk
src-tauri/gen/android/app/build/outputs/bundle/**/*.aab

251
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,251 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
create-release:
permissions:
contents: write
runs-on: ubuntu-22.04
outputs:
release_id: ${{ steps.create-release.outputs.release_id }}
upload_url: ${{ steps.create-release.outputs.upload_url }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Get version
run: echo "PACKAGE_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV
- name: Create release
id: create-release
uses: actions/github-script@v7
with:
script: |
const { data } = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `v${process.env.PACKAGE_VERSION}`,
name: `haex-hub v${process.env.PACKAGE_VERSION}`,
body: 'Take a look at the assets to download and install this app.',
draft: true,
prerelease: false
})
core.setOutput('release_id', data.id)
core.setOutput('upload_url', data.upload_url)
return data.id
build-desktop:
needs: create-release
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
- platform: 'ubuntu-22.04'
args: ''
- platform: 'windows-latest'
args: ''
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Install dependencies (Ubuntu)
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build and release Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseId: ${{ needs.create-release.outputs.release_id }}
args: ${{ matrix.args }}
build-android:
needs: create-release
permissions:
contents: write
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install Rust Android targets
run: |
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
- name: Setup NDK
uses: nttld/setup-ndk@v1
with:
ndk-version: r26d
id: setup-ndk
- name: Setup Android NDK environment for OpenSSL
run: |
echo "ANDROID_NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >> $GITHUB_ENV
echo "NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >> $GITHUB_ENV
# Add all Android toolchains to PATH for OpenSSL cross-compilation
echo "${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH
# Set CC, AR, RANLIB for each target
echo "CC_aarch64_linux_android=aarch64-linux-android24-clang" >> $GITHUB_ENV
echo "AR_aarch64_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_aarch64_linux_android=llvm-ranlib" >> $GITHUB_ENV
echo "CC_armv7_linux_androideabi=armv7a-linux-androideabi24-clang" >> $GITHUB_ENV
echo "AR_armv7_linux_androideabi=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_armv7_linux_androideabi=llvm-ranlib" >> $GITHUB_ENV
echo "CC_i686_linux_android=i686-linux-android24-clang" >> $GITHUB_ENV
echo "AR_i686_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_i686_linux_android=llvm-ranlib" >> $GITHUB_ENV
echo "CC_x86_64_linux_android=x86_64-linux-android24-clang" >> $GITHUB_ENV
echo "AR_x86_64_linux_android=llvm-ar" >> $GITHUB_ENV
echo "RANLIB_x86_64_linux_android=llvm-ranlib" >> $GITHUB_ENV
- name: Install build dependencies for OpenSSL
run: |
sudo apt-get update
sudo apt-get install -y perl make
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Setup Keystore (required for release)
run: |
echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 -d > $HOME/keystore.jks
echo "ANDROID_KEYSTORE_PATH=$HOME/keystore.jks" >> $GITHUB_ENV
echo "ANDROID_KEYSTORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
echo "ANDROID_KEY_ALIAS=${{ secrets.ANDROID_KEY_ALIAS }}" >> $GITHUB_ENV
echo "ANDROID_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }}" >> $GITHUB_ENV
- name: Build Android APK and AAB (signed)
run: pnpm tauri android build
- name: Upload Android artifacts to Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ github.ref_name }} \
src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk \
src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab \
--clobber
publish-release:
permissions:
contents: write
runs-on: ubuntu-22.04
needs: [create-release, build-desktop, build-android]
steps:
- name: Publish release
id: publish-release
uses: actions/github-script@v7
env:
release_id: ${{ needs.create-release.outputs.release_id }}
with:
script: |
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: process.env.release_id,
draft: false,
prerelease: false
})

View File

@ -1,13 +0,0 @@
# Verwandte Projekte
## SDK
- /home/haex/Projekte/haexhub-sdk
## Erweiterung HaexPass (Password Manager)
- /home/haex/Projekte/haex-pass
# Codingstyle
- alle asynchronen Funktionen bitte mit Async prependen

View File

@ -1,5 +1,3 @@
//import tailwindcss from '@tailwindcss/vite'
import { fileURLToPath } from 'node:url'
// https://nuxt.com/docs/api/configuration/nuxt-config
@ -31,7 +29,6 @@ export default defineNuxtConfig({
'@vueuse/nuxt',
'@nuxt/icon',
'@nuxt/eslint',
//"@nuxt/image",
'@nuxt/fonts',
'@nuxt/ui',
],
@ -125,7 +122,6 @@ export default defineNuxtConfig({
},
vite: {
//plugins: [tailwindcss()],
// Better support for Tauri CLI output
clearScreen: false,
// Enable environment variables

View File

@ -1,10 +1,10 @@
{
"name": "haex-hub",
"private": true,
"version": "0.1.0",
"version": "0.1.3",
"type": "module",
"scripts": {
"build": "nuxt build",
"build": "nuxt build && node scripts/fix-vite-mapdeps.js",
"dev": "nuxt dev",
"drizzle:generate": "drizzle-kit generate",
"drizzle:migrate": "drizzle-kit migrate",
@ -28,11 +28,9 @@
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-dialog": "^2.4.2",
"@tauri-apps/plugin-fs": "^2.4.4",
"@tauri-apps/plugin-http": "2.5.2",
"@tauri-apps/plugin-notification": "2.3.1",
"@tauri-apps/plugin-opener": "^2.5.2",
"@tauri-apps/plugin-os": "^2.3.2",
"@tauri-apps/plugin-sql": "2.3.0",
"@tauri-apps/plugin-store": "^2.4.1",
"@vueuse/components": "^13.9.0",
"@vueuse/core": "^13.9.0",
@ -40,7 +38,6 @@
"@vueuse/nuxt": "^13.9.0",
"drizzle-orm": "^0.44.7",
"eslint": "^9.38.0",
"fuse.js": "^7.1.0",
"nuxt-zod-i18n": "^1.12.1",
"swiper": "^12.0.3",
"tailwindcss": "^4.1.16",

23
pnpm-lock.yaml generated
View File

@ -41,9 +41,6 @@ importers:
'@tauri-apps/plugin-fs':
specifier: ^2.4.4
version: 2.4.4
'@tauri-apps/plugin-http':
specifier: 2.5.2
version: 2.5.2
'@tauri-apps/plugin-notification':
specifier: 2.3.1
version: 2.3.1
@ -53,9 +50,6 @@ importers:
'@tauri-apps/plugin-os':
specifier: ^2.3.2
version: 2.3.2
'@tauri-apps/plugin-sql':
specifier: 2.3.0
version: 2.3.0
'@tauri-apps/plugin-store':
specifier: ^2.4.1
version: 2.4.1
@ -77,9 +71,6 @@ importers:
eslint:
specifier: ^9.38.0
version: 9.38.0(jiti@2.6.1)
fuse.js:
specifier: ^7.1.0
version: 7.1.0
nuxt-zod-i18n:
specifier: ^1.12.1
version: 1.12.1(magicast@0.5.0)
@ -2101,9 +2092,6 @@ packages:
'@tauri-apps/plugin-fs@2.4.4':
resolution: {integrity: sha512-MTorXxIRmOnOPT1jZ3w96vjSuScER38ryXY88vl5F0uiKdnvTKKTtaEjTEo8uPbl4e3gnUtfsDVwC7h77GQLvQ==}
'@tauri-apps/plugin-http@2.5.2':
resolution: {integrity: sha512-x1mQKHSLDk4mS2S938OTeyk8L7QyLpCrKZCZcjkljGsvTvRMojCvI9SeJ1kaxc7t8xSilkC7WdId8xER9TIGLg==}
'@tauri-apps/plugin-notification@2.3.1':
resolution: {integrity: sha512-7gqgfANSREKhh35fY1L4j3TUjUdePmU735FYDqRGeIf8nMXWpcx6j4FhN9/4nYz+m0mv79DCTPLqIPTySggGgg==}
@ -2113,9 +2101,6 @@ packages:
'@tauri-apps/plugin-os@2.3.2':
resolution: {integrity: sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A==}
'@tauri-apps/plugin-sql@2.3.0':
resolution: {integrity: sha512-JYwIocfsLaDWa41LMiZWuzts7yCJR+EpZPRmgpO7Gd7XiAS9S67dKz306j/k/d9XntB0YopMRBol2OIWMschuA==}
'@tauri-apps/plugin-store@2.4.1':
resolution: {integrity: sha512-ckGSEzZ5Ii4Hf2D5x25Oqnm2Zf9MfDWAzR+volY0z/OOBz6aucPKEY0F649JvQ0Vupku6UJo7ugpGRDOFOunkA==}
@ -7770,10 +7755,6 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.9.0
'@tauri-apps/plugin-http@2.5.2':
dependencies:
'@tauri-apps/api': 2.9.0
'@tauri-apps/plugin-notification@2.3.1':
dependencies:
'@tauri-apps/api': 2.9.0
@ -7786,10 +7767,6 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.9.0
'@tauri-apps/plugin-sql@2.3.0':
dependencies:
'@tauri-apps/api': 2.9.0
'@tauri-apps/plugin-store@2.4.1':
dependencies:
'@tauri-apps/api': 2.9.0

View File

@ -0,0 +1,52 @@
#!/usr/bin/env node
/**
* Post-build script to fix the Vite 7.x TDZ error in __vite__mapDeps
* This script patches the generated JavaScript files after the build
*/
import { readdir, readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
const NUXT_DIR = join(process.cwd(), '.output/public/_nuxt')
async function fixFile(filePath) {
const content = await readFile(filePath, 'utf-8')
const fixedContent = content.replace(
/const __vite__mapDeps=\(i,m=__vite__mapDeps,/g,
'let __vite__mapDeps;__vite__mapDeps=(i,m=__vite__mapDeps,'
)
if (fixedContent !== content) {
await writeFile(filePath, fixedContent, 'utf-8')
console.log(`✓ Fixed TDZ error in ${filePath.split('/').pop()}`)
return true
}
return false
}
async function main() {
try {
const files = await readdir(NUXT_DIR)
const jsFiles = files.filter((f) => f.endsWith('.js'))
let fixedCount = 0
for (const file of jsFiles) {
const filePath = join(NUXT_DIR, file)
const fixed = await fixFile(filePath)
if (fixed) fixedCount++
}
if (fixedCount > 0) {
console.log(`\n✓ Fixed __vite__mapDeps TDZ error in ${fixedCount} file(s)`)
} else {
console.log('\n✓ No __vite__mapDeps TDZ errors found')
}
} catch (error) {
console.error('Error fixing __vite__mapDeps:', error)
process.exit(1)
}
}
main()

1156
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "haex-hub"
version = "0.1.0"
version = "0.1.3"
description = "A Tauri App"
authors = ["you"]
edition = "2021"
@ -20,14 +20,7 @@ tauri-build = { version = "2.2", features = [] }
serde = { version = "1.0.228", features = ["derive"] }
[dependencies]
rusqlite = { version = "0.37.0", features = [
"load_extension",
"bundled-sqlcipher-vendored-openssl",
"functions",
] }
#tauri-plugin-sql = { version = "2", features = ["sqlite"] }tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }#libsqlite3-sys = { version = "0.31", features = ["bundled-sqlcipher"] }
#sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite"] }
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
base64 = "0.22"
ed25519-dalek = "2.1"
fs_extra = "1.3.0"
@ -49,9 +42,15 @@ tauri-plugin-os = "2.3.2"
tauri-plugin-persisted-scope = "2.3.4"
tauri-plugin-store = "2.4.1"
thiserror = "2.0.17"
trash = "5.2.0"
ts-rs = { version = "11.1.0", features = ["serde-compat"] }
uhlc = "0.8.2"
url = "2.5.7"
uuid = { version = "1.18.1", features = ["v4"] }
zip = "6.0.0"
[target.'cfg(not(target_os = "android"))'.dependencies]
trash = "5.2.0"
rusqlite = { version = "0.37.0", features = ["load_extension", "bundled-sqlcipher-vendored-openssl", "functions"] }
[target.'cfg(target_os = "android")'.dependencies]
rusqlite = { version = "0.37.0", features = ["load_extension", "bundled-sqlcipher-vendored-openssl", "functions"] }

View File

@ -24,6 +24,23 @@ android {
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
signingConfigs {
create("release") {
val keystorePath = System.getenv("ANDROID_KEYSTORE_PATH")
val keystorePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
val keyAlias = System.getenv("ANDROID_KEY_ALIAS")
val keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
if (keystorePath != null && keystorePassword != null && keyAlias != null && keyPassword != null) {
storeFile = file(keystorePath)
storePassword = keystorePassword
this.keyAlias = keyAlias
this.keyPassword = keyPassword
}
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
@ -43,6 +60,12 @@ android {
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
// Sign with release config if available
val releaseSigningConfig = signingConfigs.getByName("release")
if (releaseSigningConfig.storeFile != null) {
signingConfig = releaseSigningConfig
}
}
}
kotlinOptions {

View File

@ -11,8 +11,6 @@ const INSERT_TRIGGER_TPL: &str = "z_crdt_{TABLE_NAME}_insert";
const UPDATE_TRIGGER_TPL: &str = "z_crdt_{TABLE_NAME}_update";
const DELETE_TRIGGER_TPL: &str = "z_crdt_{TABLE_NAME}_delete";
//const SYNC_ACTIVE_KEY: &str = "sync_active";
pub const HLC_TIMESTAMP_COLUMN: &str = "haex_timestamp";
/// Name der custom UUID-Generierungs-Funktion (registriert in database::core::open_and_init_db)

View File

@ -20,6 +20,7 @@ use std::time::UNIX_EPOCH;
use std::{fs, sync::Arc};
use tauri::{path::BaseDirectory, AppHandle, Manager, State};
use tauri_plugin_fs::FsExt;
#[cfg(not(target_os = "android"))]
use trash;
use ts_rs::TS;
@ -134,7 +135,6 @@ pub fn get_vaults_directory(app_handle: &AppHandle) -> Result<String, DatabaseEr
Ok(vaults_dir.to_string_lossy().to_string())
}
//#[serde(tag = "type", content = "details")]
#[derive(Debug, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
@ -219,6 +219,19 @@ pub fn move_vault_to_trash(
app_handle: AppHandle,
vault_name: String,
) -> Result<String, DatabaseError> {
// On Android, trash is not available, so delete permanently
#[cfg(target_os = "android")]
{
println!(
"Android platform detected, permanently deleting vault '{}'",
vault_name
);
return delete_vault(app_handle, vault_name);
}
// On non-Android platforms, try to use trash
#[cfg(not(target_os = "android"))]
{
let vault_path = get_vault_path(&app_handle, &vault_name)?;
let vault_shm_path = format!("{}-shm", vault_path);
let vault_wal_path = format!("{}-wal", vault_path);
@ -243,13 +256,14 @@ pub fn move_vault_to_trash(
vault_name
))
} else {
// Fallback: Permanent deletion (e.g., on mobile devices without trash)
// Fallback: Permanent deletion if trash fails
println!(
"Trash not available, falling back to permanent deletion for vault '{}'",
vault_name
);
delete_vault(app_handle, vault_name)
}
}
}
/// Deletes a vault database file permanently (bypasses trash)
@ -435,9 +449,6 @@ pub fn open_encrypted_database(
state: State<'_, AppState>,
) -> Result<String, DatabaseError> {
println!("Opening encrypted database vault_path: {}", vault_path);
// Vault-Pfad aus dem Namen ableiten
//let vault_path = get_vault_path(&app_handle, &vault_name)?;
println!("Resolved vault path: {}", vault_path);
if !Path::new(&vault_path).exists() {

View File

@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "haex-hub",
"version": "0.1.0",
"version": "0.1.3",
"identifier": "space.haex.hub",
"build": {
"beforeDevCommand": "pnpm dev",
@ -25,7 +25,8 @@
"'self'",
"http://tauri.localhost",
"haex-extension:",
"'wasm-unsafe-eval'"
"'wasm-unsafe-eval'",
"'unsafe-inline'"
],
"style-src": [
"'self'",

View File

@ -1,5 +1,13 @@
<template>
<UPopover v-model:open="open">
<UDrawer
v-model:open="open"
direction="right"
:title="t('launcher.title')"
:description="t('launcher.description')"
:ui="{
content: 'w-dvw max-w-md sm:max-w-fit',
}"
>
<UButton
icon="material-symbols:apps"
color="neutral"
@ -9,7 +17,8 @@
/>
<template #content>
<ul class="p-4 max-h-96 grid grid-cols-3 gap-2 overflow-scroll">
<div class="p-4 h-full overflow-y-auto">
<div class="flex flex-wrap">
<!-- All launcher items (system windows + enabled extensions, alphabetically sorted) -->
<UContextMenu
v-for="item in launcherItems"
@ -52,15 +61,20 @@
:label="extension.name"
:tooltip="`${extension.name} (${t('disabled')})`"
/>
</ul>
</div>
</div>
</template>
</UPopover>
</UDrawer>
<!-- Uninstall Confirmation Dialog -->
<UiDialogConfirm
v-model:open="showUninstallDialog"
:title="t('uninstall.confirm.title')"
:description="t('uninstall.confirm.description', { name: extensionToUninstall?.name || '' })"
:description="
t('uninstall.confirm.description', {
name: extensionToUninstall?.name || '',
})
"
:confirm-label="t('uninstall.confirm.button')"
confirm-icon="i-heroicons-trash"
@confirm="confirmUninstall"
@ -237,6 +251,9 @@ const handleDragEnd = () => {
de:
disabled: Deaktiviert
marketplace: Marketplace
launcher:
title: App Launcher
description: Wähle eine App zum Öffnen
contextMenu:
open: Öffnen
uninstall: Deinstallieren
@ -249,6 +266,9 @@ de:
en:
disabled: Disabled
marketplace: Marketplace
launcher:
title: App Launcher
description: Select an app to open
contextMenu:
open: Open
uninstall: Uninstall

View File

@ -2,6 +2,7 @@
<UiDialogConfirm
:confirm-label="t('create')"
@confirm="onCreateAsync"
:description="t('description')"
>
<UiButton
:label="t('vault.create')"
@ -55,7 +56,9 @@
<script setup lang="ts">
import { vaultSchema } from './schema'
const { t } = useI18n()
const { t } = useI18n({
useScope: 'local',
})
const vault = reactive<{
name: string
@ -118,6 +121,7 @@ de:
name: HaexVault
title: Neue {haexvault} erstellen
create: Erstellen
description: Erstelle eine neue Vault für deine Daten
en:
vault:
@ -127,4 +131,5 @@ en:
name: HaexVault
title: Create new {haexvault}
create: Create
description: Create a new vault for your data
</i18n>

View File

@ -58,7 +58,9 @@ const props = defineProps<{
path?: string
}>()
const { t } = useI18n()
const { t } = useI18n({
useScope: 'local',
})
const vault = reactive<{
name: string

View File

@ -1,27 +1,14 @@
<template>
<UModal
<UDrawer
v-model:open="localShowWindowOverview"
direction="bottom"
:title="t('modal.title')"
:description="t('modal.description')"
fullscreen
>
<template #content>
<div class="flex flex-col h-full">
<!-- Header -->
<div
class="flex items-center justify-end border-b p-2 border-gray-200 dark:border-gray-700"
>
<UButton
icon="i-heroicons-x-mark"
color="error"
variant="soft"
@click="localShowWindowOverview = false"
/>
</div>
<!-- Scrollable Content -->
<div class="flex-1 overflow-y-auto p-6 justify-center flex">
<div class="h-full overflow-y-auto p-6 justify-center flex">
<!-- Window Thumbnails Flex Layout -->
<div
v-if="windows.length > 0"
class="flex flex-wrap gap-6 justify-center-safe items-start"
@ -82,9 +69,8 @@
</p>
</div>
</div>
</div>
</template>
</UModal>
</UDrawer>
</template>
<script setup lang="ts">

View File

@ -4,11 +4,10 @@
<UButton
class="pointer-events-auto"
v-bind="{
...{ size: isSmallScreen ? 'lg' : 'md' },
...buttonProps,
...$attrs,
}"
@click="(e) => $emit('click', e)"
@click="$emit('click', $event)"
>
<template
v-for="(_, slotName) in $slots"

View File

@ -1,5 +1,5 @@
<template>
<div class="w-full h-full flex flex-col">
<div class="w-full h-dvh flex flex-col">
<UPageHeader
ref="headerEl"
as="header"
@ -25,7 +25,7 @@
variant="outline"
icon="i-bi-person-workspace"
size="lg"
:tooltip="t('header.workspaces')"
:tooltip="t('workspaces.label')"
@click="isOverviewMode = !isOverviewMode"
/>
</div>
@ -54,7 +54,7 @@
</template>
</UPageHeader>
<main class="flex-1 overflow-hidden bg-elevated flex flex-col relative">
<main class="overflow-hidden relative bg-elevated h-full">
<slot />
</main>
@ -95,7 +95,7 @@
class="mt-6"
@click="handleAddWorkspace"
icon="i-heroicons-plus"
:label="t('add')"
:label="t('workspaces.add')"
>
</UButton>
</div>
@ -142,14 +142,14 @@ de:
search:
label: Suche
header:
workspaces: Workspaces
workspaces:
label: Workspaces
add: Workspace hinzufügen
en:
search:
label: Search
header:
workspaces: Workspaces
workspaces:
label: Workspaces
add: Add Workspace
</i18n>

View File

@ -1,23 +1,10 @@
<template>
<div>
<div class="h-full">
<NuxtLayout>
<UDashboardPanel
id="inbox-1"
resizable
class=""
>
<template #body>
<div class="items-center justify-center flex relative flex-1">
<!-- <div class="absolute top-0 right-0">
<UiDropdownLocale @select="onSelectLocale" />
</div> -->
<div
class="flex flex-col justify-center items-center gap-5 max-w-3xl"
class="flex flex-col justify-center items-center gap-5 mx-auto h-full overflow-scroll"
>
<UiLogoHaexhub
class="bg-primary p-3 size-16 rounded-full shrink-0"
/>
<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"
>
@ -27,9 +14,7 @@
<UiTextGradient>Haex Hub</UiTextGradient>
</span>
<div
class="flex flex-col md:flex-row gap-4 w-full h-24 md:h-auto"
>
<div class="flex flex-col gap-4 h-24 items-stretch justify-center">
<HaexVaultCreate />
<HaexVaultOpen
@ -40,9 +25,9 @@
<div
v-show="lastVaults.length"
class="w-full"
class="max-w-md w-full sm:px-5"
>
<div class="font-thin text-sm justify-start px-2 pb-1">
<div class="font-thin text-sm pb-1 w-full">
{{ t('lastUsed') }}
</div>
@ -57,7 +42,8 @@
<UiButtonContext
variant="ghost"
color="neutral"
class="flex items-center no-underline justify-between text-nowrap text-sm md:text-base shrink w-full px-3"
size="xl"
class="flex items-center no-underline justify-between text-nowrap text-sm md:text-base shrink w-full hover:bg-default"
:context-menu-items="[
{
icon: 'mdi:trash-can-outline',
@ -107,14 +93,9 @@
<UiDialogConfirm
v-model:open="showRemoveDialog"
:title="t('remove.title')"
:description="
t('remove.description', { vaultName: vaultToBeRemoved })
"
:description="t('remove.description', { vaultName: vaultToBeRemoved })"
@confirm="onConfirmRemoveAsync"
/>
</div>
</template>
</UDashboardPanel>
</NuxtLayout>
</div>
</template>

View File

@ -9,6 +9,7 @@
v-model:open="showNewDeviceDialog"
:confirm-label="t('newDevice.save')"
:title="t('newDevice.title')"
:description="t('newDevice.setName')"
confirm-icon="mdi:content-save-outline"
@abort="showNewDeviceDialog = false"
@confirm="onSetDeviceNameAsync"

View File

@ -0,0 +1,25 @@
export default defineNuxtPlugin({
name: 'init-logger',
enforce: 'pre',
parallel: false,
setup() {
// Add global error handler for better debugging
window.addEventListener('error', (event) => {
console.error('[HaexHub] Global error caught:', {
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error,
stack: event.error?.stack,
})
})
window.addEventListener('unhandledrejection', (event) => {
console.error('[HaexHub] Unhandled rejection:', {
reason: event.reason,
promise: event.promise,
})
})
},
})

View File

@ -1,5 +1,6 @@
import { breakpointsTailwind } from '@vueuse/core'
import { broadcastContextToAllExtensions } from '~/composables/extensionMessageHandler'
import de from './de.json'
import en from './en.json'
@ -13,7 +14,6 @@ export const useUiStore = defineStore('uiStore', () => {
const { locale } = useI18n({
useScope: 'global',
})
const { platform } = useDeviceStore()
$i18n.setLocaleMessage('de', {
ui: de,
@ -62,11 +62,13 @@ export const useUiStore = defineStore('uiStore', () => {
})
// Broadcast theme and locale changes to extensions
watch([currentThemeName, locale], () => {
watch([currentThemeName, locale], async () => {
const deviceStore = useDeviceStore()
const platformValue = await deviceStore.platform
broadcastContextToAllExtensions({
theme: currentThemeName.value,
locale: locale.value,
platform,
platform: platformValue,
})
})