@server/next 0.35.0 → 0.35.1
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/index.d.ts +9 -7
- package/index.js +39 -3
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -230,7 +230,9 @@ type ParamsToObject<Params extends string> = {
|
|
|
230
230
|
};
|
|
231
231
|
type PathToParams<Path extends string> = ParamsToObject<ExtractPathParams<Path>>;
|
|
232
232
|
type BunEnv = Record<string, string> & {
|
|
233
|
-
upgrade?: (req: Request
|
|
233
|
+
upgrade?: (req: Request, options?: {
|
|
234
|
+
data?: any;
|
|
235
|
+
}) => boolean;
|
|
234
236
|
};
|
|
235
237
|
type Context<Params extends Record<string, string | undefined> = Record<string, string>, O extends ServerConfig = object> = {
|
|
236
238
|
method: Method;
|
|
@@ -407,9 +409,9 @@ declare class Server<O extends ServerConfig = {}> extends Router<O> {
|
|
|
407
409
|
signal?: AbortSignal | null;
|
|
408
410
|
window?: null;
|
|
409
411
|
}) => Promise<Response>;
|
|
410
|
-
post: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
412
|
+
post: (path: string, body?: string | number | boolean | ArrayBuffer | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams | {
|
|
411
413
|
[key: string]: SerializableValue;
|
|
412
|
-
} | SerializableValue[]
|
|
414
|
+
} | SerializableValue[], options?: {
|
|
413
415
|
cache?: RequestCache;
|
|
414
416
|
credentials?: RequestCredentials;
|
|
415
417
|
headers?: HeadersInit;
|
|
@@ -424,9 +426,9 @@ declare class Server<O extends ServerConfig = {}> extends Router<O> {
|
|
|
424
426
|
signal?: AbortSignal | null;
|
|
425
427
|
window?: null;
|
|
426
428
|
}) => Promise<Response>;
|
|
427
|
-
put: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
429
|
+
put: (path: string, body?: string | number | boolean | ArrayBuffer | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams | {
|
|
428
430
|
[key: string]: SerializableValue;
|
|
429
|
-
} | SerializableValue[]
|
|
431
|
+
} | SerializableValue[], options?: {
|
|
430
432
|
cache?: RequestCache;
|
|
431
433
|
credentials?: RequestCredentials;
|
|
432
434
|
headers?: HeadersInit;
|
|
@@ -441,9 +443,9 @@ declare class Server<O extends ServerConfig = {}> extends Router<O> {
|
|
|
441
443
|
signal?: AbortSignal | null;
|
|
442
444
|
window?: null;
|
|
443
445
|
}) => Promise<Response>;
|
|
444
|
-
patch: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
446
|
+
patch: (path: string, body?: string | number | boolean | ArrayBuffer | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams | {
|
|
445
447
|
[key: string]: SerializableValue;
|
|
446
|
-
} | SerializableValue[]
|
|
448
|
+
} | SerializableValue[], options?: {
|
|
447
449
|
cache?: RequestCache;
|
|
448
450
|
credentials?: RequestCredentials;
|
|
449
451
|
headers?: HeadersInit;
|
package/index.js
CHANGED
|
@@ -1736,9 +1736,10 @@ function etag(bytes) {
|
|
|
1736
1736
|
function createWebsocket(sockets, handlers) {
|
|
1737
1737
|
const run = (event, socket, body) => {
|
|
1738
1738
|
const routes = handlers.socket?.filter((r2) => r2.path === event) ?? [];
|
|
1739
|
+
const user = socket.user ?? socket.data?.user;
|
|
1739
1740
|
for (const route of routes) {
|
|
1740
1741
|
for (const fn of route.fns) {
|
|
1741
|
-
fn({ socket, sockets, body });
|
|
1742
|
+
fn({ socket, sockets, body, user });
|
|
1742
1743
|
}
|
|
1743
1744
|
}
|
|
1744
1745
|
};
|
|
@@ -2632,6 +2633,13 @@ function timer(ctx) {
|
|
|
2632
2633
|
ctx.time = createTime();
|
|
2633
2634
|
}
|
|
2634
2635
|
|
|
2636
|
+
// src/auth/socketUser.ts
|
|
2637
|
+
async function socketUser(app, headers2, cookies2) {
|
|
2638
|
+
if (!app.settings.auth) return void 0;
|
|
2639
|
+
const ctx = { options: app.settings, headers: headers2, cookies: cookies2 };
|
|
2640
|
+
return getUser(ctx);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2635
2643
|
// src/helpers/wsNode.ts
|
|
2636
2644
|
var GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
2637
2645
|
var CONTINUATION = 0;
|
|
@@ -2666,6 +2674,9 @@ var NodeWebSocket = class {
|
|
|
2666
2674
|
fragmentOpcode;
|
|
2667
2675
|
closed;
|
|
2668
2676
|
readyState;
|
|
2677
|
+
// The auth user resolved from the upgrade request (see attachWebsocket), or
|
|
2678
|
+
// undefined for an anonymous connection. Read by socket handlers as `ctx.user`.
|
|
2679
|
+
user;
|
|
2669
2680
|
constructor(socket, handlers) {
|
|
2670
2681
|
this.socket = socket;
|
|
2671
2682
|
this.handlers = handlers;
|
|
@@ -2764,13 +2775,24 @@ var NodeWebSocket = class {
|
|
|
2764
2775
|
};
|
|
2765
2776
|
async function attachWebsocket(server2, app) {
|
|
2766
2777
|
const { createHash } = await import("crypto");
|
|
2767
|
-
server2.on("upgrade", (req, socket, head) => {
|
|
2778
|
+
server2.on("upgrade", async (req, socket, head) => {
|
|
2768
2779
|
const key = req.headers["sec-websocket-key"];
|
|
2769
2780
|
const upgrade = String(req.headers.upgrade || "").toLowerCase();
|
|
2770
2781
|
if (upgrade !== "websocket" || !key || !app.handlers.socket.length) {
|
|
2771
2782
|
socket.destroy();
|
|
2772
2783
|
return;
|
|
2773
2784
|
}
|
|
2785
|
+
const cookies2 = parseCookies(req.headers.cookie);
|
|
2786
|
+
let user;
|
|
2787
|
+
try {
|
|
2788
|
+
user = await socketUser(app, req.headers, cookies2);
|
|
2789
|
+
} catch {
|
|
2790
|
+
socket.write(
|
|
2791
|
+
"HTTP/1.1 401 Unauthorized\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
|
|
2792
|
+
);
|
|
2793
|
+
socket.destroy();
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2774
2796
|
const accept = createHash("sha1").update(key + GUID).digest("base64");
|
|
2775
2797
|
socket.write(
|
|
2776
2798
|
`HTTP/1.1 101 Switching Protocols\r
|
|
@@ -2786,6 +2808,7 @@ Sec-WebSocket-Accept: ${accept}\r
|
|
|
2786
2808
|
onMessage: (body) => app.websocket.message(ws, body),
|
|
2787
2809
|
onClose: () => app.websocket.close(ws)
|
|
2788
2810
|
});
|
|
2811
|
+
ws.user = user;
|
|
2789
2812
|
app.websocket.open(ws);
|
|
2790
2813
|
if (head?.length) ws.receive(head);
|
|
2791
2814
|
socket.on("data", (chunk) => ws.receive(chunk));
|
|
@@ -2902,7 +2925,20 @@ async function createWinter(req, app, server2) {
|
|
|
2902
2925
|
|
|
2903
2926
|
// src/context/handlers.ts
|
|
2904
2927
|
var Winter = async (app, request, env2) => {
|
|
2905
|
-
if (env2?.upgrade
|
|
2928
|
+
if (env2?.upgrade) {
|
|
2929
|
+
const wantsWs = String(request.headers.get("upgrade") || "").toLowerCase() === "websocket";
|
|
2930
|
+
if (wantsWs) {
|
|
2931
|
+
const headers2 = parseHeaders_default(request.headers);
|
|
2932
|
+
const cookies2 = parseCookies(headers2.cookie);
|
|
2933
|
+
let user;
|
|
2934
|
+
try {
|
|
2935
|
+
user = await socketUser(app, headers2, cookies2);
|
|
2936
|
+
} catch {
|
|
2937
|
+
return new Response("Unauthorized", { status: 401 });
|
|
2938
|
+
}
|
|
2939
|
+
if (env2.upgrade(request, { data: { user } })) return;
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2906
2942
|
Object.assign(globalThis.env, env2);
|
|
2907
2943
|
const ctx = await createWinter(request, app, env2);
|
|
2908
2944
|
const res = await handleRequest(app, ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.1",
|
|
4
4
|
"description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
|
|
5
5
|
"homepage": "https://server-js.com/",
|
|
6
6
|
"repository": "github:franciscop/server-next",
|