fix: Move the API keys page off the /api prefix
/api-keys shares a raw string prefix with /api, and the proxies in front of this app do not all match by path segment. Nginx Proxy Manager routes /api straight to the Go server with a prefix location, so /api-keys never reached Next at all — it reached a control plane with no such route and came back as a JSON 404. Traefik's PathPrefix has the same shape of matcher, which puts the Helm ingress at risk whenever ingress.api.enabled is on. The page is /tokens now, which cannot collide with anything, and which matches the /api/tokens the REST API already publishes. The sidebar still says API Keys — the label is for the reader, the path is for the router. A permanent redirect covers anyone who bookmarked the old path today. Fixing the proxy config instead would have left the trap set for the next deployment, and for whatever sits in front of it.
This commit is contained in:
@@ -297,7 +297,7 @@ export default function SettingsPage() {
|
||||
|
||||
</SectionCard>
|
||||
|
||||
{/* The cap lives here rather than on /api-keys because it is
|
||||
{/* The cap lives here rather than on /tokens because it is
|
||||
instance policy, not one person's credentials — which is
|
||||
also what lets that page be reachable at every role. */}
|
||||
<SectionCard
|
||||
@@ -313,7 +313,7 @@ export default function SettingsPage() {
|
||||
</Field>
|
||||
<p className="mt-4 text-sm text-text-secondary">
|
||||
Keys themselves are managed on{" "}
|
||||
<Link href="/api-keys" className="text-accent hover:underline">
|
||||
<Link href="/tokens" className="text-accent hover:underline">
|
||||
API Keys
|
||||
</Link>
|
||||
, which every member can reach.
|
||||
|
||||
@@ -185,7 +185,7 @@ const navGroups: NavGroup[] = [
|
||||
// Not adminOnly: the API lets any member mint and revoke their own
|
||||
// keys, capped at their own role, so gating the page would hide a
|
||||
// capability they have.
|
||||
{ href: "/api-keys", label: "API Keys", icon: <TokenIcon /> },
|
||||
{ href: "/tokens", label: "API Keys", icon: <TokenIcon /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,6 +8,20 @@ const apiUrl = process.env.API_URL ?? process.env.NEXT_PUBLIC_API_URL ?? "http:/
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: "standalone",
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
// The API keys page briefly lived at /api-keys, which every
|
||||
// raw-prefix proxy in front of this app captures with its /api
|
||||
// rule — nginx's `location /api` matches /api-keys, so the
|
||||
// request reached the Go server and 404'd. The page is at
|
||||
// /tokens now precisely because that cannot happen to it.
|
||||
source: "/api-keys",
|
||||
destination: "/tokens",
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user