Local, password-only auth: - No public pages; everything outside /admin and /auth redirects in - First run (no users) sends every page to /auth/signup, which creates the super admin (user #1) once and then locks - Login is email/username + password; removed the emailed-code flow, /auth/sso and email password reset - Google login kept for existing accounts only, never creates them - seed-super-admin now requires SEED_SUPER_ADMIN_PASSWORD Bots-first admin: - /admin and closed sections (people, logs, backups) redirect to /admin/bots; only bots and settings are live (AdminSections) - Removed the old admin layout; every /admin page uses the bots rail - Coordinator bot created at signup/seed and by /admin/bots (ensureCoordinatorBot), which redirects to its chat - bots.system_prompt (markdown) with a default coordinator prompt - seed-bots reuses the existing coordinator Settings: - Sub pages general (default), profile, change-password, listed in the rail with a back link; unknown settings paths redirect to general - Redesigned settings UI: pane header, grouped rows, sticky save bar - General: System/Light/Dark theme, saved per device Co-Authored-By: Claude Opus 5.5 <[email protected]>
81 lines
2.7 KiB
TypeScript
81 lines
2.7 KiB
TypeScript
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
|
import type { PagePropsType } from "../types";
|
|
import userAuth from "../functions/backend/auth/user-auth";
|
|
import grabHasUsers from "../functions/backend/auth/grab-has-users";
|
|
import isAdminSectionPath from "../utils/is-admin-section-path";
|
|
import { AdminHomePath } from "../dict/admin-sections-dict";
|
|
import isUnknownSettingsPath from "../utils/is-unknown-settings-path";
|
|
import { SettingsDefaultPath } from "../dict/settings-pages-dict";
|
|
|
|
/**
|
|
* Routing for a local install. There are no public pages:
|
|
* - no account yet: everything goes to `/auth/signup` (super admin setup)
|
|
* - signup after setup: back to `/auth/login` (or the bots if logged in)
|
|
* - anything outside the live admin sections and `/auth`: `/admin/bots`
|
|
* - an unknown `/admin/settings/*` page: `/admin/settings/general`
|
|
* - `/admin/*` logged out: `/auth/login`
|
|
* - `/auth/*` logged in (except logout): `/admin/bots`
|
|
*/
|
|
const server: BunextPageServerFn<PagePropsType> = async ({ req, url }) => {
|
|
const { user, user_types } = await userAuth({ req });
|
|
const is_signup_page = url.pathname.startsWith("/auth/signup");
|
|
const has_users = await grabHasUsers();
|
|
|
|
if (!has_users && !is_signup_page) {
|
|
return redirect({ destination: "/auth/signup" });
|
|
}
|
|
|
|
if (has_users && is_signup_page) {
|
|
return redirect({
|
|
destination: user?.logged_in_status ? AdminHomePath : "/auth/login",
|
|
});
|
|
}
|
|
|
|
if (url.pathname.startsWith("/admin") && !user?.logged_in_status) {
|
|
return redirect({ destination: "/auth/login" });
|
|
}
|
|
|
|
if (
|
|
!isAdminSectionPath({ pathname: url.pathname }) &&
|
|
!url.pathname.startsWith("/auth")
|
|
) {
|
|
return redirect({ destination: AdminHomePath });
|
|
}
|
|
|
|
if (isUnknownSettingsPath({ pathname: url.pathname })) {
|
|
return redirect({ destination: SettingsDefaultPath });
|
|
}
|
|
|
|
if (
|
|
url.pathname.startsWith("/auth") &&
|
|
!url.pathname.match(/logout/) &&
|
|
user?.logged_in_status
|
|
) {
|
|
return redirect({ destination: AdminHomePath });
|
|
}
|
|
|
|
return {
|
|
props: {
|
|
environment: process.env.NODE_ENV,
|
|
envs: {
|
|
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID || "",
|
|
R2_PUBLIC_DOMAIN: process.env.R2_PUBLIC_DOMAIN || "",
|
|
PAYSTACK_PUBLIC_KEY: process.env.PAYSTACK_PUBLIC_KEY || "",
|
|
},
|
|
user,
|
|
user_types,
|
|
},
|
|
};
|
|
};
|
|
|
|
function redirect({ destination }: { destination: string }) {
|
|
return {
|
|
redirect: {
|
|
destination,
|
|
permanent: false,
|
|
},
|
|
};
|
|
}
|
|
|
|
export default server;
|