@imenam/mcp-feature-analyzer 1.0.0 → 1.0.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/README.md CHANGED
@@ -259,11 +259,11 @@ Le serveur lance `git` sans shell, uniquement en lecture (`rev-parse`, `diff`, `
259
259
 
260
260
  ### Exposition réseau de la GUI
261
261
 
262
- La GUI montre le code des dépôts analysés et ses retours sont lus par l'agent : elle n'est joignable que depuis la machine elle-même (`src/core/request-guard.ts`).
262
+ La GUI montre le code des dépôts analysés et ses retours sont lus par l'agent : elle n'est joignable que depuis la machine elle-même, avec la garde de requêtes de `@imenam/mcp-gui-interface` (`honoGuiGuard`).
263
263
 
264
- - Le worker écoute sur `127.0.0.1` uniquement. Le proxy le joint par `localhost` ; l'accès depuis un autre poste passe par le proxy et son authentification.
265
- - L'en-tête `Host` doit désigner la boucle locale, la machine (nom ou adresse) ou l'hôte du proxy : une page tierce qui fait pointer son propre domaine vers `127.0.0.1` est refusée (`403`).
266
- - Une requête de modification exige `Content-Type: application/json` (`415` sinon) et, quand le navigateur envoie un en-tête `Origin`, la même origine que l'hôte appelé (`403` sinon) : une page web ouverte dans le navigateur ne peut pas soumettre de revue à la place du relecteur.
264
+ - Le worker écoute sur `127.0.0.1` uniquement (`GUI_LISTEN_HOST`). L'accès depuis un autre poste passe par le proxy ou le gateway manager et leur authentification ; tous deux relaient vers `localhost:<port>`.
265
+ - L'en-tête `Host` doit désigner la boucle locale : une page tierce qui fait pointer son propre domaine vers `127.0.0.1` est refusée (`403`).
266
+ - Une requête de modification venant d'un autre site est refusée (`403`) : `Sec-Fetch-Site` doit valoir `same-origin` ou `none` et, en son absence, l'hôte de l'`Origin` doit être la machine ou le proxy. Une page web ouverte dans le navigateur ne peut pas soumettre de revue à la place du relecteur.
267
267
 
268
268
  ---
269
269
 
@@ -2,14 +2,13 @@ import { serve } from "@hono/node-server";
2
2
  import { serveStatic } from "@hono/node-server/serve-static";
3
3
  import { Hono } from "hono";
4
4
  import { streamSSE } from "hono/streaming";
5
- import { ProxyClient, createLogger, setupLogging } from "@imenam/mcp-gui-interface";
5
+ import { GUI_LISTEN_HOST, ProxyClient, createLogger, honoGuiGuard, setupLogging } from "@imenam/mcp-gui-interface";
6
6
  import path from "path";
7
7
  import fs from "fs";
8
8
  import { fileURLToPath } from "url";
9
9
  import { IPCMessageSchema, PUSHED_EVENT_TYPES } from "../shared/schemas/ipc.schema.js";
10
10
  import { AddNoteBodySchema, DeleteNoteBodySchema, SetFileReviewedBodySchema, SetFindingStatusBodySchema, SubmitReviewBodySchema, } from "../shared/schemas/api.schema.js";
11
11
  import { resolveLogDir } from "./core/log-dir.js";
12
- import { LISTEN_HOST, allowedHostnames, checkRequest } from "./core/request-guard.js";
13
12
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
13
  function findProjectRoot(startDir) {
15
14
  let current = startDir;
@@ -78,20 +77,7 @@ const parentCheckInterval = setInterval(() => {
78
77
  }, 2000);
79
78
  const app = new Hono();
80
79
  // Contrôle de l'hôte appelé et des requêtes de modification, avant toute route.
81
- const allowedHosts = allowedHostnames(guiMode.kind === "proxy" ? guiMode.proxyUrl : undefined);
82
- app.use("*", async (c, next) => {
83
- const rejection = checkRequest({
84
- method: c.req.method,
85
- host: c.req.header("host"),
86
- origin: c.req.header("origin"),
87
- contentType: c.req.header("content-type"),
88
- }, allowedHosts);
89
- if (rejection !== null) {
90
- logger.warn(`Request refused (${rejection.status}) ${c.req.method} ${c.req.path}: ${rejection.error}`);
91
- return c.json({ error: rejection.error }, rejection.status);
92
- }
93
- await next();
94
- });
80
+ app.use("*", honoGuiGuard({ proxyUrl: guiMode.kind === "proxy" ? guiMode.proxyUrl : undefined }));
95
81
  let proxyClient = null;
96
82
  const sseStreams = new Set();
97
83
  const pendingRequests = new Map();
@@ -311,8 +297,8 @@ app.get("/*", (c, next) => {
311
297
  * l'utilisateur ouvre : via le proxy, ou directement en localhost.
312
298
  */
313
299
  function listen(port, publicUrl, isProxied) {
314
- const serverInstance = serve({ fetch: app.fetch, port, hostname: LISTEN_HOST }, (info) => {
315
- logger.info(`Feature Analyzer GUI listening on port ${info.port} (${LISTEN_HOST})`);
300
+ const serverInstance = serve({ fetch: app.fetch, port, hostname: GUI_LISTEN_HOST }, (info) => {
301
+ logger.info(`Feature Analyzer GUI listening on port ${info.port} (${GUI_LISTEN_HOST})`);
316
302
  safeSend(IPCMessageSchema.parse({
317
303
  type: "READY",
318
304
  data: { port: info.port, isProxied, url: publicUrl },
@@ -1 +1 @@
1
- export declare const APP_VERSION = "1.0.0";
1
+ export declare const APP_VERSION = "1.0.1";
@@ -1,2 +1,2 @@
1
1
  // Auto-generated version file - do not edit manually
2
- export const APP_VERSION = '1.0.0';
2
+ export const APP_VERSION = '1.0.1';