diff --git a/.env.example b/.env.example index aa43c6e..6b33689 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,8 @@ NODE_ENV=production HOST=0.0.0.0 PORT=4321 +# Optional application base path (use "/" for root, or "/mirror" for subpath deployments) +BASE_URL=/ # Database Configuration # For self-hosted, SQLite is used by default @@ -31,6 +33,12 @@ BETTER_AUTH_URL=http://localhost:4321 # PUBLIC_BETTER_AUTH_URL=https://gitea-mirror.example.com # BETTER_AUTH_TRUSTED_ORIGINS=https://gitea-mirror.example.com # +# If your app is served from a path prefix (e.g. https://git.example.com/mirror), set: +# BASE_URL=/mirror +# BETTER_AUTH_URL=https://git.example.com +# PUBLIC_BETTER_AUTH_URL=https://git.example.com +# BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com +# # BETTER_AUTH_URL - Used server-side for auth callbacks and redirects # PUBLIC_BETTER_AUTH_URL - Used client-side (browser) for auth API calls # BETTER_AUTH_TRUSTED_ORIGINS - Comma-separated list of origins allowed to make auth requests diff --git a/Dockerfile b/Dockerfile index f809791..3214a06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,8 @@ RUN apt-get update && apt-get -y upgrade && apt-get install -y --no-install-reco # ---------------------------- FROM base AS builder +ARG BASE_URL=/ +ENV BASE_URL=${BASE_URL} COPY package.json ./ COPY bun.lock* ./ RUN bun install --frozen-lockfile @@ -73,6 +75,7 @@ ENV NODE_ENV=production ENV HOST=0.0.0.0 ENV PORT=4321 ENV DATABASE_URL=file:data/gitea-mirror.db +ENV BASE_URL=/ # Create directories and setup permissions RUN mkdir -p /app/certs && \ @@ -90,6 +93,6 @@ VOLUME /app/data EXPOSE 4321 HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ - CMD wget --no-verbose --tries=1 --spider http://localhost:4321/api/health || exit 1 + CMD sh -c 'BASE="${BASE_URL:-/}"; if [ "$BASE" = "/" ]; then BASE=""; else BASE="${BASE%/}"; fi; wget --no-verbose --tries=1 --spider "http://localhost:4321${BASE}/api/health" || exit 1' ENTRYPOINT ["./docker-entrypoint.sh"] diff --git a/README.md b/README.md index 75276df..c7ac38e 100644 --- a/README.md +++ b/README.md @@ -300,7 +300,19 @@ CLEANUP_DRY_RUN=false # Set to true to test without changes ### Reverse Proxy Configuration -If using a reverse proxy (e.g., nginx proxy manager) and experiencing issues with JavaScript files not loading properly, try enabling HTTP/2 support in your proxy configuration. While not required by the application, some proxy configurations may have better compatibility with HTTP/2 enabled. See [issue #43](https://github.com/RayLabsHQ/gitea-mirror/issues/43) for reference. +If you run behind a reverse proxy on a subpath (for example `https://git.example.com/mirror`), configure: + +```bash +BASE_URL=/mirror +BETTER_AUTH_URL=https://git.example.com +PUBLIC_BETTER_AUTH_URL=https://git.example.com +BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com +``` + +Notes: +- `BASE_URL` sets the application path prefix. +- `BETTER_AUTH_TRUSTED_ORIGINS` should contain origins only (no path). +- When building Docker images, pass `BASE_URL` at build time as well. ### Mirror Token Rotation (GitHub Token Changed) diff --git a/astro.config.mjs b/astro.config.mjs index 293315f..2aec23c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -4,8 +4,25 @@ import tailwindcss from '@tailwindcss/vite'; import react from '@astrojs/react'; import node from '@astrojs/node'; +const normalizeBaseUrl = (value) => { + if (!value || value.trim() === '') { + return '/'; + } + + let normalized = value.trim(); + if (!normalized.startsWith('/')) { + normalized = `/${normalized}`; + } + + normalized = normalized.replace(/\/+$/, ''); + return normalized || '/'; +}; + +const base = normalizeBaseUrl(process.env.BASE_URL); + // https://astro.build/config export default defineConfig({ + base, output: 'server', adapter: node({ mode: 'standalone', diff --git a/docker-compose.alt.yml b/docker-compose.alt.yml index 296bfba..3631a75 100644 --- a/docker-compose.alt.yml +++ b/docker-compose.alt.yml @@ -22,6 +22,8 @@ services: # BETTER_AUTH_URL=https://gitea-mirror.example.com # PUBLIC_BETTER_AUTH_URL=https://gitea-mirror.example.com # BETTER_AUTH_TRUSTED_ORIGINS=https://gitea-mirror.example.com + # NOTE: Path-prefix deployments (e.g. /mirror) require BASE_URL at build time. + # Use docker-compose.yml (which builds from source) and set BASE_URL there. # === CORE SETTINGS === # These are technically required but have working defaults @@ -29,6 +31,7 @@ services: - DATABASE_URL=file:data/gitea-mirror.db - HOST=0.0.0.0 - PORT=4321 + - BASE_URL=${BASE_URL:-/} - PUBLIC_BETTER_AUTH_URL=${PUBLIC_BETTER_AUTH_URL:-http://localhost:4321} # Optional concurrency controls (defaults match in-app defaults) # If you want perfect ordering of issues and PRs, set these at 1 @@ -36,7 +39,11 @@ services: - MIRROR_PULL_REQUEST_CONCURRENCY=${MIRROR_PULL_REQUEST_CONCURRENCY:-5} healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=3", "--spider", "http://localhost:4321/api/health"] + test: + [ + "CMD-SHELL", + "BASE=\"${BASE_URL:-/}\"; if [ \"$${BASE}\" = \"/\" ]; then BASE=\"\"; else BASE=\"$${BASE%/}\"; fi; wget --no-verbose --tries=3 --spider \"http://localhost:4321$${BASE}/api/health\"", + ] interval: 30s timeout: 10s retries: 5 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b7b97d5..0c50d4b 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -45,6 +45,8 @@ services: build: context: . dockerfile: Dockerfile + args: + BASE_URL: ${BASE_URL:-/} platforms: - linux/amd64 - linux/arm64 @@ -66,6 +68,7 @@ services: - DATABASE_URL=file:data/gitea-mirror.db - HOST=0.0.0.0 - PORT=4321 + - BASE_URL=${BASE_URL:-/} - BETTER_AUTH_SECRET=dev-secret-key # GitHub/Gitea Mirror Config - GITHUB_USERNAME=${GITHUB_USERNAME:-your-github-username} @@ -89,7 +92,11 @@ services: # Optional: Skip TLS verification (insecure, use only for testing) # - GITEA_SKIP_TLS_VERIFY=${GITEA_SKIP_TLS_VERIFY:-false} healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4321/api/health"] + test: + [ + "CMD-SHELL", + "BASE=\"${BASE_URL:-/}\"; if [ \"$${BASE}\" = \"/\" ]; then BASE=\"\"; else BASE=\"$${BASE%/}\"; fi; wget --no-verbose --tries=1 --spider \"http://localhost:4321$${BASE}/api/health\"", + ] interval: 30s timeout: 5s retries: 3 diff --git a/docker-compose.yml b/docker-compose.yml index c278b44..ee4533b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,8 @@ services: build: context: . dockerfile: Dockerfile + args: + BASE_URL: ${BASE_URL:-/} platforms: - linux/amd64 - linux/arm64 @@ -30,6 +32,7 @@ services: - DATABASE_URL=file:data/gitea-mirror.db - HOST=0.0.0.0 - PORT=4321 + - BASE_URL=${BASE_URL:-/} - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your-secret-key-change-this-in-production} - BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:4321} # REVERSE PROXY: If you access Gitea Mirror through a reverse proxy (e.g. Nginx, Caddy, Traefik), @@ -37,6 +40,11 @@ services: # BETTER_AUTH_URL=https://gitea-mirror.example.com # PUBLIC_BETTER_AUTH_URL=https://gitea-mirror.example.com # BETTER_AUTH_TRUSTED_ORIGINS=https://gitea-mirror.example.com + # If deployed under a path prefix (e.g. https://git.example.com/mirror), also set: + # BASE_URL=/mirror + # BETTER_AUTH_URL=https://git.example.com + # PUBLIC_BETTER_AUTH_URL=https://git.example.com + # BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com - PUBLIC_BETTER_AUTH_URL=${PUBLIC_BETTER_AUTH_URL:-http://localhost:4321} - BETTER_AUTH_TRUSTED_ORIGINS=${BETTER_AUTH_TRUSTED_ORIGINS:-} # Optional: ENCRYPTION_SECRET will be auto-generated if not provided @@ -81,7 +89,11 @@ services: - HEADER_AUTH_AUTO_PROVISION=${HEADER_AUTH_AUTO_PROVISION:-false} - HEADER_AUTH_ALLOWED_DOMAINS=${HEADER_AUTH_ALLOWED_DOMAINS:-} healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=3", "--spider", "http://localhost:4321/api/health"] + test: + [ + "CMD-SHELL", + "BASE=\"${BASE_URL:-/}\"; if [ \"$${BASE}\" = \"/\" ]; then BASE=\"\"; else BASE=\"$${BASE%/}\"; fi; wget --no-verbose --tries=3 --spider \"http://localhost:4321$${BASE}/api/health\"", + ] interval: 30s timeout: 10s retries: 5 diff --git a/docs/ENVIRONMENT_VARIABLES.md b/docs/ENVIRONMENT_VARIABLES.md index 6a83963..a6d8a6d 100644 --- a/docs/ENVIRONMENT_VARIABLES.md +++ b/docs/ENVIRONMENT_VARIABLES.md @@ -33,6 +33,7 @@ Essential application settings required for running Gitea Mirror. | `NODE_ENV` | Application environment | `production` | No | | `HOST` | Server host binding | `0.0.0.0` | No | | `PORT` | Server port | `4321` | No | +| `BASE_URL` | Application base path. Use `/` for root deployments, or a prefix such as `/mirror` when serving behind a reverse-proxy path prefix. | `/` | No | | `DATABASE_URL` | Database connection URL | `sqlite://data/gitea-mirror.db` | No | | `BETTER_AUTH_SECRET` | Secret key for session signing (generate with: `openssl rand -base64 32`) | - | Yes | | `BETTER_AUTH_URL` | Primary base URL for authentication. This should be the main URL where your application is accessed. | `http://localhost:4321` | No | @@ -302,6 +303,7 @@ services: environment: # Core Configuration - NODE_ENV=production + - BASE_URL=/ - DATABASE_URL=file:data/gitea-mirror.db - BETTER_AUTH_SECRET=your-secure-secret-here # Primary access URL: @@ -370,6 +372,21 @@ This setup allows you to: **Important:** When accessing from different origins (IP vs domain), you'll need to log in separately on each origin as cookies cannot be shared across different origins for security reasons. +### Path Prefix Deployments + +If you serve Gitea Mirror under a subpath such as `https://git.example.com/mirror`, set: + +```bash +BASE_URL=/mirror +BETTER_AUTH_URL=https://git.example.com +PUBLIC_BETTER_AUTH_URL=https://git.example.com +BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com +``` + +Notes: +- `BETTER_AUTH_TRUSTED_ORIGINS` must contain origins only (no path). +- `BASE_URL` is applied at build time, so set it for image builds too. + ### Trusted Origins The `BETTER_AUTH_TRUSTED_ORIGINS` variable serves multiple purposes: diff --git a/src/components/NotFound.tsx b/src/components/NotFound.tsx index 8dee1cb..4e63ea2 100644 --- a/src/components/NotFound.tsx +++ b/src/components/NotFound.tsx @@ -1,6 +1,7 @@ import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Home, ArrowLeft, GitBranch, BookOpen, Settings, FileQuestion } from "lucide-react"; +import { withBase } from "@/lib/base-path"; export function NotFound() { return ( @@ -21,7 +22,7 @@ export function NotFound() { {/* Action Buttons */}
@@ -27,7 +28,7 @@ export function RecentActivity({ activities }: RecentActivityProps) {

@@ -54,7 +55,7 @@ export function RepositoryList({ repositories }: RepositoryListProps) { Configure your GitHub connection to start mirroring repositories.

) : ( diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 0cb44a7..acfae13 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -14,6 +14,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { withBase } from "@/lib/base-path"; interface HeaderProps { currentPage?: "dashboard" | "repositories" | "organizations" | "configuration" | "activity-log"; @@ -101,14 +102,14 @@ export function Header({ currentPage, onNavigate, onMenuClick, onToggleCollapse, )}
diff --git a/src/components/layout/MainLayout.tsx b/src/components/layout/MainLayout.tsx index 0582547..6530f25 100644 --- a/src/components/layout/MainLayout.tsx +++ b/src/components/layout/MainLayout.tsx @@ -11,6 +11,7 @@ import { Toaster } from "@/components/ui/sonner"; import { useAuth } from "@/hooks/useAuth"; import { useRepoSync } from "@/hooks/useSyncRepo"; import { useConfigStatus } from "@/hooks/useConfigStatus"; +import { stripBasePath, withBase } from "@/lib/base-path"; // Navigation context to signal when navigation happens const NavigationContext = createContext<{ navigationKey: number }>({ navigationKey: 0 }); @@ -71,7 +72,7 @@ function AppWithProviders({ page: initialPage }: AppProps) { // Handle browser back/forward navigation useEffect(() => { const handlePopState = () => { - const path = window.location.pathname; + const path = stripBasePath(window.location.pathname); const pageMap: Record = { '/': 'dashboard', '/repositories': 'repositories', @@ -125,7 +126,7 @@ function AppWithProviders({ page: initialPage }: AppProps) { if (!authLoading && !user) { // Use window.location for client-side redirect if (typeof window !== 'undefined') { - window.location.href = '/login'; + window.location.href = withBase('/login'); } return null; } diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 5af231c..344f97f 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -9,6 +9,7 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; +import { stripBasePath, withBase } from "@/lib/base-path"; interface SidebarProps { className?: string; @@ -24,14 +25,14 @@ export function Sidebar({ className, onNavigate, isOpen, isCollapsed = false, on useEffect(() => { // Hydration happens here - const path = window.location.pathname; + const path = stripBasePath(window.location.pathname); setCurrentPath(path); }, []); // Listen for URL changes (browser back/forward) useEffect(() => { const handlePopState = () => { - setCurrentPath(window.location.pathname); + setCurrentPath(stripBasePath(window.location.pathname)); }; window.addEventListener('popstate', handlePopState); @@ -45,7 +46,7 @@ export function Sidebar({ className, onNavigate, isOpen, isCollapsed = false, on if (currentPath === href) return; // Update URL without page reload - window.history.pushState({}, '', href); + window.history.pushState({}, '', withBase(href)); setCurrentPath(href); // Map href to page name for the parent component @@ -163,7 +164,7 @@ export function Sidebar({ className, onNavigate, isOpen, isCollapsed = false, on Check out the documentation for help with setup and configuration.

{ // Call API to update organization destination - const response = await fetch(`/api/organizations/${orgId}`, { + const response = await fetch(`${withBase("/api/organizations")}/${orgId}`, { method: "PATCH", headers: { "Content-Type": "application/json", @@ -189,7 +190,7 @@ export function OrganizationList({
{org.name} @@ -264,7 +265,7 @@ export function OrganizationList({
{org.name} diff --git a/src/components/repositories/Repository.tsx b/src/components/repositories/Repository.tsx index 4d366ee..a2caadc 100644 --- a/src/components/repositories/Repository.tsx +++ b/src/components/repositories/Repository.tsx @@ -50,6 +50,7 @@ import AddRepositoryDialog from "./AddRepositoryDialog"; import { useLiveRefresh } from "@/hooks/useLiveRefresh"; import { useConfigStatus } from "@/hooks/useConfigStatus"; import { useNavigation } from "@/components/layout/MainLayout"; +import { withBase } from "@/lib/base-path"; const REPOSITORY_SORT_OPTIONS = [ { value: "imported-desc", label: "Recently Imported" }, @@ -1518,7 +1519,7 @@ export default function Repository() { @@ -44,4 +45,4 @@ const errorDescription = Astro.url.searchParams.get('error_description');
- \ No newline at end of file + diff --git a/src/pages/config.astro b/src/pages/config.astro index 59fda44..dd63982 100644 --- a/src/pages/config.astro +++ b/src/pages/config.astro @@ -7,13 +7,14 @@ import { db, configs } from '@/lib/db'; import ThemeScript from '@/components/theme/ThemeScript.astro'; import { Button } from '@/components/ui/button'; import type { SaveConfigApiRequest,SaveConfigApiResponse } from '@/types/config'; +import { withBase } from '@/lib/base-path'; --- - + Configuration - Gitea Mirror diff --git a/src/pages/docs/advanced.astro b/src/pages/docs/advanced.astro index ad4895b..ff9302f 100644 --- a/src/pages/docs/advanced.astro +++ b/src/pages/docs/advanced.astro @@ -1,12 +1,13 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; ---
+
+
{`# If deployed under a path prefix (example: /mirror):
+BASE_URL=/mirror
+BETTER_AUTH_URL=https://git.example.com
+PUBLIC_BETTER_AUTH_URL=https://git.example.com
+BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com`}
    +
  • BASE_URL — Application base path for path-prefix deployments (e.g. /mirror)
  • BETTER_AUTH_URL — Server-side auth base URL for callbacks and redirects
  • PUBLIC_BETTER_AUTH_URL — Client-side (browser) URL for auth API calls
  • BETTER_AUTH_TRUSTED_ORIGINS — Comma-separated origins allowed to make auth requests
  • @@ -243,9 +253,10 @@ BETTER_AUTH_TRUSTED_ORIGINS=https://gitea-mirror.example.com`} image: ghcr.io/raylabshq/gitea-mirror:latest environment: - BETTER_AUTH_SECRET=your-secret-key-min-32-chars - - BETTER_AUTH_URL=https://gitea-mirror.example.com - - PUBLIC_BETTER_AUTH_URL=https://gitea-mirror.example.com - - BETTER_AUTH_TRUSTED_ORIGINS=https://gitea-mirror.example.com + - BASE_URL=/mirror + - BETTER_AUTH_URL=https://git.example.com + - PUBLIC_BETTER_AUTH_URL=https://git.example.com + - BETTER_AUTH_TRUSTED_ORIGINS=https://git.example.com # ... other settings ...`} @@ -509,4 +520,4 @@ ls -t "$BACKUP_DIR"/backup_*.tar.gz | tail -n +8 | xargs rm -f`}
- \ No newline at end of file + diff --git a/src/pages/docs/architecture.astro b/src/pages/docs/architecture.astro index 27c010b..087a6a7 100644 --- a/src/pages/docs/architecture.astro +++ b/src/pages/docs/architecture.astro @@ -1,12 +1,13 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; ---
Back to Documentation diff --git a/src/pages/docs/authentication.astro b/src/pages/docs/authentication.astro index d87ef96..4de4afe 100644 --- a/src/pages/docs/authentication.astro +++ b/src/pages/docs/authentication.astro @@ -1,12 +1,13 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; ---
Back to Documentation diff --git a/src/pages/docs/ca-certificates.astro b/src/pages/docs/ca-certificates.astro index 3553867..9078547 100644 --- a/src/pages/docs/ca-certificates.astro +++ b/src/pages/docs/ca-certificates.astro @@ -1,12 +1,13 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; ---
Back to Documentation diff --git a/src/pages/docs/configuration.astro b/src/pages/docs/configuration.astro index 2b1a8ab..9dc2bd7 100644 --- a/src/pages/docs/configuration.astro +++ b/src/pages/docs/configuration.astro @@ -1,8 +1,10 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; const envVars = [ { name: 'NODE_ENV', desc: 'Runtime environment', default: 'development', example: 'production' }, + { name: 'BASE_URL', desc: 'Application base path', default: '/', example: '/mirror' }, { name: 'DATABASE_URL', desc: 'SQLite database URL', default: 'file:data/gitea-mirror.db', example: 'file:path/to/database.db' }, { name: 'JWT_SECRET', desc: 'Secret key for JWT auth', default: 'Auto-generated', example: 'your-secure-string' }, { name: 'HOST', desc: 'Server host', default: 'localhost', example: '0.0.0.0' }, @@ -35,7 +37,7 @@ const giteaOptions = [
- \ No newline at end of file + diff --git a/src/pages/docs/index.astro b/src/pages/docs/index.astro index e20edbc..5db1243 100644 --- a/src/pages/docs/index.astro +++ b/src/pages/docs/index.astro @@ -1,6 +1,7 @@ --- import MainLayout from '../../layouts/main.astro'; import { LuSettings, LuRocket, LuBookOpen, LuShield, LuKey, LuNetwork } from 'react-icons/lu'; +import { withBase } from '@/lib/base-path'; // Define our documentation pages directly const docs = [ @@ -69,7 +70,7 @@ const sortedDocs = docs.sort((a, b) => a.order - b.order); return ( @@ -85,4 +86,4 @@ const sortedDocs = docs.sort((a, b) => a.order - b.order); })}
- \ No newline at end of file + diff --git a/src/pages/docs/quickstart.astro b/src/pages/docs/quickstart.astro index 2193f7d..c541a83 100644 --- a/src/pages/docs/quickstart.astro +++ b/src/pages/docs/quickstart.astro @@ -1,12 +1,13 @@ --- import MainLayout from '../../layouts/main.astro'; +import { withBase } from '@/lib/base-path'; ---
Back to Documentation @@ -418,11 +419,11 @@ bun run start
📖 - Check out the Configuration Guide for advanced settings + Check out the Configuration Guide for advanced settings
🏗️ - Review the Architecture Documentation to understand the system + Review the Architecture Documentation to understand the system
📊 @@ -434,4 +435,4 @@ bun run start
- \ No newline at end of file + diff --git a/src/pages/index.astro b/src/pages/index.astro index f316b01..22630c1 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -4,6 +4,7 @@ import App from '@/components/layout/MainLayout'; import { db, repositories, mirrorJobs, users } from '@/lib/db'; import { sql } from 'drizzle-orm'; import ThemeScript from '@/components/theme/ThemeScript.astro'; +import { withBase } from '@/lib/base-path'; // Check if any users exist in the database const userCountResult = await db.select({ count: sql`count(*)` }).from(users); @@ -11,7 +12,7 @@ const userCount = userCountResult[0]?.count || 0; // Redirect to signup if no users exist if (userCount === 0) { - return Astro.redirect('/signup'); + return Astro.redirect(withBase('/signup')); } // Fetch data from the database @@ -59,7 +60,7 @@ try { - + Dashboard - Gitea Mirror diff --git a/src/pages/login.astro b/src/pages/login.astro index e27a6db..fc6535c 100644 --- a/src/pages/login.astro +++ b/src/pages/login.astro @@ -4,6 +4,7 @@ import ThemeScript from '@/components/theme/ThemeScript.astro'; import { LoginPage } from '@/components/auth/LoginPage'; import { db, users } from '@/lib/db'; import { sql } from 'drizzle-orm'; +import { withBase } from '@/lib/base-path'; // Check if any users exist in the database const userCountResult = await db @@ -13,7 +14,7 @@ const userCount = userCountResult[0].count; // Redirect to signup if no users exist if (userCount === 0) { - return Astro.redirect('/signup'); + return Astro.redirect(withBase('/signup')); } const generator = Astro.generator; @@ -23,7 +24,7 @@ const generator = Astro.generator; - + Login - Gitea Mirror diff --git a/src/pages/oauth/consent.astro b/src/pages/oauth/consent.astro index c741944..a9406d9 100644 --- a/src/pages/oauth/consent.astro +++ b/src/pages/oauth/consent.astro @@ -3,11 +3,12 @@ import '@/styles/global.css'; import ConsentPage from '@/components/oauth/ConsentPage'; import ThemeScript from '@/components/theme/ThemeScript.astro'; import Providers from '@/components/layout/Providers'; +import { withBase } from '@/lib/base-path'; // Check if user is authenticated const sessionCookie = Astro.cookies.get('better-auth-session'); if (!sessionCookie) { - return Astro.redirect('/login'); + return Astro.redirect(withBase('/login')); } --- @@ -15,7 +16,7 @@ if (!sessionCookie) { - + Authorize Application - Gitea Mirror @@ -25,4 +26,4 @@ if (!sessionCookie) { - \ No newline at end of file + diff --git a/src/pages/organizations.astro b/src/pages/organizations.astro index de2b450..d283703 100644 --- a/src/pages/organizations.astro +++ b/src/pages/organizations.astro @@ -2,6 +2,7 @@ import '../styles/global.css'; import App from '@/components/layout/MainLayout'; import ThemeScript from '@/components/theme/ThemeScript.astro'; +import { withBase } from '@/lib/base-path'; --- @@ -9,7 +10,7 @@ import ThemeScript from '@/components/theme/ThemeScript.astro'; - + Organizations - Gitea Mirror diff --git a/src/pages/repositories.astro b/src/pages/repositories.astro index 1888473..088322f 100644 --- a/src/pages/repositories.astro +++ b/src/pages/repositories.astro @@ -2,13 +2,14 @@ import '../styles/global.css'; import App from '@/components/layout/MainLayout'; import ThemeScript from '@/components/theme/ThemeScript.astro'; +import { withBase } from '@/lib/base-path'; --- - + Repositories - Gitea Mirror diff --git a/src/pages/signup.astro b/src/pages/signup.astro index 3dcfc4c..8f4786b 100644 --- a/src/pages/signup.astro +++ b/src/pages/signup.astro @@ -4,6 +4,7 @@ import ThemeScript from '@/components/theme/ThemeScript.astro'; import { SignupPage } from '@/components/auth/SignupPage'; import { db, users } from '@/lib/db'; import { sql } from 'drizzle-orm'; +import { withBase } from '@/lib/base-path'; // Check if any users exist in the database const userCountResult = await db @@ -13,7 +14,7 @@ const userCount = userCountResult[0]?.count; // Redirect to login if users already exist if (userCount !== null && Number(userCount) > 0) { - return Astro.redirect('/login'); + return Astro.redirect(withBase('/login')); } const generator = Astro.generator; @@ -23,7 +24,7 @@ const generator = Astro.generator; - + Setup Admin Account - Gitea Mirror