diff --git a/api/backend/ai/ai_router.py b/api/backend/ai/ai_router.py index 2f6f0a4..01520df 100644 --- a/api/backend/ai/ai_router.py +++ b/api/backend/ai/ai_router.py @@ -67,4 +67,4 @@ async def ai(c: AI): @ai_router.get("/ai/check") async def check(): - return JSONResponse(content=bool(open_ai_key or llama_model)) + return JSONResponse(content={"ai_enabled": bool(open_ai_key or llama_model)}) diff --git a/api/backend/auth/auth_router.py b/api/backend/auth/auth_router.py index 5405eac..1af09df 100644 --- a/api/backend/auth/auth_router.py +++ b/api/backend/auth/auth_router.py @@ -1,5 +1,6 @@ # STL from datetime import timedelta +import os # PDM from fastapi import Depends, APIRouter, HTTPException, status @@ -61,3 +62,8 @@ async def create_user(user: UserCreate): @auth_router.get("/auth/users/me", response_model=User) async def read_users_me(current_user: User = Depends(get_current_user)): return current_user + + +@auth_router.get("/auth/check") +async def check_auth(): + return {"registration": os.environ.get("REGISTRATION_ENABLED", "True") == "True"} diff --git a/api/backend/database/startup.py b/api/backend/database/startup.py index 4e34fde..86cfaf5 100644 --- a/api/backend/database/startup.py +++ b/api/backend/database/startup.py @@ -1,6 +1,9 @@ +import os from api.backend.database.common import connect, QUERIES import logging +from api.backend.auth.auth_utils import get_password_hash + LOG = logging.getLogger(__name__) @@ -12,4 +15,29 @@ def init_database(): LOG.info(f"Executing query: {query}") _ = cursor.execute(query) + if os.environ.get("REGISTRATION_ENABLED", "True") == "False": + default_user_email = os.environ.get("DEFAULT_USER_EMAIL") + default_user_password = os.environ.get("DEFAULT_USER_PASSWORD") + default_user_full_name = os.environ.get("DEFAULT_USER_FULL_NAME") + + if ( + not default_user_email + or not default_user_password + or not default_user_full_name + ): + LOG.error( + "DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD, or DEFAULT_USER_FULL_NAME is not set!" + ) + exit(1) + + query = "INSERT INTO users (email, hashed_password, full_name) VALUES (?, ?, ?)" + _ = cursor.execute( + query, + ( + default_user_email, + get_password_hash(default_user_password), + default_user_full_name, + ), + ) + cursor.close() diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 50c3d82..eec1f3e 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -48,14 +48,14 @@ export const checkAI = async ( ) => { const token = Cookies.get("token"); try { - const response = await fetch("/api/ai/check", { + const response = await fetch("/api/check", { headers: { "content-type": "application/json", Authorization: `Bearer ${token}`, }, }); const data = await response.json(); - setAiEnabled(data); + setAiEnabled(data.ai_enabled); } catch (error) { console.error("Error fetching jobs:", error); throw error; diff --git a/src/pages/api/ai/check.ts b/src/pages/api/check.ts similarity index 73% rename from src/pages/api/ai/check.ts rename to src/pages/api/check.ts index bfe7034..5f37511 100644 --- a/src/pages/api/ai/check.ts +++ b/src/pages/api/check.ts @@ -17,12 +17,21 @@ export default async function handler( } ); + const checksResponse = await fetch( + `${global.process.env.NEXT_PUBLIC_API_URL}/api/auth/check`, + { + method: "GET", + headers, + } + ); + if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const result = await response.json(); - res.status(200).json(result); + const checksResult = await checksResponse.json(); + res.status(200).json({ ...result, ...checksResult }); } catch (error) { console.error("Error submitting scrape job:", error); res.status(500).json({ error: "Internal Server Error" }); diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 8b5728b..846a5e4 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import axios from "axios"; import { Button, TextField, Typography, Box } from "@mui/material"; import { useTheme } from "@mui/material/styles"; @@ -18,7 +18,16 @@ const AuthForm: React.FC = () => { const theme = useTheme(); const router = useRouter(); const { login } = useAuth(); + const [registrationEnabled, setRegistrationEnabled] = useState(true); + const checkRegistrationEnabled = async () => { + const response = await axios.get(`/api/check`); + setRegistrationEnabled(response.data.registration); + }; + + useEffect(() => { + checkRegistrationEnabled(); + }, []); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); try { @@ -124,9 +133,37 @@ const AuthForm: React.FC = () => { > {mode.charAt(0).toUpperCase() + mode.slice(1)} - + {registrationEnabled && ( + + )} + + {!registrationEnabled && ( +
+ + Registration has been disabled + +
+ )}