diff --git a/surfsense_backend/.env.example b/surfsense_backend/.env.example index fe1055c57..3ddfdd652 100644 --- a/surfsense_backend/.env.example +++ b/surfsense_backend/.env.example @@ -9,6 +9,7 @@ NEXT_FRONTEND_URL=http://localhost:3000 # Auth AUTH_TYPE=GOOGLE or LOCAL +REGISTRATION_ENABLED= TRUE or FALSE # For Google Auth Only GOOGLE_OAUTH_CLIENT_ID=924507538m GOOGLE_OAUTH_CLIENT_SECRET=GOCSV diff --git a/surfsense_backend/app/app.py b/surfsense_backend/app/app.py index 17f908247..8c7c53db7 100644 --- a/surfsense_backend/app/app.py +++ b/surfsense_backend/app/app.py @@ -1,6 +1,6 @@ from contextlib import asynccontextmanager -from fastapi import Depends, FastAPI +from fastapi import Depends, FastAPI, HTTPException, status from fastapi.middleware.cors import CORSMiddleware from sqlalchemy.ext.asyncio import AsyncSession @@ -18,6 +18,14 @@ async def lifespan(app: FastAPI): yield +def registration_allowed(): + if not config.REGISTRATION_ENABLED: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail="Registration is disabled" + ) + return True + + app = FastAPI(lifespan=lifespan) # Add CORS middleware @@ -36,6 +44,7 @@ app.include_router( fastapi_users.get_register_router(UserRead, UserCreate), prefix="/auth", tags=["auth"], + dependencies=[Depends(registration_allowed)], # blocks registration when disabled ) app.include_router( fastapi_users.get_reset_password_router(), @@ -62,6 +71,9 @@ if config.AUTH_TYPE == "GOOGLE": ), prefix="/auth/google", tags=["auth"], + dependencies=[ + Depends(registration_allowed) + ], # blocks OAuth registration when disabled ) app.include_router(crud_router, prefix="/api/v1", tags=["crud"]) diff --git a/surfsense_backend/app/config/__init__.py b/surfsense_backend/app/config/__init__.py index acd1017e4..6e894542b 100644 --- a/surfsense_backend/app/config/__init__.py +++ b/surfsense_backend/app/config/__init__.py @@ -43,6 +43,7 @@ class Config: # Auth AUTH_TYPE = os.getenv("AUTH_TYPE") + REGISTRATION_ENABLED = os.getenv("REGISTRATION_ENABLED", "TRUE").upper() == "TRUE" # Google OAuth GOOGLE_OAUTH_CLIENT_ID = os.getenv("GOOGLE_OAUTH_CLIENT_ID") diff --git a/surfsense_web/app/(home)/register/page.tsx b/surfsense_web/app/(home)/register/page.tsx index 303d9a378..c10f92b71 100644 --- a/surfsense_web/app/(home)/register/page.tsx +++ b/surfsense_web/app/(home)/register/page.tsx @@ -64,6 +64,20 @@ export default function RegisterPage() { const data = await response.json(); + if (!response.ok && response.status === 403) { + const friendlyMessage = + "Registrations are currently closed. If you need access, contact your administrator."; + setErrorTitle("Registration is disabled"); + setError(friendlyMessage); + toast.error("Registration is disabled", { + id: loadingToast, + description: friendlyMessage, + duration: 6000, + }); + setIsLoading(false); + return; + } + if (!response.ok) { throw new Error(data.detail || `HTTP ${response.status}`); }