Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fcf4ee8e0 | ||
|
|
a4fab3dcc9 |
@@ -97,13 +97,15 @@ not for the public pages. See `docs/design-principles.md` for the design.
|
|||||||
- `pagerite.js` — public page entry; runs fetch-navigation, scroll-reveal,
|
- `pagerite.js` — public page entry; runs fetch-navigation, scroll-reveal,
|
||||||
brand shrink-to-fit (the themed size is the maximum; JS reduces the
|
brand shrink-to-fit (the themed size is the maximum; JS reduces the
|
||||||
font-size so a long brand or narrow viewport still fits one line),
|
font-size so a long brand or narrow viewport still fits one line),
|
||||||
code copy buttons, and the auth check: it fetches
|
code copy buttons, and the auth check: it probes `GET /_api/settings`
|
||||||
`/auth/api/validate?perm=pagerite:admin` and only then injects the 🖊️
|
and only then injects the 🖊️ edit pens (asset URLs from the
|
||||||
edit pens (asset URLs from the `pagerite:editor-src`/`-css` meta tags);
|
`pagerite:editor-src`/`-css` meta tags). The same reverse proxy that
|
||||||
a 401 adds a "log in" link to `/auth/` in the banner corner, a 403
|
gates `/_api` returns 401 for anonymous users, 403 for users without
|
||||||
nothing, and any other result (no auth server, e.g. dev) leaves
|
the admin permission, and 200 for admins; a 401 adds a "log in" link
|
||||||
editing open. Pages themselves render identically for everyone; the
|
to `/auth/` in the banner corner, a 403 nothing, and any other
|
||||||
real gate is the auth proxy in front of all of `/_api`. The backend links the shared CSS as two separate
|
result (no auth proxy, e.g. dev) leaves editing open. Pages themselves
|
||||||
|
render identically for everyone; the real gate is the auth proxy in
|
||||||
|
front of all of `/_api`. The backend links the shared CSS as two separate
|
||||||
stylesheets (base and theme) so they can be swapped or augmented.
|
stylesheets (base and theme) so they can be swapped or augmented.
|
||||||
- `assets/` — shared styles and data files built by Vite and served hashed
|
- `assets/` — shared styles and data files built by Vite and served hashed
|
||||||
under `/_assets/`: `pagerite.css` (base layout + conservative variables),
|
under `/_assets/`: `pagerite.css` (base layout + conservative variables),
|
||||||
|
|||||||
@@ -28,11 +28,13 @@
|
|||||||
|
|
||||||
// --- Auth-gated edit pens ---------------------------------------------
|
// --- Auth-gated edit pens ---------------------------------------------
|
||||||
// Pages render identically for everyone; the 🖊️ pens are injected by JS
|
// Pages render identically for everyone; the 🖊️ pens are injected by JS
|
||||||
// only after the auth server validates the session (perm pagerite:admin).
|
// only after we know the user has pagerite:admin access. We probe our own
|
||||||
|
// /_api/settings endpoint: the same reverse proxy that gates /_api returns
|
||||||
|
// 401/403 here, and a 200 means the permission is present.
|
||||||
// 401 = anonymous: show a small login link in the banner corner instead.
|
// 401 = anonymous: show a small login link in the banner corner instead.
|
||||||
// 403 = logged in without the permission: no pens. Any other outcome
|
// 403 = logged in without the permission: no pens. Any other outcome
|
||||||
// (404, network error — i.e. no auth server deployed, as in dev) leaves
|
// (network error — i.e. no auth proxy deployed, as in dev) leaves editing
|
||||||
// editing open as before: the real gate is the proxy in front of /_api.
|
// open as before: the real gate is the proxy in front of /_api.
|
||||||
let authorized = false;
|
let authorized = false;
|
||||||
let editorMeta = null;
|
let editorMeta = null;
|
||||||
|
|
||||||
@@ -78,9 +80,9 @@
|
|||||||
};
|
};
|
||||||
let status = 0;
|
let status = 0;
|
||||||
try {
|
try {
|
||||||
status = (await fetch("/auth/api/validate?perm=pagerite:admin")).status;
|
status = (await fetch("/_api/settings")).status;
|
||||||
} catch {
|
} catch {
|
||||||
// Auth server unreachable: treat as not deployed.
|
// Auth proxy unreachable: treat as not deployed.
|
||||||
}
|
}
|
||||||
if (status === 401) addLoginLink();
|
if (status === 401) addLoginLink();
|
||||||
else if (status !== 403) {
|
else if (status !== 403) {
|
||||||
|
|||||||
+3
-2
@@ -563,8 +563,9 @@ async def show_page(request: Request, path: str) -> HTMLResponse | Response:
|
|||||||
"""
|
"""
|
||||||
path = path.strip("/")
|
path = path.strip("/")
|
||||||
if path and _is_reserved(path):
|
if path and _is_reserved(path):
|
||||||
# Reserved slug shape: never content — no tree lookup.
|
# Invalid slug shape: not a content URL, let FastAPI return its
|
||||||
return HTMLResponse(views.render_not_found(data.menu, path, data.brand, data.custom_css, data.theme), 404)
|
# built-in 404 instead of rendering an editable article page.
|
||||||
|
raise HTTPException(404)
|
||||||
chain = resolve(data.menu, path)
|
chain = resolve(data.menu, path)
|
||||||
node = chain[-1] if chain else None
|
node = chain[-1] if chain else None
|
||||||
if node is not None and node.published and node.content is not None:
|
if node is not None and node.published and node.content is not None:
|
||||||
|
|||||||
+1
-1
@@ -353,7 +353,7 @@ def render_not_found(
|
|||||||
doc = E.article
|
doc = E.article
|
||||||
with doc:
|
with doc:
|
||||||
doc.h1("Not Found")
|
doc.h1("Not Found")
|
||||||
doc.p(f"No page at /{path}.")
|
doc.p(f"No article at /{path}. If there was before, it may have been deleted.")
|
||||||
scripts, styles = _page_assets(theme)
|
scripts, styles = _page_assets(theme)
|
||||||
return str(
|
return str(
|
||||||
_layout(styles, scripts, custom_css, theme)(
|
_layout(styles, scripts, custom_css, theme)(
|
||||||
|
|||||||
Reference in New Issue
Block a user