@sanctuary-framework/mcp-server 0.10.1 → 0.10.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/dist/cli.cjs +100 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +100 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +44 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8703,6 +8703,24 @@ var DashboardApprovalChannel = class {
|
|
|
8703
8703
|
rateLimits = /* @__PURE__ */ new Map();
|
|
8704
8704
|
/** Whether the dashboard is running in standalone mode (no MCP server) */
|
|
8705
8705
|
_standaloneMode = false;
|
|
8706
|
+
/**
|
|
8707
|
+
* v0.10.2: when set, requests from loopback addresses (127.0.0.1 / ::1)
|
|
8708
|
+
* are treated as authenticated without requiring a Bearer token or
|
|
8709
|
+
* dashboard session cookie. Only the `startStandaloneDashboard` boot
|
|
8710
|
+
* path enables this, and ONLY after the supplied passphrase successfully
|
|
8711
|
+
* decrypts at least one stored identity — proving the caller already
|
|
8712
|
+
* holds the primary secret that protects every piece of Sanctuary state.
|
|
8713
|
+
*
|
|
8714
|
+
* Rationale: the dashboard auth token is a dashboard-access credential
|
|
8715
|
+
* layered on top of the master-key unlock. Once the operator has already
|
|
8716
|
+
* presented the passphrase on the command line (terminal-side auth), a
|
|
8717
|
+
* second login prompt in the auto-opened browser just trains users to
|
|
8718
|
+
* paste secrets into web forms — the exact habit Sanctuary exists to
|
|
8719
|
+
* discourage. Remote (non-loopback) callers still require the bearer
|
|
8720
|
+
* token, so this is a localhost-only ergonomics unlock, not a network
|
|
8721
|
+
* policy change.
|
|
8722
|
+
*/
|
|
8723
|
+
_autoAuthLocalhost = false;
|
|
8706
8724
|
constructor(config) {
|
|
8707
8725
|
this.config = config;
|
|
8708
8726
|
this.authToken = config.auth_token;
|
|
@@ -8738,6 +8756,26 @@ var DashboardApprovalChannel = class {
|
|
|
8738
8756
|
setStandaloneMode(standalone) {
|
|
8739
8757
|
this._standaloneMode = standalone;
|
|
8740
8758
|
}
|
|
8759
|
+
/**
|
|
8760
|
+
* v0.10.2: enable (or disable) the loopback auto-auth fast path. See
|
|
8761
|
+
* {@link _autoAuthLocalhost} for the rationale and threat model. Callers
|
|
8762
|
+
* should gate this on both (a) the dashboard host being a loopback
|
|
8763
|
+
* interface and (b) the master-key unlock having succeeded against
|
|
8764
|
+
* on-disk state.
|
|
8765
|
+
*/
|
|
8766
|
+
setAutoAuthLocalhost(enabled) {
|
|
8767
|
+
this._autoAuthLocalhost = enabled;
|
|
8768
|
+
}
|
|
8769
|
+
/**
|
|
8770
|
+
* v0.10.2: is this request from a loopback interface? We treat the
|
|
8771
|
+
* standard IPv4/IPv6 loopback addresses plus the IPv4-mapped IPv6 form
|
|
8772
|
+
* as loopback so LAN clients never accidentally hit the unauthenticated
|
|
8773
|
+
* fast path even on hosts where the HTTP server binds 0.0.0.0.
|
|
8774
|
+
*/
|
|
8775
|
+
isLoopbackRequest(req) {
|
|
8776
|
+
const addr = this.getRemoteAddr(req);
|
|
8777
|
+
return addr === "127.0.0.1" || addr === "::1" || addr === "localhost";
|
|
8778
|
+
}
|
|
8741
8779
|
/**
|
|
8742
8780
|
* Start the HTTP(S) server for the dashboard.
|
|
8743
8781
|
*/
|
|
@@ -8887,6 +8925,9 @@ var DashboardApprovalChannel = class {
|
|
|
8887
8925
|
*/
|
|
8888
8926
|
checkAuth(req, url, res) {
|
|
8889
8927
|
if (!this.authToken) return true;
|
|
8928
|
+
if (this._autoAuthLocalhost && this.isLoopbackRequest(req)) {
|
|
8929
|
+
return true;
|
|
8930
|
+
}
|
|
8890
8931
|
const authHeader = req.headers.authorization;
|
|
8891
8932
|
if (authHeader) {
|
|
8892
8933
|
const parts = authHeader.split(" ");
|
|
@@ -8912,6 +8953,9 @@ var DashboardApprovalChannel = class {
|
|
|
8912
8953
|
*/
|
|
8913
8954
|
isAuthenticated(req, url) {
|
|
8914
8955
|
if (!this.authToken) return true;
|
|
8956
|
+
if (this._autoAuthLocalhost && this.isLoopbackRequest(req)) {
|
|
8957
|
+
return true;
|
|
8958
|
+
}
|
|
8915
8959
|
const authHeader = req.headers.authorization;
|
|
8916
8960
|
if (authHeader) {
|
|
8917
8961
|
const parts = authHeader.split(" ");
|