@server/next 0.21.0 → 0.21.2
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 +3 -2
- package/src/auth/auth.js +2 -2
- package/src/auth/index.js +2 -2
- package/src/auth/index.test.js +4 -2
- package/src/auth/logout.js +1 -1
- package/src/helpers/handleRequest.js +0 -12
- package/src/index.js +17 -11
- package/src/middle/assets.js +2 -0
- package/src/middle/index.js +3 -10
- package/src/router.test.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.2",
|
|
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": "https://github.com/franciscop/server-next.git",
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
"license": "UNLICENSED",
|
|
11
11
|
"documentation": {
|
|
12
12
|
"title": "Server JS - A modern web server for Bun and Node.js",
|
|
13
|
+
"home": "./docs/index.html",
|
|
13
14
|
"menu": {
|
|
14
|
-
"About": "/
|
|
15
|
+
"About": "/",
|
|
15
16
|
"Documentation": "/documentation",
|
|
16
17
|
"Github": "https://github.com/franciscop/server-next"
|
|
17
18
|
}
|
package/src/auth/auth.js
CHANGED
|
@@ -48,8 +48,8 @@ export default async function auth(ctx) {
|
|
|
48
48
|
|
|
49
49
|
const auth = await options.session.get(sessionId);
|
|
50
50
|
// Mmh, which one to do...
|
|
51
|
-
if (!auth) throw ServerError.AUTH_NO_SESSION();
|
|
52
|
-
|
|
51
|
+
// if (!auth) throw ServerError.AUTH_NO_SESSION();
|
|
52
|
+
if (!auth) return; // SESSION ALREADY INVALID; no auth
|
|
53
53
|
|
|
54
54
|
if (!auth.provider) throw ServerError.AUTH_NO_PROVIDER();
|
|
55
55
|
if (!options.provider.includes(auth.provider)) {
|
package/src/auth/index.js
CHANGED
|
@@ -12,16 +12,16 @@ const load = async (ctx) => {
|
|
|
12
12
|
|
|
13
13
|
const middle = async (ctx) => {
|
|
14
14
|
if (ctx.options.auth) {
|
|
15
|
-
ctx.app.post("/auth/logout", logout);
|
|
16
|
-
|
|
17
15
|
if (ctx.options.auth.provider.includes("github")) {
|
|
18
16
|
if (!env.GITHUB_ID) throw new Error("GITHUB_ID not defined");
|
|
19
17
|
if (!env.GITHUB_SECRET) throw new Error("GITHUB_SECRET not defined");
|
|
18
|
+
ctx.app.get("/auth/logout", logout);
|
|
20
19
|
ctx.app.get("/auth/login/github", providers.github.login);
|
|
21
20
|
ctx.app.get("/auth/callback/github", providers.github.callback);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
if (ctx.options.auth.provider.includes("email")) {
|
|
24
|
+
ctx.app.post("/auth/logout", logout);
|
|
25
25
|
ctx.app.post("/auth/register/email", providers.email.register);
|
|
26
26
|
ctx.app.post("/auth/login/email", providers.email.login);
|
|
27
27
|
ctx.app.put("/auth/password/email", providers.email.password);
|
package/src/auth/index.test.js
CHANGED
|
@@ -61,7 +61,8 @@ describe("token", () => {
|
|
|
61
61
|
it("cannot get the session", async () => {
|
|
62
62
|
const authorization = "Bearer REqA2l022l8Q0tuI";
|
|
63
63
|
const req = await api.get("/", { headers: { authorization } });
|
|
64
|
-
expect(req).
|
|
64
|
+
expect(req.status).toBe(404);
|
|
65
|
+
// expect(req).not.toSucceed("Invalid session");
|
|
65
66
|
});
|
|
66
67
|
|
|
67
68
|
it("cannot get the user", async () => {
|
|
@@ -112,7 +113,8 @@ describe("cookie", () => {
|
|
|
112
113
|
it("can get the proper session", async () => {
|
|
113
114
|
const cookie = "authentication=REqA2l022l8Q0tuI";
|
|
114
115
|
const req = await api.get("/", { headers: { cookie } });
|
|
115
|
-
expect(req).
|
|
116
|
+
expect(req.status).toBe(404);
|
|
117
|
+
// expect(req).not.toSucceed("Invalid session");
|
|
116
118
|
});
|
|
117
119
|
|
|
118
120
|
it("can get the proper session", async () => {
|
package/src/auth/logout.js
CHANGED
|
@@ -7,7 +7,7 @@ export default async function logout(ctx) {
|
|
|
7
7
|
if (type === "token") {
|
|
8
8
|
return { token: null };
|
|
9
9
|
} else if (type === "cookie") {
|
|
10
|
-
return cookies({ authorization: null }).
|
|
10
|
+
return cookies({ authorization: null }).redirect("/");
|
|
11
11
|
} else if (type === "jwt") {
|
|
12
12
|
throw new Error("JWT auth not supported yet");
|
|
13
13
|
} else if (type === "key") {
|
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import middle from "../middle/index.js";
|
|
2
1
|
import parseResponse from "../parseResponse.js";
|
|
3
2
|
import pathPattern from "../pathPattern.js";
|
|
4
3
|
import define from "./define.js";
|
|
5
4
|
import validate from "./validate.js";
|
|
6
5
|
|
|
7
|
-
const extendWithDefaults = (ctx) => {
|
|
8
|
-
// TODO: find a better way of doing this FFS
|
|
9
|
-
// Only want to execute it once; it needs to happen on a per-request
|
|
10
|
-
// basis since we only have full access to the options there
|
|
11
|
-
if (ctx.app.extended) return;
|
|
12
|
-
middle(ctx);
|
|
13
|
-
ctx.app.extended = true;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
6
|
export default async function handleRequest(handlers, ctx) {
|
|
17
|
-
extendWithDefaults(ctx);
|
|
18
|
-
|
|
19
7
|
for (let [method, matcher, ...cbs] of handlers[ctx.method]) {
|
|
20
8
|
const match = pathPattern(matcher, ctx.url.pathname || "/");
|
|
21
9
|
// Skip this whole middleware if there was no match
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
parseHeaders,
|
|
12
12
|
} from "./helpers/index.js";
|
|
13
13
|
|
|
14
|
+
import { assets, auth } from "./middle/index.js";
|
|
15
|
+
|
|
14
16
|
// Export the reply helpers
|
|
15
17
|
export * from "./reply.js";
|
|
16
18
|
|
|
@@ -27,7 +29,7 @@ export default function server(options = {}) {
|
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
// Keep a copy of the options in the instance
|
|
30
|
-
this.opts = options;
|
|
32
|
+
this.opts = config(options);
|
|
31
33
|
this.platform = getMachine();
|
|
32
34
|
|
|
33
35
|
// TODO: find a way to remove this hack
|
|
@@ -71,6 +73,11 @@ export default function server(options = {}) {
|
|
|
71
73
|
if (this.platform.runtime === "node") {
|
|
72
74
|
this.node();
|
|
73
75
|
}
|
|
76
|
+
|
|
77
|
+
this.use(assets);
|
|
78
|
+
if (this.opts.auth) {
|
|
79
|
+
this.use(auth({ options: this.opts, app: this }));
|
|
80
|
+
}
|
|
74
81
|
}
|
|
75
82
|
|
|
76
83
|
server.prototype.self = function () {
|
|
@@ -89,12 +96,11 @@ server.prototype.self = function () {
|
|
|
89
96
|
// #region Runtimes
|
|
90
97
|
// Node.js
|
|
91
98
|
server.prototype.node = async function () {
|
|
92
|
-
const options = config(this.opts);
|
|
93
99
|
const http = await import("http");
|
|
94
100
|
http
|
|
95
101
|
.createServer(async (request, response) => {
|
|
96
102
|
try {
|
|
97
|
-
const ctx = await createNodeContext(request,
|
|
103
|
+
const ctx = await createNodeContext(request, this.opts, this);
|
|
98
104
|
const out = await handleRequest(this.handlers, ctx);
|
|
99
105
|
|
|
100
106
|
response.writeHead(out.status || 200, parseHeaders(out.headers));
|
|
@@ -121,8 +127,7 @@ server.prototype.callback = async function (request, context) {
|
|
|
121
127
|
if (typeof Netlify === "undefined") {
|
|
122
128
|
throw new Error("Netlify doesn't exist");
|
|
123
129
|
}
|
|
124
|
-
const
|
|
125
|
-
const ctx = await createWinterContext(request, options, this);
|
|
130
|
+
const ctx = await createWinterContext(request, this.opts, this);
|
|
126
131
|
return await handleRequest(this.handlers, ctx);
|
|
127
132
|
} catch (error) {
|
|
128
133
|
return new Response(error.message, { status: error.status || 500 });
|
|
@@ -135,8 +140,7 @@ server.prototype.fetch = async function (request, env) {
|
|
|
135
140
|
Object.assign(globalThis.env, env); // Extend env with the passed vars
|
|
136
141
|
|
|
137
142
|
try {
|
|
138
|
-
const
|
|
139
|
-
const ctx = await createWinterContext(request, options, this);
|
|
143
|
+
const ctx = await createWinterContext(request, this.opts, this);
|
|
140
144
|
return await handleRequest(this.handlers, ctx);
|
|
141
145
|
} catch (error) {
|
|
142
146
|
return new Response(error.message, { status: error.status || 500 });
|
|
@@ -146,6 +150,8 @@ server.prototype.fetch = async function (request, env) {
|
|
|
146
150
|
// #region HTTP methods
|
|
147
151
|
// INTERNAL
|
|
148
152
|
server.prototype.handle = function (method, path, ...middleware) {
|
|
153
|
+
// Do not try to optimize, we NEED the method to remain '*' here so that
|
|
154
|
+
// it doesn't auto-finish
|
|
149
155
|
if (method === "*") {
|
|
150
156
|
for (let m in this.handlers) {
|
|
151
157
|
this.handlers[m].push([method, path, ...middleware]);
|
|
@@ -224,17 +230,17 @@ server.prototype.test = function () {
|
|
|
224
230
|
);
|
|
225
231
|
|
|
226
232
|
const headers = parseHeaders(res.headers);
|
|
227
|
-
let
|
|
233
|
+
let body;
|
|
228
234
|
if (headers["set-cookie"]) {
|
|
229
235
|
// TODO: this should really be a smart merge of the 2
|
|
230
236
|
cookie = headers["set-cookie"];
|
|
231
237
|
}
|
|
232
238
|
if (headers["content-type"]?.includes("application/json")) {
|
|
233
|
-
|
|
239
|
+
body = await res.json();
|
|
234
240
|
} else {
|
|
235
|
-
|
|
241
|
+
body = await res.text();
|
|
236
242
|
}
|
|
237
|
-
return { status: res.status, headers, data };
|
|
243
|
+
return { status: res.status, headers, body, data: body };
|
|
238
244
|
};
|
|
239
245
|
return {
|
|
240
246
|
app: this,
|
package/src/middle/assets.js
CHANGED
package/src/middle/index.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import authMod from "../auth/index.js";
|
|
2
2
|
import assets from "./assets.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (ctx.options.public) {
|
|
7
|
-
// We need these before other endpoints
|
|
8
|
-
ctx.app.handlers.get.unshift(["*", "*", assets]);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
await auth.middle(ctx);
|
|
12
|
-
}
|
|
4
|
+
const auth = authMod.middle;
|
|
5
|
+
export { assets, auth };
|
package/src/router.test.js
CHANGED
|
@@ -15,7 +15,7 @@ describe("can route properly", () => {
|
|
|
15
15
|
// INTERNAL - so this might change in the future
|
|
16
16
|
it("has the correct structure", () => {
|
|
17
17
|
const registeredPaths = app.handlers.get.map((h) => h[1]);
|
|
18
|
-
expect(registeredPaths).toEqual(["/hello", "/api/hello", "/"]);
|
|
18
|
+
expect(registeredPaths).toEqual(["*", "/hello", "/api/hello", "/"]);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it("can get fallback when nothing matches", async () => {
|