commit f6989707f46744f856f5d7f5deb80b9b60bbbebd Author: Jesse Wierzbinski Date: Sun Apr 14 15:16:57 2024 -1000 refactor: :art: Move Lysand-FE into its own repository diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4f5ee1c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,21 @@ +node_modules +Dockerfile* +docker-compose* +.dockerignore +.git +.gitignore +README.md +LICENSE +.vscode +Makefile +helm-charts +.env +.editorconfig +.idea +coverage* +uploads +.output +.nuxt +logs +dist +pages/dist \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3a3cce5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..e79174b --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,79 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: ["main"] + pull_request: + # The branches below must be a subset of the branches above + branches: ["main"] + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: ["javascript"] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..4763492 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,136 @@ +name: Docker + +on: + push: + branches: ["main"] + tags: ["v*.*.*"] + pull_request: + branches: ["*"] + workflow_dispatch: + inputs: + tag: + description: "Tag" + required: false + default: "v0.0.0" + +env: + REGISTRY: ghcr.io + +jobs: + build: + name: Build for ${{ matrix.platform }} + runs-on: ${{ matrix.os }} + environment: + name: Production + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + platform: linux/arm64 + - os: ubuntu-latest + platform: linux/amd64 + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: build + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + name: Merge digests + runs-on: ubuntu-latest + environment: + name: Production + needs: + - build + steps: + - name: Prepare + run: | + echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_ENV + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a7f73a --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0ca9544 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM oven/bun:1.1.3 AS base +# Temporarily switch back to the non-alpine version of Bun because of Bun's issues with musl + +# Install dependencies into temp directory +# This will cache them and speed up future builds +FROM base AS install +RUN mkdir -p /temp/dev +COPY package.json bun.lockb /temp/dev/ +RUN cd /temp/dev && bun install --frozen-lockfile + +FROM base AS builder +COPY . /app + +COPY --from=install /temp/dev/node_modules /app/node_modules +RUN cd /app && bun run build + +FROM base as final + +COPY --from=builder /app/.output/ /app + +LABEL org.opencontainers.image.authors "Gaspard Wierzbinski (https://cpluspatch.com)" +LABEL org.opencontainers.image.source "https://github.com/lysand-org/lysand-fe" +LABEL org.opencontainers.image.vendor "Lysand Org" +LABEL org.opencontainers.image.licenses "AGPL-3.0" +LABEL org.opencontainers.image.title "Lysand-FE" +LABEL org.opencontainers.image.description "Frontend for the Lysand Project" + +WORKDIR /app/server +CMD ["bun", "index.mjs"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d0b0297 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# FE \ No newline at end of file diff --git a/app.vue b/app.vue new file mode 100644 index 0000000..207756e --- /dev/null +++ b/app.vue @@ -0,0 +1,13 @@ + + + \ No newline at end of file diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..b089938 --- /dev/null +++ b/biome.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.6.4/schema.json", + "organizeImports": { + "enabled": true, + "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + }, + "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + } +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..2881dfc Binary files /dev/null and b/bun.lockb differ diff --git a/components/LoginInput.vue b/components/LoginInput.vue new file mode 100644 index 0000000..a5a3ae4 --- /dev/null +++ b/components/LoginInput.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/composables/useConfig.ts b/composables/useConfig.ts new file mode 100644 index 0000000..2941b14 --- /dev/null +++ b/composables/useConfig.ts @@ -0,0 +1,19 @@ +export const useConfig = async () => { + let host = useRequestHeader("X-Forwarded-Host") ?? useRuntimeConfig().public.apiHost; + + if (!host?.includes("http")) { + // On server, this will be some kind of localhost + host = `http://${host}`; + } + + if (!host) { + throw createError({ + statusCode: 500, + statusMessage: "No X-Forwarded-Host header found", + }); + } + + return await fetch(new URL("/api/_fe/config", host)).then((res) => + res.json(), + ); +}; diff --git a/constants.ts b/constants.ts new file mode 100644 index 0000000..5ef419d --- /dev/null +++ b/constants.ts @@ -0,0 +1,12 @@ +export const recommendedClients = [ + { + name: "Soapbox", + icon: "https://soapbox.pub/assets/logo.svg", + link: "https://fe.soapbox.pub/", + }, + { + name: "Megalodon", + icon: "https://sk22.github.io/megalodon/mastodon/src/main/res/mipmap-xhdpi/ic_launcher_round.png", + link: "https://sk22.github.io/megalodon/", + }, +]; diff --git a/emails/welcome.vue b/emails/welcome.vue new file mode 100644 index 0000000..4973afc --- /dev/null +++ b/emails/welcome.vue @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts new file mode 100644 index 0000000..a81e4ac --- /dev/null +++ b/nuxt.config.ts @@ -0,0 +1,59 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + modules: [ + "@nuxtjs/seo", + "@nuxtjs/tailwindcss", + "@vueuse/nuxt", + "@vue-email/nuxt", + ], + app: { + head: { + link: [ + { + rel: "icon", + href: "/favicon.png", + type: "image/png", + }, + ], + htmlAttrs: { lang: "en-us" }, + }, + }, + nitro: { + preset: "bun", + minify: true, + prerender: { + failOnError: true, + }, + }, + devServer: { + port: 5173, + }, + schemaOrg: { + enabled: false, + }, + ogImage: { + enabled: false, + }, + vite: { + define: { + __VERSION__: JSON.stringify("0.4"), + }, + server: { + hmr: { + clientPort: 5173, + }, + }, + }, + runtimeConfig: { + public: { + language: "en-US", + titleSeparator: "·", + siteName: "Lysand", + trailingSlash: true, + apiHost: "localhost:8080", + }, + }, + site: { + url: "https://social.lysand.org", + }, +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..6ee5a82 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "c12": "^1.10.0", + "nuxt": "^3.11.2", + "vue": "^3.4.21", + "vue-router": "^4.3.0", + "shiki": "^1.2.4" + }, + "devDependencies": { + "@biomejs/biome": "^1.6.4", + "@nuxtjs/seo": "^2.0.0-rc.10", + "@nuxtjs/tailwindcss": "^6.11.4", + "@tailwindcss/forms": "^0.5.7", + "@vue-email/nuxt": "^0.8.19" + }, + "trustedDependencies": [ + "@biomejs/biome", + "@fortawesome/fontawesome-common-types", + "@fortawesome/free-regular-svg-icons", + "@fortawesome/free-solid-svg-icons", + "json-editor-vue" + ] +} diff --git a/pages/[username]/[uuid].vue b/pages/[username]/[uuid].vue new file mode 100644 index 0000000..93c1d8b --- /dev/null +++ b/pages/[username]/[uuid].vue @@ -0,0 +1,72 @@ + + + + + \ No newline at end of file diff --git a/pages/[username]/index.vue b/pages/[username]/index.vue new file mode 100644 index 0000000..29998e7 --- /dev/null +++ b/pages/[username]/index.vue @@ -0,0 +1,83 @@ + + + + + \ No newline at end of file diff --git a/pages/index.vue b/pages/index.vue new file mode 100644 index 0000000..e847fe4 --- /dev/null +++ b/pages/index.vue @@ -0,0 +1,72 @@ + + + \ No newline at end of file diff --git a/pages/oauth/authorize.vue b/pages/oauth/authorize.vue new file mode 100644 index 0000000..c4fc7e6 --- /dev/null +++ b/pages/oauth/authorize.vue @@ -0,0 +1,114 @@ + + + \ No newline at end of file diff --git a/pages/oauth/redirect.vue b/pages/oauth/redirect.vue new file mode 100644 index 0000000..1647834 --- /dev/null +++ b/pages/oauth/redirect.vue @@ -0,0 +1,175 @@ + + + \ No newline at end of file diff --git a/pages/register/index.vue b/pages/register/index.vue new file mode 100644 index 0000000..562fede --- /dev/null +++ b/pages/register/index.vue @@ -0,0 +1,176 @@ +