botnote 0.1.51 → 0.1.53
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/README.md +67 -17
- package/dist/bin.js +22 -17
- package/dist/bin.js.map +1 -1
- package/dist/cli.js +12 -10
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +28 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/mcp/http-client.js +12 -5
- package/dist/mcp/http-client.js.map +1 -1
- package/dist/mcp/server.js +4 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/rest/auth.d.ts +47 -0
- package/dist/rest/auth.js +116 -0
- package/dist/rest/auth.js.map +1 -0
- package/dist/rest/routes.js +10 -12
- package/dist/rest/routes.js.map +1 -1
- package/dist/rest/server.d.ts +4 -1
- package/dist/rest/server.js +24 -53
- package/dist/rest/server.js.map +1 -1
- package/package.json +1 -1
- package/web/dist/assets/{index-Bb8Ou6Tf.js → index-2lPPOtvF.js} +54 -54
- package/web/dist/index.html +1 -1
package/dist/rest/server.js
CHANGED
|
@@ -9,9 +9,11 @@ import path from "node:path";
|
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
import Fastify from "fastify";
|
|
11
11
|
import { hasZodFastifySchemaValidationErrors, isResponseSerializationError, jsonSchemaTransform, serializerCompiler, validatorCompiler } from "fastify-type-provider-zod";
|
|
12
|
+
import { corsOrigins, DEFAULT_PORT, envValue } from "../config.js";
|
|
12
13
|
import { consumeSession } from "../service/sessions.js";
|
|
13
14
|
import { consumeToken } from "../service/tokens.js";
|
|
14
15
|
import { VERSION } from "../version.js";
|
|
16
|
+
import { authConfigFromEnv, clientIp, describeAuthConfig, isTrustedProxy, isTrustedWithoutCredential } from "./auth.js";
|
|
15
17
|
import { registerRoutes } from "./routes.js";
|
|
16
18
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
19
|
function resolveWebDist(explicit) {
|
|
@@ -28,42 +30,16 @@ function resolveWebDist(explicit) {
|
|
|
28
30
|
}
|
|
29
31
|
return null;
|
|
30
32
|
}
|
|
31
|
-
/** Default CORS allowlist. Add public origins via BOTNOTE_CORS_ORIGINS
|
|
32
|
-
* (comma-separated). Localhost stays enabled for daemon access. */
|
|
33
|
-
function defaultCorsOrigins() {
|
|
34
|
-
const built = [
|
|
35
|
-
"http://127.0.0.1:4280",
|
|
36
|
-
"http://localhost:4280",
|
|
37
|
-
"https://botnote.net"
|
|
38
|
-
];
|
|
39
|
-
const extra = process.env.BOTNOTE_CORS_ORIGINS;
|
|
40
|
-
if (extra) {
|
|
41
|
-
for (const o of extra.split(",").map((s) => s.trim()).filter(Boolean)) {
|
|
42
|
-
if (!built.includes(o))
|
|
43
|
-
built.push(o);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return built;
|
|
47
|
-
}
|
|
48
|
-
/** Read the caller's real IP. cf-connecting-ip is set by Cloudflare for every
|
|
49
|
-
* request that goes through CF Tunnel — without it, rate-limit would key on
|
|
50
|
-
* the tunnel's loopback address and the whole world would share one bucket. */
|
|
51
|
-
function clientIp(req) {
|
|
52
|
-
const cf = req.headers["cf-connecting-ip"];
|
|
53
|
-
if (typeof cf === "string" && cf)
|
|
54
|
-
return cf;
|
|
55
|
-
const xff = req.headers["x-forwarded-for"];
|
|
56
|
-
if (typeof xff === "string" && xff)
|
|
57
|
-
return xff.split(",")[0].trim();
|
|
58
|
-
return req.ip;
|
|
59
|
-
}
|
|
60
33
|
export async function buildServer(opts) {
|
|
61
34
|
const isProduction = process.env.NODE_ENV === "production";
|
|
35
|
+
const auth = opts.auth ?? authConfigFromEnv();
|
|
62
36
|
const app = Fastify({
|
|
63
37
|
logger: { level: opts.logLevel ?? "info" },
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
|
|
38
|
+
// Only peers listed in BOTNOTE_TRUST_PROXY may rewrite req.ip through
|
|
39
|
+
// x-forwarded-for. cf-connecting-ip is handled by clientIp() with the
|
|
40
|
+
// same peer check, because Cloudflare's tunnel connects from loopback and
|
|
41
|
+
// without it the whole internet would share one rate-limit bucket.
|
|
42
|
+
trustProxy: (address) => isTrustedProxy(address, auth.trustedProxies)
|
|
67
43
|
}).withTypeProvider();
|
|
68
44
|
app.setValidatorCompiler(validatorCompiler);
|
|
69
45
|
app.setSerializerCompiler(serializerCompiler);
|
|
@@ -74,7 +50,7 @@ export async function buildServer(opts) {
|
|
|
74
50
|
hook: "onRequest"
|
|
75
51
|
});
|
|
76
52
|
await app.register(cors, {
|
|
77
|
-
origin:
|
|
53
|
+
origin: corsOrigins(),
|
|
78
54
|
// credentials: true so cookies can be sent across origins (browser will
|
|
79
55
|
// refuse to attach cookies on a fetch to a different origin otherwise).
|
|
80
56
|
credentials: true,
|
|
@@ -88,7 +64,7 @@ export async function buildServer(opts) {
|
|
|
88
64
|
// leaked token can't quietly exfil thousands of entities per second.
|
|
89
65
|
max: 1000,
|
|
90
66
|
timeWindow: "1 minute",
|
|
91
|
-
keyGenerator: (req) => clientIp(req),
|
|
67
|
+
keyGenerator: (req) => clientIp(req, auth),
|
|
92
68
|
// /health is a probe; /assets/* are dozens of static files per page load.
|
|
93
69
|
// Counting them would cap real API headroom for no benefit.
|
|
94
70
|
allowList: (req) => {
|
|
@@ -111,7 +87,7 @@ export async function buildServer(opts) {
|
|
|
111
87
|
},
|
|
112
88
|
servers: [
|
|
113
89
|
{
|
|
114
|
-
url: `http://localhost:${process.env.BOTNOTE_PORT ??
|
|
90
|
+
url: `http://localhost:${envValue(process.env.BOTNOTE_PORT) ?? DEFAULT_PORT}`,
|
|
115
91
|
description: "local"
|
|
116
92
|
}
|
|
117
93
|
],
|
|
@@ -178,13 +154,12 @@ export async function buildServer(opts) {
|
|
|
178
154
|
return reply.code(500).send({ error: "server_error" });
|
|
179
155
|
});
|
|
180
156
|
// ----- auth -----
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
if (requireAuth) {
|
|
157
|
+
// Every /v1 request needs a session cookie or bearer token, except a direct
|
|
158
|
+
// loopback connection when BOTNOTE_TRUST_LOCALHOST is on. Whether a request
|
|
159
|
+
// is "loopback" is decided by the TCP peer address, never by headers: a LAN
|
|
160
|
+
// client hitting a 0.0.0.0 bind gets the same gate as the public internet,
|
|
161
|
+
// and forged x-forwarded-for from an untrusted peer changes nothing.
|
|
162
|
+
if (auth.required) {
|
|
188
163
|
// IMPORTANT: register at onRequest, not preHandler. fastify-type-provider-zod
|
|
189
164
|
// runs schema validation at preValidation, which is BEFORE preHandler — so
|
|
190
165
|
// a preHandler auth gate lets an unauthenticated POST get a 400 zod error
|
|
@@ -200,9 +175,8 @@ export async function buildServer(opts) {
|
|
|
200
175
|
req.url.startsWith("/v1/auth/logout")) {
|
|
201
176
|
return;
|
|
202
177
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return; // direct private-network/localhost access is trusted
|
|
178
|
+
if (isTrustedWithoutCredential(req, auth))
|
|
179
|
+
return;
|
|
206
180
|
// Browser path: session cookie set by /v1/auth/login.
|
|
207
181
|
const cookieToken = req.cookies?.botnote_session;
|
|
208
182
|
if (cookieToken) {
|
|
@@ -211,21 +185,18 @@ export async function buildServer(opts) {
|
|
|
211
185
|
return;
|
|
212
186
|
}
|
|
213
187
|
// CLI / MCP path: bearer token.
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
-
const plaintext =
|
|
188
|
+
const authHeader = req.headers.authorization;
|
|
189
|
+
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
190
|
+
const plaintext = authHeader.slice("Bearer ".length).trim();
|
|
217
191
|
const tok = await consumeToken(opts.db, plaintext);
|
|
218
192
|
if (tok)
|
|
219
193
|
return;
|
|
220
194
|
}
|
|
221
195
|
return reply.code(401).send({ error: "unauthenticated" });
|
|
222
196
|
});
|
|
223
|
-
app.log.info("auth: required for /v1/* via reverse proxy (cookie or bearer; direct access trusted)");
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
app.log.info("auth: disabled (set BOTNOTE_REQUIRE_AUTH=1 to enforce)");
|
|
227
197
|
}
|
|
228
|
-
|
|
198
|
+
app.log.info(describeAuthConfig(auth));
|
|
199
|
+
await registerRoutes(app, { db: opts.db, embedding: opts.embedding, auth });
|
|
229
200
|
const webDist = resolveWebDist(opts.webDist);
|
|
230
201
|
if (webDist) {
|
|
231
202
|
await app.register(fastifyStatic, {
|
package/dist/rest/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/rest/server.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,IAAI,MAAM,eAAe,CAAC;AACjC,OAAO,SAAS,MAAM,qBAAqB,CAAC;AAC5C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,SAAS,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,OAAsD,MAAM,SAAS,CAAC;AAC7E,OAAO,EACL,mCAAmC,EACnC,4BAA4B,EAC5B,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/rest/server.ts"],"names":[],"mappings":"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"}
|