bosia 0.7.6 → 0.7.8
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/package.json +1 -1
- package/src/core/hooks.ts +13 -0
- package/src/core/plugins/inspector/overlay.ts +1 -3
- package/src/core/server.ts +10 -2
- package/src/lib/index.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bosia",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
|
|
6
6
|
"keywords": [
|
package/src/core/hooks.ts
CHANGED
|
@@ -113,6 +113,19 @@ export type Metadata = {
|
|
|
113
113
|
|
|
114
114
|
type MaybePromise<T> = T | Promise<T>;
|
|
115
115
|
|
|
116
|
+
// ─── Frame-Guard Opt-Out ──────────────────────────────────
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Internal response header a `handle` can set to opt a single response out of
|
|
120
|
+
* the global `X-Frame-Options: SAMEORIGIN` guard. Use when a trusted proxy hub
|
|
121
|
+
* serves another origin's content that must be embeddable (e.g. an app preview
|
|
122
|
+
* iframe): the proxy strips the upstream `X-Frame-Options`, but the framework
|
|
123
|
+
* would otherwise re-add its own. The header is stripped before the response
|
|
124
|
+
* leaves the process, so it never reaches the client. Other security headers
|
|
125
|
+
* (`X-Content-Type-Options`, `Referrer-Policy`) are unaffected.
|
|
126
|
+
*/
|
|
127
|
+
export const NO_FRAME_GUARD_HEADER = "x-bosia-no-frame-guard";
|
|
128
|
+
|
|
116
129
|
// ─── Middleware Composition ────────────────────────────────
|
|
117
130
|
|
|
118
131
|
/**
|
|
@@ -138,12 +138,10 @@ function send(payload,onOk,onErr){
|
|
|
138
138
|
function closeForm(){if(form){form.remove();form=null}}
|
|
139
139
|
function openForm(loc,el){
|
|
140
140
|
closeForm();
|
|
141
|
-
var chain=userFrames(el).join(" → ");
|
|
142
141
|
var r=el.getBoundingClientRect();
|
|
143
142
|
form=document.createElement("div");
|
|
144
143
|
form.style.cssText="position:fixed;left:"+r.left+"px;top:"+(r.bottom+6)+"px;background:#fff;color:#111;border:1px solid #d4d4d8;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.18);padding:10px;width:340px;z-index:2147483647;font:13px ui-sans-serif,system-ui,sans-serif";
|
|
145
|
-
|
|
146
|
-
form.innerHTML=header+
|
|
144
|
+
form.innerHTML=
|
|
147
145
|
'<textarea placeholder="Describe a fix (Enter to send, Esc to cancel, empty = open in editor)" style="width:100%;min-height:64px;border:1px solid #e4e4e7;border-radius:4px;padding:6px;font:13px ui-sans-serif,system-ui,sans-serif;resize:vertical;box-sizing:border-box;outline:none"></textarea>'+
|
|
148
146
|
'<div style="margin-top:8px;display:flex;gap:6px;justify-content:flex-end">'+
|
|
149
147
|
'<button data-cancel style="padding:4px 10px;border:1px solid #e4e4e7;background:#fff;border-radius:4px;cursor:pointer;font-size:12px">Cancel</button>'+
|
package/src/core/server.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { RouteManifest } from "./types.ts";
|
|
|
12
12
|
// Pre-compile route patterns into RegExp at startup (shared by renderer.ts via module reference)
|
|
13
13
|
compileRoutes(apiRoutes);
|
|
14
14
|
compileRoutes(serverRoutes);
|
|
15
|
-
import type
|
|
15
|
+
import { NO_FRAME_GUARD_HEADER, type Handle, type RequestEvent } from "./hooks.ts";
|
|
16
16
|
import { HttpError, Redirect, ActionFailure } from "./errors.ts";
|
|
17
17
|
import { CookieJar } from "./cookies.ts";
|
|
18
18
|
import { safePath } from "./safePath.ts";
|
|
@@ -842,7 +842,15 @@ async function handleRequest(request: Request, url: URL): Promise<Response> {
|
|
|
842
842
|
const response = userHandle ? await userHandle({ event, resolve }) : await resolve(event);
|
|
843
843
|
|
|
844
844
|
const headers = new Headers(response.headers);
|
|
845
|
-
|
|
845
|
+
// A handle can mark a response (e.g. a proxied embeddable preview) to opt
|
|
846
|
+
// out of the frame guard. Strip the internal marker so it never ships, and
|
|
847
|
+
// skip only X-Frame-Options for that response — other security headers stay.
|
|
848
|
+
const skipFrameGuard = headers.has(NO_FRAME_GUARD_HEADER);
|
|
849
|
+
headers.delete(NO_FRAME_GUARD_HEADER);
|
|
850
|
+
for (const [k, v] of Object.entries(SECURITY_HEADERS)) {
|
|
851
|
+
if (skipFrameGuard && k === "X-Frame-Options") continue;
|
|
852
|
+
headers.set(k, v);
|
|
853
|
+
}
|
|
846
854
|
const cspHeader = buildCspHeader(nonce);
|
|
847
855
|
if (cspHeader) headers.set("Content-Security-Policy", cspHeader);
|
|
848
856
|
// Apply CORS headers for allowed origins. `Vary: Origin` is set whenever
|
package/src/lib/index.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// import type { RequestEvent, LoadEvent, Handle, Cookies } from "bosia"
|
|
7
7
|
|
|
8
8
|
export { cn, getServerTime } from "./utils.ts";
|
|
9
|
-
export { sequence } from "../core/hooks.ts";
|
|
9
|
+
export { sequence, NO_FRAME_GUARD_HEADER } from "../core/hooks.ts";
|
|
10
10
|
export { error, redirect, fail } from "../core/errors.ts";
|
|
11
11
|
// `invalidate` / `invalidateAll` (server response-cache eviction) live in
|
|
12
12
|
// "bosia/server" — they touch server-process state and pulling them into
|