From 19ed0becce8ae78ed62287b9c97371c2510c58c2 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Mon, 20 Oct 2025 15:54:52 +0530 Subject: [PATCH 1/2] feat: implement registration toggle in backend and handle disabled state in frontend --- surfsense_backend/.env.example | 1 + surfsense_backend/app/app.py | 8 +++++++- surfsense_backend/app/config/__init__.py | 1 + surfsense_web/app/(home)/register/page.tsx | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) 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..1998f663f 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 @@ -17,6 +17,10 @@ async def lifespan(app: FastAPI): await create_db_and_tables() 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) @@ -36,6 +40,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 +67,7 @@ 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..58641e2a1 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}`); } From fd94193fd59bea3bfbacbcb0f0c1e3c67cd0be9b Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Mon, 20 Oct 2025 16:25:14 +0530 Subject: [PATCH 2/2] fix: ran linting for both backend and frontend --- surfsense_backend/app/app.py | 10 +++++++-- surfsense_web/app/(home)/register/page.tsx | 24 +++++++++++----------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/surfsense_backend/app/app.py b/surfsense_backend/app/app.py index 1998f663f..8c7c53db7 100644 --- a/surfsense_backend/app/app.py +++ b/surfsense_backend/app/app.py @@ -17,11 +17,15 @@ async def lifespan(app: FastAPI): await create_db_and_tables() yield + def registration_allowed(): if not config.REGISTRATION_ENABLED: - raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Registration is disabled") + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail="Registration is disabled" + ) return True + app = FastAPI(lifespan=lifespan) # Add CORS middleware @@ -67,7 +71,9 @@ if config.AUTH_TYPE == "GOOGLE": ), prefix="/auth/google", tags=["auth"], - dependencies=[Depends(registration_allowed)], # blocks OAuth registration when disabled + dependencies=[ + Depends(registration_allowed) + ], # blocks OAuth registration when disabled ) app.include_router(crud_router, prefix="/api/v1", tags=["crud"]) diff --git a/surfsense_web/app/(home)/register/page.tsx b/surfsense_web/app/(home)/register/page.tsx index 58641e2a1..c10f92b71 100644 --- a/surfsense_web/app/(home)/register/page.tsx +++ b/surfsense_web/app/(home)/register/page.tsx @@ -65,18 +65,18 @@ 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; - } + 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}`);