@stacksjs/defaults 0.75.60 → 0.75.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/Middleware/Csrf.ts +26 -0
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
package/app/Middleware/Csrf.ts
CHANGED
|
@@ -168,10 +168,36 @@ export function responseMayUseCsrfToken(response: Response): boolean {
|
|
|
168
168
|
|| type.endsWith('+json')
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Whether a response told shared caches they may keep it: its `Cache-Control`
|
|
173
|
+
* says `public` or gives an `s-maxage`, and says neither `private` nor
|
|
174
|
+
* `no-store`.
|
|
175
|
+
*
|
|
176
|
+
* Such a response is, by its own account, the same for everyone, so it must
|
|
177
|
+
* not carry a per-visitor cookie. A CDN refuses to store a response that sets
|
|
178
|
+
* one (Cloudflare answers `cf-cache-status: BYPASS`), so seeding here kept
|
|
179
|
+
* every shareable API read out of the edge; and a cache that stored it anyway
|
|
180
|
+
* would hand one visitor's token to everybody behind it.
|
|
181
|
+
*/
|
|
182
|
+
export function responseDeclaresShared(response: Response): boolean {
|
|
183
|
+
const value = (response.headers.get('cache-control') || '').toLowerCase()
|
|
184
|
+
if (!value || /\b(?:private|no-store)\b/.test(value))
|
|
185
|
+
return false
|
|
186
|
+
return /\bpublic\b/.test(value) || /\bs-maxage\s*=/.test(value)
|
|
187
|
+
}
|
|
188
|
+
|
|
171
189
|
export function seedCsrfCookieIfMissing(req: Request, response: Response, minted?: string, responseHasNoCookies = false): Response {
|
|
172
190
|
if (!responseMayUseCsrfToken(response))
|
|
173
191
|
return response
|
|
174
192
|
|
|
193
|
+
// Nothing depends on a shareable response seeding the cookie: a page that
|
|
194
|
+
// carries forms is per-visitor and never says `public`, and a client about to
|
|
195
|
+
// submit without a cookie can ask for one from a response that is not shared.
|
|
196
|
+
// This holds for every layer that seeds - the API router, and the page server
|
|
197
|
+
// that proxies `/api` to it - because they all come through here.
|
|
198
|
+
if (responseDeclaresShared(response))
|
|
199
|
+
return response
|
|
200
|
+
|
|
175
201
|
// A token the router minted before rendering wins over "the header already
|
|
176
202
|
// has one", because it put that value in the header itself - and the page
|
|
177
203
|
// has already embedded it in every form it drew. Generating a second token
|
package/ide/vscode/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"publisher": "Stacks",
|
|
3
3
|
"name": "vscode-stacks",
|
|
4
4
|
"displayName": "Stacks",
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.62",
|
|
6
6
|
"description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.62",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.35",
|
|
58
|
-
"@stacksjs/mobile": "^0.75.
|
|
58
|
+
"@stacksjs/mobile": "^0.75.62",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.348",
|
|
60
60
|
"ts-qr-codes": "^0.1.8"
|
|
61
61
|
}
|