Repository navigation
Commit 0d5afb3
committed
fix: moderation preview scope, comment vote races, and email link origin
Three fixes, consolidated into one PR by request.
1. Move the moderation preview off the public reader routes (#1340
follow-up)
#1340 let admins resolve in_review/rejected posts at their public URLs.
That put the public reader — vote, bookmark and comment controls — on a
post that may be about to be rejected, and `post.vote` has no status
guard, so a misclick writes a vote and author points onto content the
moderator is declining. It also stopped admins seeing the site the way
readers do, and made the rejected-post banner's "not visible to anyone
else" untrue.
Preview now lives at /admin/moderation/preview/{id}: read-only, inside
the admin gate. The public routes and their visibility filter revert.
It also fixes the link path. #1340 sent Preview straight off-site, so the
member's own title/excerpt/body — where a spammer would put the payload —
was never shown; the preview renders both halves. And that off-site href
skipped `safeExternalHref` and rel, so an externalUrl that never passed
`httpUrl()` validation would run as a `javascript:` URL inside the
authenticated admin session, and the page under review received the admin
surface as its referrer.
2. Drop the frozen sort snapshot, serialise votes per comment (#1341
follow-up)
Freezing sort scores was more than the fix needed and wrong on its own
terms: counts still updated on refetch while the order did not, so a
thread could show a 42-point comment below a 3-point one; the documented
"re-pick the sort" escape hatch never fired, because selecting the
already-selected option is a no-op; and the added tiebreak made Top
identical to New on the common all-zero thread.
Not refetching after a successful vote is the whole fix. Ordering is
derived from the data on screen again, so it cannot contradict the counts
beside it. Votes are serialised per comment (newest click wins), since
#1341 dropped the in-flight guard without replacing it and overlapping
writes could land in either order. The resync remount is per comment too.
3. Email links pointed at the deployment, not the site
`getAppOrigin()` fell back to VERCEL_URL, which is the unique
per-deployment hostname — and Vercel sets it in production too. With
DOMAIN_NAME unset, every link it built (the admin's "post awaiting
review" deep link, report emails, the verification link) went out as
*.vercel.app. Production now resolves to the project's production domain,
falling back to the canonical origin; preview deploys still get their own
URL. The duplicate copy of this logic in utils/emailToken.ts is gone.1 parent 33771d3 commit 0d5afb3
13 files changed
Lines changed: 447 additions & 338 deletions
File tree
- app
- (admin)/admin/moderation
- preview/[postId]
- (app)
- [username]/[slug]
- d/[slug]
- components
- ContentDetail
- Discussion
- server
- api/router
- lib
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
76 | 58 | | |
77 | 59 | | |
78 | 60 | | |
| |||
310 | 292 | | |
311 | 293 | | |
312 | 294 | | |
313 | | - | |
| 295 | + | |
314 | 296 | | |
315 | 297 | | |
316 | 298 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | 13 | | |
15 | 14 | | |
16 | 15 | | |
| |||
32 | 31 | | |
33 | 32 | | |
34 | 33 | | |
35 | | - | |
36 | 34 | | |
37 | 35 | | |
38 | 36 | | |
| |||
42 | 40 | | |
43 | 41 | | |
44 | 42 | | |
45 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
46 | 59 | | |
47 | 60 | | |
48 | 61 | | |
| |||
363 | 376 | | |
364 | 377 | | |
365 | 378 | | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
| 379 | + | |
372 | 380 | | |
373 | 381 | | |
374 | 382 | | |
| |||
525 | 533 | | |
526 | 534 | | |
527 | 535 | | |
528 | | - | |
529 | | - | |
530 | | - | |
531 | | - | |
532 | | - | |
533 | | - | |
| 536 | + | |
534 | 537 | | |
535 | 538 | | |
536 | 539 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | 15 | | |
17 | 16 | | |
18 | 17 | | |
| |||
27 | 26 | | |
28 | 27 | | |
29 | 28 | | |
30 | | - | |
31 | 29 | | |
32 | 30 | | |
33 | 31 | | |
| |||
39 | 37 | | |
40 | 38 | | |
41 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
42 | 47 | | |
43 | 48 | | |
44 | 49 | | |
| |||
68 | 73 | | |
69 | 74 | | |
70 | 75 | | |
71 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
72 | 85 | | |
73 | 86 | | |
74 | 87 | | |
| |||
147 | 160 | | |
148 | 161 | | |
149 | 162 | | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
| 163 | + | |
155 | 164 | | |
156 | 165 | | |
157 | 166 | | |
| |||
201 | 210 | | |
202 | 211 | | |
203 | 212 | | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
| 213 | + | |
209 | 214 | | |
210 | 215 | | |
211 | 216 | | |
| |||
0 commit comments