diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 86fecb34..ecda93be 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -33,7 +33,7 @@ module.exports = { code: 90, comments: 140, tabWidth: 2, - ignorePattern: '^import .* |.*LL\\..*|.*d=.*', + ignorePattern: '^(import .* |.*LL\\..*|.*d=.*|.*from \')', ignoreComments: true, ignoreRegExpLiterals: true, ignoreTemplateLiterals: true, diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..73536140 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +* text eol=lf diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..2d338291 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,16 @@ +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: Breaking Changes 🛠+ labels: + - Semver-Major + - breaking-change + - title: Exciting New Features 🎉 + labels: + - Semver-Minor + - enhancement + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..bf9cdebc --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,51 @@ +name: 'lint' + +on: + push: + branches: + - main + - dev + + pull_request: + branches: + - main + - dev + +jobs: + lint-web: + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - uses: actions/setup-node@v3 + with: + node-version: '20' + + - uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-lint-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-lint-store- + + - name: Install deps + run: pnpm install --frozen-lockfile + + - name: Run Eslint and Prettier Lint + run: pnpm lint + + - name: Check TSC + run: pnpm tsc diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..aced5034 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,275 @@ +name: "Build app & create release" + +on: + push: + tags: + - v*.*.* + +jobs: + build-wireguard-go: + strategy: + fail-fast: false + matrix: + architecture: [arm64, amd64] + + runs-on: [self-hosted, macOS] + + steps: + - uses: actions/checkout@v4 + with: + repository: WireGuard/wireguard-go + ref: master + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + - name: Build wireguard-go binary + run: make + env: + GOOS: darwin + GOARCH: ${{ matrix.architecture }} + - name: Upload binary artifact arm64 + if: matrix.architecture == 'arm64' + uses: actions/upload-artifact@v3 + with: + name: wireguard-go-aarch64-apple-darwin + path: wireguard-go + - name: Upload binary artifact amd64 + if: matrix.architecture == 'amd64' + uses: actions/upload-artifact@v3 + with: + name: wireguard-go-x86_64-apple-darwin + path: wireguard-go + + create-release: + name: create-release + runs-on: self-hosted + outputs: + upload_url: ${{ steps.release.outputs.upload_url }} + steps: + - name: Create GitHub release + id: release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + draft: true + generate_release_notes: true + + build-linux: + needs: + - create-release + + runs-on: + - self-hosted + - Linux + + steps: + - uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: Write release version + run: | + VERSION=$(echo ${GITHUB_REF_NAME#v} | cut -d '-' -f1) + echo Version: $VERSION + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - uses: actions/setup-node@v3 + with: + node-version: "20" + + - uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-build-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-build-store- + + - name: Install deps + run: pnpm install --frozen-lockfile + - uses: dtolnay/rust-toolchain@stable + + - name: install linux deps + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev unzip + + - name: install protobuf compiler + run: | + PB_REL='https://github.com/protocolbuffers/protobuf/releases' + PB_VERSION='3.20.0' && curl -LO $PB_REL/download/v$PB_VERSION/protoc-$PB_VERSION-linux-x86_64.zip + sudo unzip protoc-$PB_VERSION-linux-x86_64.zip bin/protoc include/google/* -d /usr/local + + - name: Build packages + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload DEB + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: src-tauri/target/release/bundle/deb/defguard-client_${{ env.VERSION }}_amd64.deb + asset_name: defguard-client_${{ env.VERSION }}_amd64.deb + asset_content_type: application/octet-stream + + - name: Upload AppImage + if: matrix.platform == 'Linux' + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: src-tauri/target/release/bundle/appimage/defguard-client_${{ env.VERSION }}_amd64.AppImage + asset_name: defguard-client_${{ env.VERSION }}_amd64.AppImage + asset_content_type: application/octet-stream + + - name: Rename client binary + run: mv src-tauri/target/release/defguard-client defguard-client-linux-x86_64-${{ github.ref_name }} + + - name: Tar client binary + uses: a7ul/tar-action@v1.1.0 + with: + command: c + files: | + defguard-client-linux-x86_64-${{ github.ref_name }} + outPath: defguard-client-linux-x86_64-${{ github.ref_name }}.tar.gz + + - name: Upload client archive + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: defguard-client-linux-x86_64-${{ github.ref_name }}.tar.gz + asset_name: defguard-client-linux-x86_64-${{ github.ref_name }}.tar.gz + asset_content_type: application/octet-stream + + - name: Rename daemon binary + run: mv src-tauri/target/release/defguard-service defguard-service-linux-x86_64-${{ github.ref_name }} + + - name: Tar daemon binary + uses: a7ul/tar-action@v1.1.0 + with: + command: c + files: | + defguard-service-linux-x86_64-${{ github.ref_name }} + outPath: defguard-service-linux-x86_64-${{ github.ref_name }}.tar.gz + + - name: Upload daemon archive + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: defguard-service-linux-x86_64-${{ github.ref_name }}.tar.gz + asset_name: defguard-service-linux-x86_64-${{ github.ref_name }}.tar.gz + asset_content_type: application/octet-stream + + build-macos: + needs: + - create-release + - build-wireguard-go + + strategy: + fail-fast: false + matrix: + target: [aarch64-apple-darwin, x86_64-apple-darwin] + + runs-on: + - self-hosted + - macOS + + steps: + - uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: Write release version + run: | + VERSION=$(echo ${GITHUB_REF_NAME#v} | cut -d '-' -f1) + echo Version: $VERSION + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - uses: actions/setup-node@v3 + with: + node-version: "20" + + - uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-build-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-build-store- + + - name: Install deps + run: pnpm install --frozen-lockfile + - uses: dtolnay/rust-toolchain@stable + + - name: Install protobuf compiler + run: brew install protobuf + + - name: Install ARM target + run: rustup target add aarch64-apple-darwin + + - name: Download wireguard-go binary + uses: actions/download-artifact@v3 + with: + name: wireguard-go-${{ matrix.target }} + path: src-tauri/resources-macos/binaries/wireguard-go-${{ matrix.target }} + + - name: Unlock keychain + run: security -v unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" /Users/admin/Library/Keychains/login.keychain + + - name: Build app + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APPLE_SIGNING_IDENTITY: "Developer ID Application: TEONITE (6WD6W6WQNV)" + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_ID: "admin@teonite.com" + APPLE_PASSWORD: ${{ secrets.NOTARYTOOL_APP_SPECIFIC_PASSWORD }} + APPLE_TEAM_ID: "6WD6W6WQNV" + with: + args: --target ${{ matrix.target }} -v + + - name: Build installation package + run: | + bash build-macos-package.sh src-tauri/target/${{ matrix.target }} src-tauri/resources-macos/scripts "Developer ID Installer: TEONITE (6WD6W6WQNV)" /Users/admin/Library/Keychains/login.keychain + xcrun notarytool submit --wait --apple-id admin@teonite.com --password ${{ secrets.NOTARYTOOL_APP_SPECIFIC_PASSWORD }} --team-id 6WD6W6WQNV src-tauri/target/${{ matrix.target }}/product-signed/defguard.pkg + xcrun stapler staple src-tauri/target/${{ matrix.target }}/product-signed/defguard.pkg + + - name: Upload installation package + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: src-tauri/target/${{ matrix.target }}/product-signed/defguard.pkg + asset_name: defguard-${{ matrix.target }}-${{ env.VERSION }}.pkg + asset_content_type: application/octet-stream diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..be37ad8e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,53 @@ +name: Test backend + +on: + push: + branches: + - main + - dev + paths-ignore: + - "*.md" + - "LICENSE" + pull_request: + branches: + - main + - dev + paths-ignore: + - "*.md" + - "LICENSE" + +env: + CARGO_TERM_COLOR: always + +jobs: + test: + runs-on: [self-hosted, Linux] + container: rust:1.73 + defaults: + run: + working-directory: ./src-tauri + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Debug + run: echo ${{ github.ref_name }} + - name: Cache + uses: Swatinem/rust-cache@v2 + - name: install linux deps + run: | + apt-get update + apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev unzip + - name: install protobuf compiler + run: | + PB_REL='https://github.com/protocolbuffers/protobuf/releases' + PB_VERSION='3.20.0' && curl -LO $PB_REL/download/v$PB_VERSION/protoc-$PB_VERSION-linux-x86_64.zip + unzip protoc-$PB_VERSION-linux-x86_64.zip bin/protoc include/google/* -d /usr/local + - name: Check format + run: | + rustup component add rustfmt + cargo fmt -- --check + - name: Run tests + run: cargo test --locked --no-fail-fast diff --git a/.gitignore b/.gitignore index a547bf36..b611ef10 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ dist-ssr *.local # Editor directories and files -.vscode/* +**/.vscode/* !.vscode/extensions.json .idea .DS_Store diff --git a/.gitmodules b/.gitmodules index 3a12f3b0..5aee25bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "src/shared/defguard-ui"] path = src/shared/defguard-ui url = ../ui.git +[submodule "src-tauri/proto"] + path = src-tauri/proto + url = ../proto.git diff --git a/README.md b/README.md index 2a528fae..3aaa368e 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,21 @@ -# Defguard client frontend +# Defguard desktop client + +Desktop client for managing connection via instance of defguard. Built with tauri and React.js ## Development -### Install pnpm -```bash -npm i -g pnpm -``` -### Install dependencies +### Tauri requirements + +Make sure to install prerequisites from [tauri](https://tauri.app/v1/guides/getting-started/prerequisites/). + +### Install pnpm and node deps + ```bash pnpm install ``` -### Start dev server -```bash -pnpm dev -``` -## Building -### After installing deps +### Dev server command + ```bash -pnpm build +pnpm tauri dev ``` diff --git a/build-macos-package.sh b/build-macos-package.sh new file mode 100755 index 00000000..99ed7b29 --- /dev/null +++ b/build-macos-package.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -e + +TARGET_DIRECTORY=$1 +SCRIPTS_DIRECTORY=$2 +APPLE_PACKAGE_SIGNING_IDENTITY=$3 +KEYCHAIN=$4 + +mkdir -p "${TARGET_DIRECTORY}/package" +mkdir -p "${TARGET_DIRECTORY}/product" +mkdir -p "${TARGET_DIRECTORY}/product-signed" + +APP_ROOT="${TARGET_DIRECTORY}/release/bundle/macos/defguard-client.app" + +chmod -R 755 ${APP_ROOT} + +pkgbuild \ + --analyze \ + --root ${APP_ROOT} \ + "${TARGET_DIRECTORY}/defguard-client.plist" + +PACKAGE_PATH="${TARGET_DIRECTORY}/package/defguard.pkg" + +pkgbuild \ + --identifier "net.defguard" \ + --root ${APP_ROOT} \ + --component-plist ${TARGET_DIRECTORY}/defguard-client.plist \ + --install-location "/Applications/defguard-client.app" \ + --scripts ${SCRIPTS_DIRECTORY} \ + "${PACKAGE_PATH}" + +productbuild \ + --package "${PACKAGE_PATH}" \ + "${TARGET_DIRECTORY}/product/defguard.pkg" + +productsign \ + --sign "${APPLE_PACKAGE_SIGNING_IDENTITY}" \ + --keychain "${KEYCHAIN}" \ + "${TARGET_DIRECTORY}/product/defguard.pkg" \ + "${TARGET_DIRECTORY}/product-signed/defguard.pkg" diff --git a/index.html b/index.html index 8b0b56f7..fa5d30c0 100644 --- a/index.html +++ b/index.html @@ -3,10 +3,12 @@
-