Build the Go API and React UI for managing domain denylist/allowlist/recipient deny and spam settings, plus shared lists that import/apply across domains with wildcard compaction, entry verification, and Migadu-friendly list encoding (including per-domain recipient filtering and rejection bisect on apply).
176 lines
4.2 KiB
TypeScript
176 lines
4.2 KiB
TypeScript
import { Navigate, Route, Routes } from 'react-router-dom'
|
|
import { useAuth } from './auth/AuthContext'
|
|
import { DomainsProvider } from './auth/DomainsContext'
|
|
import { DomainDetailPage } from './pages/DomainDetailPage'
|
|
import { HomePage } from './pages/HomePage'
|
|
import { LoginPage } from './pages/LoginPage'
|
|
import { RegisterPage } from './pages/RegisterPage'
|
|
import { SharedListsPage } from './pages/SharedListsPage'
|
|
import { StubPage } from './pages/StubPage'
|
|
import type { ReactNode } from 'react'
|
|
|
|
function Protected({ children }: { children: ReactNode }) {
|
|
const { user, loading, status } = useAuth()
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="auth-layout">
|
|
<p className="muted">Loading…</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!user) {
|
|
if (status?.registration_open) {
|
|
return <Navigate to="/register" replace />
|
|
}
|
|
return <Navigate to="/login" replace />
|
|
}
|
|
|
|
if (user.role !== 'admin') {
|
|
return (
|
|
<div className="auth-layout">
|
|
<div className="auth-panel">
|
|
<h1>Access denied</h1>
|
|
<p className="lede">
|
|
Your account is signed in but does not have admin permission for
|
|
domain controls.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return <DomainsProvider>{children}</DomainsProvider>
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<Routes>
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route path="/register" element={<RegisterPage />} />
|
|
<Route
|
|
path="/"
|
|
element={
|
|
<Protected>
|
|
<HomePage />
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/shared-lists"
|
|
element={
|
|
<Protected>
|
|
<SharedListsPage />
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/domains/:domain/settings"
|
|
element={
|
|
<Protected>
|
|
<DomainDetailPage />
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/domains/:domain/records"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="DNS records"
|
|
description="View Migadu DNS records for the selected domain."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/domains/:domain/diagnostics"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Diagnostics"
|
|
description="Domain diagnostics from the Migadu API."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/domains/:domain/usage"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Usage"
|
|
description="Domain usage statistics from the Migadu API."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/mailboxes"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Mailboxes"
|
|
description="Manage mailboxes on administered domains."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/identities"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Identities"
|
|
description="Manage mailbox identities."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/forwardings"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Forwardings"
|
|
description="Manage address forwardings."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/aliases"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Aliases"
|
|
description="Manage aliases on administered domains."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/rewrites"
|
|
element={
|
|
<Protected>
|
|
<StubPage
|
|
title="Rewrites"
|
|
description="Manage rewrite rules."
|
|
domainScoped
|
|
/>
|
|
</Protected>
|
|
}
|
|
/>
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Routes>
|
|
)
|
|
}
|