diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4a91fd7..bccd036 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,4 +33,4 @@ jobs: uses: docker/build-push-action@v5 with: push: true - tags: ${{ secrets.REGISTRY_URL }}/beammp/website:${{ github.REF_NAME }}, ${{ secrets.REGISTRY_URL }}/beammp/website:latest + tags: ${{ secrets.REGISTRY_URL }}/beammp/website:${{ github.REF_NAME }}, ${{ secrets.REGISTRY_URL }}/beammp/website:latest, ${{ secrets.REGISTRY_URL }}/beammp/website:production diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 53bcfff..420678e 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -1,4 +1,4 @@ -name: Build Docker image and push to release +name: Build Docker image and push to prerelease on: push: @@ -17,11 +17,6 @@ jobs: oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} tags: tag:ci - - name: Install registry CA certificate - run: | - sudo mkdir -p /etc/docker/certs.d/${{ secrets.REGISTRY_URL }} - echo "${{ secrets.REGISTRY_CA_CERT }}" | base64 -d | sudo tee /etc/docker/certs.d/${{ secrets.REGISTRY_URL }}/ca.crt - - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -38,4 +33,4 @@ jobs: uses: docker/build-push-action@v5 with: push: true - tags: ${{ secrets.REGISTRY_URL }}/beammp/website:${{ github.REF_NAME }}, ${{ secrets.REGISTRY_URL }}/beammp/website:dev + tags: ${{ secrets.REGISTRY_URL }}/beammp/website:${{ github.REF_NAME }}, ${{ secrets.REGISTRY_URL }}/beammp/website:latest diff --git a/.gitignore b/.gitignore index 5bf2a52..23b4ea7 100644 --- a/.gitignore +++ b/.gitignore @@ -102,7 +102,6 @@ dist # TernJS port file .tern-port -*.exe *.zip # Logs diff --git a/nginx.conf b/nginx.conf index 3362543..1382da5 100644 --- a/nginx.conf +++ b/nginx.conf @@ -9,27 +9,39 @@ server { index index.html; # Baseline security hardening for a static SPA. + # NOTE: add_header directives are NOT inherited by child location blocks that + # define their own add_header. To avoid silently dropping security headers, + # use the `expires` directive (not add_header Cache-Control) in location blocks. add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self' https://backend.beammp.com; object-src 'none'; base-uri 'self'; frame-ancestors 'none'" always; + # Installer directory: serve files directly; return 404 for anything missing. location ^~ /installer/ { - #try_files $uri =404; - try_files $uri $uri/ /index.html; + try_files $uri =404; } - location / { - # SPA fallback: serve index.html for non-file routes so Vue Router can render NotFound - try_files $uri $uri/ /index.html; - } - - # Let real 404s for assets return 404s; Vue handles route-level 404 via the SPA fallback above. - - location /static/ { - # Serve static files directly - expires max; + # Vite-hashed assets (JS, CSS, fonts, images): serve directly with a long cache. + # These files have content hashes in their names so stale cache is never an issue. + # Return 404 if a file is genuinely missing rather than silently serving index.html. + location ~* \.(js|css|woff2?|ttf|eot|svg|webp|avif|png|jpg|jpeg|gif|ico|map)$ { + try_files $uri =404; + expires 1y; access_log off; } + + # Data / download files: serve directly, no client-side cache, 404 if missing. + location ~* \.(json|txt|exe|zip)$ { + try_files $uri =404; + expires -1; + access_log off; + } + + # SPA fallback: all other paths go to index.html so Vue Router can render the + # correct view (including the NotFound page for unknown routes). + location / { + try_files $uri /index.html; + } } \ No newline at end of file diff --git a/package.json b/package.json index 494e6a1..ee22dc1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "beammp-website", "private": true, - "version": "2.4.15", + "version": "2.4.16", "type": "module", "scripts": { "dev": "vite", diff --git a/public/installer/BeamMP_Installer.exe b/public/installer/BeamMP_Installer.exe new file mode 100644 index 0000000..e3819cb Binary files /dev/null and b/public/installer/BeamMP_Installer.exe differ diff --git a/public/installer/BeamMP_Installer.msi b/public/installer/BeamMP_Installer.msi deleted file mode 100644 index 6c30f9a..0000000 Binary files a/public/installer/BeamMP_Installer.msi and /dev/null differ diff --git a/src/views/Home.vue b/src/views/Home.vue index 96a7f95..07ee60e 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -27,11 +27,11 @@ const heroImageSrc = ref(landingLq) const installerDownloadUrl = computed(() => { //const base = import.meta.env.BASE_URL || '/' /*if (base === './') { - return '/installer/BeamMP_Installer.msi' + return '/installer/BeamMP_Installer.exe' } - return `${base.replace(/\/$/, '')}/installer/BeamMP_Installer.msi` + return `${base.replace(/\/$/, '')}/installer/BeamMP_Installer.exe` */ - return 'https://github.com/BeamMP/BeamMP-Launcher/releases/download/v2.8.0/BeamMP_Installer.msi' + return 'https://github.com/BeamMP/BeamMP-Launcher/releases/download/v2.8.0/BeamMP_Installer.exe' }) onMounted(async () => {