mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-24 23:41:10 +02:00
Implemented comprehensive registration control system that allows administrators to disable new user registrations through the admin panel. This provides better control over user access and supports closed registration scenarios. Backend changes: - Added disable_registration field to SiteConfiguration model (db.py) - Created migration #39 to add disable_registration column with default false - Updated SiteConfigurationBase, Update, and Read schemas - Enhanced registration_allowed() dependency to check database toggle - Returns 403 with clear message when registration is disabled Frontend changes: - Added disable_registration to SiteConfig interface and default config - Updated LocalLoginForm to conditionally hide "Sign up" link when disabled - Added RouteGuard support for "registration" route key - Protected /register page with RouteGuard (shows 404 when disabled) - Added "Registration Control" section to admin site-settings page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import React, { createContext, useContext, useEffect, useState } from "react";
|
|
|
|
export interface SiteConfig {
|
|
// Header/Navbar toggles
|
|
show_pricing_link: boolean;
|
|
show_docs_link: boolean;
|
|
show_github_link: boolean;
|
|
show_sign_in: boolean;
|
|
|
|
// Homepage toggles
|
|
show_get_started_button: boolean;
|
|
show_talk_to_us_button: boolean;
|
|
|
|
// Footer toggles
|
|
show_pages_section: boolean;
|
|
show_legal_section: boolean;
|
|
show_register_section: boolean;
|
|
|
|
// Route disabling
|
|
disable_pricing_route: boolean;
|
|
disable_docs_route: boolean;
|
|
disable_contact_route: boolean;
|
|
disable_terms_route: boolean;
|
|
disable_privacy_route: boolean;
|
|
|
|
// Registration control
|
|
disable_registration: boolean;
|
|
|
|
// Custom text
|
|
custom_copyright: string | null;
|
|
}
|
|
|
|
const defaultConfig: SiteConfig = {
|
|
show_pricing_link: false,
|
|
show_docs_link: false,
|
|
show_github_link: false,
|
|
show_sign_in: true,
|
|
show_get_started_button: false,
|
|
show_talk_to_us_button: false,
|
|
show_pages_section: false,
|
|
show_legal_section: false,
|
|
show_register_section: false,
|
|
disable_pricing_route: true,
|
|
disable_docs_route: true,
|
|
disable_contact_route: true,
|
|
disable_terms_route: true,
|
|
disable_privacy_route: true,
|
|
disable_registration: false,
|
|
custom_copyright: "SurfSense 2025",
|
|
};
|
|
|
|
interface SiteConfigContextType {
|
|
config: SiteConfig;
|
|
loading: boolean;
|
|
error: string | null;
|
|
refetch: () => Promise<void>;
|
|
}
|
|
|
|
const SiteConfigContext = createContext<SiteConfigContextType>({
|
|
config: defaultConfig,
|
|
loading: true,
|
|
error: null,
|
|
refetch: async () => {},
|
|
});
|
|
|
|
export function SiteConfigProvider({ children }: { children: React.ReactNode }) {
|
|
const [config, setConfig] = useState<SiteConfig>(defaultConfig);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchConfig = async () => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const backendUrl =
|
|
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http://localhost:8000";
|
|
const response = await fetch(`${backendUrl}/api/v1/site-config/public`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch site configuration: ${response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
setConfig(data);
|
|
} catch (err) {
|
|
const errorMessage = err instanceof Error ? err.message : "Unknown error occurred";
|
|
setError(errorMessage);
|
|
console.error("Error fetching site configuration:", err);
|
|
// Keep default config on error
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchConfig();
|
|
}, []);
|
|
|
|
return (
|
|
<SiteConfigContext.Provider value={{ config, loading, error, refetch: fetchConfig }}>
|
|
{children}
|
|
</SiteConfigContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useSiteConfig() {
|
|
const context = useContext(SiteConfigContext);
|
|
if (!context) {
|
|
throw new Error("useSiteConfig must be used within a SiteConfigProvider");
|
|
}
|
|
return context;
|
|
}
|