Skip to main content

max / makenotwork

server: convert remaining identity-leak surfaces to MaybeUserVerified Follow-up to the MaybeUser audit. Closes the custom_domain.rs hole (custom_domain_fallback delegates to render_project_page, which the prior commit had upgraded to expect verified extraction for the paywall path). Also converts item_page, collection_page (already converted), purchase_page, receipt_page (already converted), and join_wizard to MaybeUserVerified. Net behavior: identity flags surfaced to public pages (is_owner, is_following, in_library, is_logged_in) now refresh suspension/ revocation state on every request (5s cache). Affordance leaks where a revoked owner would still see edit buttons on their own draft items are closed. Public surfaces still on MaybeUserUnverified: blog, docs, discover, landing, raw git browsing, /, and the global header rendering on pages/public/mod.rs — pages where stale identity is purely cosmetic.
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-25 23:40 UTC
Commit: e488b0e054d411f2a0d960cd28cb31589d216220
Parent: 2a7414c
4 files changed, +9 insertions, -9 deletions
@@ -12,7 +12,7 @@ use axum::{
12 12 use tower_sessions::Session;
13 13
14 14 use crate::{
15 - auth::{MaybeUserUnverified, SessionUser},
15 + auth::{MaybeUserVerified, SessionUser},
16 16 db::{self, Slug},
17 17 error::{AppError, Result},
18 18 helpers::get_csrf_token,
@@ -100,7 +100,7 @@ pub async fn custom_domain_fallback(
100 100 headers: HeaderMap,
101 101 uri: Uri,
102 102 session: Session,
103 - MaybeUserUnverified(maybe_user): MaybeUserUnverified,
103 + MaybeUserVerified(maybe_user): MaybeUserVerified,
104 104 ) -> Response {
105 105 let Some(host) = extract_host(&headers) else {
106 106 return StatusCode::NOT_FOUND.into_response();
@@ -7,7 +7,7 @@ use axum::{
7 7 use tower_sessions::Session;
8 8
9 9 use crate::{
10 - auth::{MaybeUserUnverified, SessionUser},
10 + auth::{MaybeUserVerified, SessionUser},
11 11 db::{self, ContentData, ItemId, ItemType},
12 12 error::{AppError, Result},
13 13 helpers::{fetch_discussion_info, get_csrf_token, get_initials},
@@ -22,7 +22,7 @@ use crate::{
22 22 pub(in crate::routes::pages::public) async fn item_page(
23 23 State(state): State<AppState>,
24 24 session: Session,
25 - MaybeUserUnverified(maybe_user): MaybeUserUnverified,
25 + MaybeUserVerified(maybe_user): MaybeUserVerified,
26 26 Path(item_id): Path<String>,
27 27 ) -> Result<Response> {
28 28 let csrf_token = get_csrf_token(&session).await;
@@ -18,7 +18,7 @@ use serde::Deserialize;
18 18 use tower_sessions::Session;
19 19
20 20 use crate::{
21 - auth::{MaybeUserUnverified, MaybeUserVerified, SessionUser},
21 + auth::{MaybeUserVerified, SessionUser},
22 22 db::{self, FollowTargetType, ItemId, Username},
23 23 error::{AppError, Result},
24 24 helpers::get_csrf_token,
@@ -66,7 +66,7 @@ pub(super) async fn user_page(
66 66 State(state): State<AppState>,
67 67 session: Session,
68 68 headers: axum::http::HeaderMap,
69 - MaybeUserUnverified(maybe_user): MaybeUserUnverified,
69 + MaybeUserVerified(maybe_user): MaybeUserVerified,
70 70 Path(username): Path<String>,
71 71 ) -> Result<Response> {
72 72 let csrf_token = get_csrf_token(&session).await;
@@ -150,7 +150,7 @@ pub(crate) async fn render_user_profile(
150 150 pub(super) async fn purchase_page(
151 151 State(state): State<AppState>,
152 152 session: Session,
153 - MaybeUserUnverified(maybe_user): MaybeUserUnverified,
153 + MaybeUserVerified(maybe_user): MaybeUserVerified,
154 154 Path(item_id): Path<String>,
155 155 Query(query): Query<PurchaseQuery>,
156 156 ) -> Result<impl IntoResponse> {
@@ -14,7 +14,7 @@ use serde::Deserialize;
14 14 use tower_sessions::Session;
15 15
16 16 use crate::{
17 - auth::{hash_password, login_user, track_session, AuthUser, MaybeUserUnverified, SessionUser},
17 + auth::{hash_password, login_user, track_session, AuthUser, MaybeUserVerified, SessionUser},
18 18 db::{self},
19 19 email,
20 20 error::{AppError, Result},
@@ -38,7 +38,7 @@ pub struct JoinQuery {
38 38 #[tracing::instrument(skip_all, name = "join_wizard::page")]
39 39 pub async fn wizard_page(
40 40 session: Session,
41 - MaybeUserUnverified(maybe_user): MaybeUserUnverified,
41 + MaybeUserVerified(maybe_user): MaybeUserVerified,
42 42 Query(query): Query<JoinQuery>,
43 43 ) -> Response {
44 44 if maybe_user.is_some() {