also looking at this
feat(reviews): the suggestions get an interface, priced as designed
#6
9 files
+741
-10
| @@ -193,17 +193,36 @@ async function cookieUserId(request: any): Promise<number> { | ||
| 193 | 193 | if (!header) |
| 194 | 194 | return 0 |
| 195 | 195 | |
| 196 | const found = await viewerFromCookies(cookieJarFromHeader(header)) | |
| 197 | return found?.id ?? 0 | |
| 198 | } | |
| 199 | ||
| 200 | /** | |
| 201 | * A `Cookie` header, parsed into the record `viewerFromCookies` reads. | |
| 202 | * | |
| 203 | * Exported for the pages served without a parsed cookie jar: the frontend | |
| 204 | * server hands views `__stxServeContext.cookies` ready-made, but a page | |
| 205 | * rendered through `route.serve()`'s file routing gets the raw headers and | |
| 206 | * nothing else, and a view that only asks for the jar renders every reader | |
| 207 | * there as a stranger. | |
| 208 | */ | |
| 209 | export function cookieJarFromHeader(header: unknown): Record<string, string> { | |
| 196 | 210 | const jar: Record<string, string> = {} |
| 197 | for (const part of header.split(';')) { | |
| 211 | ||
| 212 | for (const part of String(header ?? '').split(';')) { | |
| 198 | 213 | const cut = part.indexOf('=') |
| 199 | 214 | if (cut < 0) |
| 200 | 215 | continue |
| 201 | 216 | |
| 202 | jar[part.slice(0, cut).trim()] = decodeURIComponent(part.slice(cut + 1).trim()) | |
| 217 | try { | |
| 218 | jar[part.slice(0, cut).trim()] = decodeURIComponent(part.slice(cut + 1).trim()) | |
| 219 | } | |
| 220 | catch { | |
| 221 | // A malformed escape in one cookie is not a reason to drop the others. | |
| 222 | } | |
| 203 | 223 | } |
| 204 | 224 | |
| 205 | const found = await viewerFromCookies(jar) | |
| 206 | return found?.id ?? 0 | |
| 225 | return jar | |
| 207 | 226 | } |
| 208 | 227 | |
| 209 | 228 | /** |