Add dedicated local admin domain routing
This commit is contained in:
+14
-13
@@ -11,6 +11,7 @@ import {
|
||||
Type,
|
||||
type LucideIcon,
|
||||
} from "lucide-react";
|
||||
import { getAdminAppPath } from "@/lib/admin-routing";
|
||||
|
||||
type AdminNavigationCopy = {
|
||||
overview: string;
|
||||
@@ -42,56 +43,56 @@ export function getAdminNavigation(
|
||||
return [
|
||||
{
|
||||
label: copy.overview,
|
||||
href: "/",
|
||||
href: getAdminAppPath("/"),
|
||||
icon: LayoutDashboard,
|
||||
active: active === "overview",
|
||||
},
|
||||
{
|
||||
label: copy.maintenance,
|
||||
href: "/maintenance",
|
||||
href: getAdminAppPath("/maintenance"),
|
||||
icon: ShieldAlert,
|
||||
active: active === "maintenance",
|
||||
},
|
||||
{
|
||||
label: copy.uiKit,
|
||||
href: "/ui-kit",
|
||||
href: getAdminAppPath("/ui-kit"),
|
||||
icon: SwatchBook,
|
||||
active: active === "ui-kit",
|
||||
},
|
||||
{
|
||||
label: copy.media,
|
||||
href: "/media",
|
||||
href: getAdminAppPath("/media"),
|
||||
icon: ImageIcon,
|
||||
active: active === "media",
|
||||
},
|
||||
{
|
||||
label: copy.siteSettings,
|
||||
href: "/site-settings",
|
||||
href: getAdminAppPath("/site-settings"),
|
||||
icon: Globe2,
|
||||
active: active === "site-settings",
|
||||
},
|
||||
{
|
||||
label: copy.marquee ?? "Marquee",
|
||||
href: "/marquee",
|
||||
href: getAdminAppPath("/marquee"),
|
||||
icon: Type,
|
||||
active: active === "marquee",
|
||||
},
|
||||
{
|
||||
label: copy.smtp ?? "SMTP",
|
||||
href: "/smtp",
|
||||
href: getAdminAppPath("/smtp"),
|
||||
icon: Mail,
|
||||
active: active === "smtp" && !smtpChild,
|
||||
expanded: active === "smtp",
|
||||
children: [
|
||||
{
|
||||
label: copy.smtp ?? "SMTP",
|
||||
href: "/smtp",
|
||||
href: getAdminAppPath("/smtp"),
|
||||
icon: Mail,
|
||||
active: smtpChild === "settings" || (!smtpChild && active === "smtp"),
|
||||
},
|
||||
{
|
||||
label: copy.contactProtection ?? "Contact Protection",
|
||||
href: "/smtp/contact-protection",
|
||||
href: getAdminAppPath("/smtp/contact-protection"),
|
||||
icon: ShieldAlert,
|
||||
active: smtpChild === "contact-protection",
|
||||
},
|
||||
@@ -99,26 +100,26 @@ export function getAdminNavigation(
|
||||
},
|
||||
{
|
||||
label: copy.portfolio,
|
||||
href: "/portfolio",
|
||||
href: getAdminAppPath("/portfolio"),
|
||||
icon: FolderKanban,
|
||||
active: active === "portfolio" && !portfolioChild,
|
||||
expanded: active === "portfolio",
|
||||
children: [
|
||||
{
|
||||
label: "Projects",
|
||||
href: "/portfolio",
|
||||
href: getAdminAppPath("/portfolio"),
|
||||
icon: FolderKanban,
|
||||
active: portfolioChild === "overview" || portfolioChild === "projects",
|
||||
},
|
||||
{
|
||||
label: "Add Project",
|
||||
href: "/portfolio/projects/new",
|
||||
href: getAdminAppPath("/portfolio/projects/new"),
|
||||
icon: PlusSquare,
|
||||
active: portfolioChild === "new-project",
|
||||
},
|
||||
{
|
||||
label: "Add Category",
|
||||
href: "/portfolio/categories",
|
||||
href: getAdminAppPath("/portfolio/categories"),
|
||||
icon: Tags,
|
||||
active: portfolioChild === "categories",
|
||||
},
|
||||
|
||||
+56
-1
@@ -1,6 +1,7 @@
|
||||
const DEFAULT_ADMIN_HOST = "root.mohfarawati.de";
|
||||
const DEFAULT_ADMIN_URL = `https://${DEFAULT_ADMIN_HOST}`;
|
||||
const DEFAULT_SITE_URL = "https://mohfarawati.de";
|
||||
const DEV_ADMIN_PREFIX = "/root";
|
||||
|
||||
export const INTERNAL_ADMIN_PREFIX = "/admin-internal";
|
||||
|
||||
@@ -16,10 +17,32 @@ function normalizeBaseUrl(url: string): string {
|
||||
return url.replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
function parseHostname(value: string | undefined): string | undefined {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const trimmed = value.trim().toLowerCase();
|
||||
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL(trimmed).hostname.toLowerCase();
|
||||
} catch {
|
||||
return trimmed.replace(/^https?:\/\//, "").split("/")[0]?.replace(/:\d+$/, "") || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getAdminHost(): string {
|
||||
return (process.env.ADMIN_HOST ?? DEFAULT_ADMIN_HOST).trim().toLowerCase();
|
||||
}
|
||||
|
||||
export function getSiteHost(): string {
|
||||
return parseHostname(process.env.NEXT_PUBLIC_SITE_URL ?? DEFAULT_SITE_URL) ?? "localhost";
|
||||
}
|
||||
|
||||
export function getRequestHostname(hostHeader?: string | null): string {
|
||||
return (hostHeader ?? "")
|
||||
.split(",")[0]
|
||||
@@ -32,10 +55,18 @@ export function isAdminHost(hostname: string): boolean {
|
||||
return hostname === getAdminHost();
|
||||
}
|
||||
|
||||
export function hasDedicatedAdminHost(): boolean {
|
||||
return getAdminHost() !== getSiteHost();
|
||||
}
|
||||
|
||||
export function isLegacyAdminPath(pathname: string): boolean {
|
||||
return pathname === "/root" || pathname.startsWith("/root/");
|
||||
}
|
||||
|
||||
export function isDevelopmentAdminPath(pathname: string): boolean {
|
||||
return pathname === DEV_ADMIN_PREFIX || pathname.startsWith(`${DEV_ADMIN_PREFIX}/`);
|
||||
}
|
||||
|
||||
export function isInternalAdminPath(pathname: string): boolean {
|
||||
return pathname === INTERNAL_ADMIN_PREFIX || pathname.startsWith(`${INTERNAL_ADMIN_PREFIX}/`);
|
||||
}
|
||||
@@ -50,12 +81,36 @@ export function toInternalAdminPath(pathname: string): string {
|
||||
return `${INTERNAL_ADMIN_PREFIX}${normalizedPathname}`;
|
||||
}
|
||||
|
||||
export function fromDevelopmentAdminPath(pathname: string): string {
|
||||
if (pathname === DEV_ADMIN_PREFIX) {
|
||||
return "/";
|
||||
}
|
||||
|
||||
if (pathname.startsWith(`${DEV_ADMIN_PREFIX}/`)) {
|
||||
return pathname.slice(DEV_ADMIN_PREFIX.length);
|
||||
}
|
||||
|
||||
return pathname;
|
||||
}
|
||||
|
||||
export function getAdminBaseUrl(): string {
|
||||
return normalizeBaseUrl(process.env.NEXT_PUBLIC_ADMIN_URL ?? DEFAULT_ADMIN_URL);
|
||||
}
|
||||
|
||||
export function getAdminAppPath(pathname = "/"): string {
|
||||
const normalizedPathname = normalizePathname(pathname);
|
||||
|
||||
if (process.env.NODE_ENV !== "production" && !hasDedicatedAdminHost()) {
|
||||
return normalizedPathname === "/"
|
||||
? DEV_ADMIN_PREFIX
|
||||
: `${DEV_ADMIN_PREFIX}${normalizedPathname}`;
|
||||
}
|
||||
|
||||
return normalizedPathname;
|
||||
}
|
||||
|
||||
export function buildAdminUrl(pathname = "/"): string {
|
||||
return `${getAdminBaseUrl()}${normalizePathname(pathname)}`;
|
||||
return `${getAdminBaseUrl()}${getAdminAppPath(pathname)}`;
|
||||
}
|
||||
|
||||
export function getSiteBaseUrl(): string {
|
||||
|
||||
Reference in New Issue
Block a user