-
-
setPasswords({ ...passwords, current: e.target.value })}
- required
+
+
+
+
Require login
+
+ When ON, dashboard requires password. When OFF, access without login.
+
+
+
updateRequireLogin(!settings.requireLogin)}
+ disabled={loading}
/>
-
+ {settings.requireLogin === true && (
+
)}
-
-
-
-
-
+
{/* Routing Preferences */}
diff --git a/src/app/api/settings/require-login/route.js b/src/app/api/settings/require-login/route.js
new file mode 100644
index 0000000..1e1a14d
--- /dev/null
+++ b/src/app/api/settings/require-login/route.js
@@ -0,0 +1,12 @@
+import { NextResponse } from "next/server";
+import { getSettings } from "@/lib/localDb";
+
+export async function GET() {
+ try {
+ const settings = await getSettings();
+ const requireLogin = settings.requireLogin !== false;
+ return NextResponse.json({ requireLogin });
+ } catch (error) {
+ return NextResponse.json({ requireLogin: true }, { status: 200 });
+ }
+}
diff --git a/src/app/api/settings/route.js b/src/app/api/settings/route.js
index a1863a6..fa2332f 100644
--- a/src/app/api/settings/route.js
+++ b/src/app/api/settings/route.js
@@ -5,13 +5,15 @@ import bcrypt from "bcryptjs";
export async function GET() {
try {
const settings = await getSettings();
- // Don't return the password hash to the client
const { password, ...safeSettings } = settings;
- // Add ENABLE_REQUEST_LOGS from env
const enableRequestLogs = process.env.ENABLE_REQUEST_LOGS === "true";
- return NextResponse.json({ ...safeSettings, enableRequestLogs });
+ return NextResponse.json({
+ ...safeSettings,
+ enableRequestLogs,
+ hasPassword: !!password
+ });
} catch (error) {
console.log("Error getting settings:", error);
return NextResponse.json({ error: error.message }, { status: 500 });
@@ -37,8 +39,9 @@ export async function PATCH(request) {
return NextResponse.json({ error: "Invalid current password" }, { status: 401 });
}
} else {
- // First time setting password, check if it matches default 123456
- if (body.currentPassword !== "123456") {
+ // First time setting password, no current password needed
+ // Allow empty currentPassword or default "123456"
+ if (body.currentPassword && body.currentPassword !== "123456") {
return NextResponse.json({ error: "Invalid current password" }, { status: 401 });
}
}
diff --git a/src/app/login/page.js b/src/app/login/page.js
index a8e868e..653c2ef 100644
--- a/src/app/login/page.js
+++ b/src/app/login/page.js
@@ -11,14 +11,13 @@ export default function LoginPage() {
const [hasPassword, setHasPassword] = useState(null);
const router = useRouter();
- // Check if password is set on mount
useEffect(() => {
- async function checkPassword() {
+ async function checkAuth() {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
+ const baseUrl = typeof window !== "undefined" ? window.location.origin : "";
try {
- const baseUrl = typeof window !== "undefined" ? window.location.origin : "";
const res = await fetch(`${baseUrl}/api/settings`, {
signal: controller.signal,
});
@@ -26,8 +25,12 @@ export default function LoginPage() {
if (res.ok) {
const data = await res.json();
+ if (data.requireLogin === false) {
+ router.push("/dashboard");
+ router.refresh();
+ return;
+ }
if (!data.password) {
- // No password set - auto login
const loginRes = await fetch(`${baseUrl}/api/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -43,11 +46,10 @@ export default function LoginPage() {
}
} catch (err) {
clearTimeout(timeoutId);
- // Silent fail - default to showing login form
setHasPassword(true);
}
}
- checkPassword();
+ checkAuth();
}, [router]);
const handleLogin = async (e) => {
diff --git a/src/lib/localDb.js b/src/lib/localDb.js
index 4e2fa6d..6c39b0f 100644
--- a/src/lib/localDb.js
+++ b/src/lib/localDb.js
@@ -48,7 +48,8 @@ const defaultData = {
apiKeys: [],
settings: {
cloudEnabled: false,
- stickyRoundRobinLimit: 3
+ stickyRoundRobinLimit: 3,
+ requireLogin: true
},
pricing: {} // NEW: pricing configuration
};
diff --git a/src/proxy.js b/src/proxy.js
index 4b97c90..a683a6c 100644
--- a/src/proxy.js
+++ b/src/proxy.js
@@ -12,16 +12,26 @@ export async function proxy(request) {
if (pathname.startsWith("/dashboard")) {
const token = request.cookies.get("auth_token")?.value;
- if (!token) {
- return NextResponse.redirect(new URL("/login", request.url));
+ if (token) {
+ try {
+ await jwtVerify(token, SECRET);
+ return NextResponse.next();
+ } catch (err) {
+ return NextResponse.redirect(new URL("/login", request.url));
+ }
}
+ const origin = request.nextUrl.origin;
try {
- await jwtVerify(token, SECRET);
- return NextResponse.next();
+ const res = await fetch(`${origin}/api/settings/require-login`);
+ const data = await res.json();
+ if (data.requireLogin === false) {
+ return NextResponse.next();
+ }
} catch (err) {
- return NextResponse.redirect(new URL("/login", request.url));
+ // On error, require login
}
+ return NextResponse.redirect(new URL("/login", request.url));
}
// Redirect / to /dashboard if logged in, or /dashboard if it's the root