uade-mcp 0.2.0 → 0.2.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/README.md +2 -1
- package/SECURITY.md +17 -6
- package/dist/auth/login.js +8 -0
- package/dist/auth/login.js.map +1 -1
- package/dist/error-de-uso.js +11 -0
- package/dist/error-de-uso.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/net/browser.js +2 -1
- package/dist/net/browser.js.map +1 -1
- package/dist/net/open-browser.js +47 -9
- package/dist/net/open-browser.js.map +1 -1
- package/dist/net/policy.js +9 -1
- package/dist/net/policy.js.map +1 -1
- package/dist/report/errores.js +17 -6
- package/dist/report/errores.js.map +1 -1
- package/dist/sources/docs/leer.js +9 -1
- package/dist/sources/docs/leer.js.map +1 -1
- package/dist/sources/docs/pdf-imagenes.js +114 -20
- package/dist/sources/docs/pdf-imagenes.js.map +1 -1
- package/dist/sources/mail/draft.js +3 -2
- package/dist/sources/mail/draft.js.map +1 -1
- package/dist/sources/pia/alta.js +4 -3
- package/dist/sources/pia/alta.js.map +1 -1
- package/dist/sources/pia/index.js +4 -3
- package/dist/sources/pia/index.js.map +1 -1
- package/dist/sources/pia/parse.js +2 -1
- package/dist/sources/pia/parse.js.map +1 -1
- package/dist/sources/planificador/index.js +14 -2
- package/dist/sources/planificador/index.js.map +1 -1
- package/dist/sources/sharepoint/index.js +16 -4
- package/dist/sources/sharepoint/index.js.map +1 -1
- package/dist/sources/teams/index.js +5 -3
- package/dist/sources/teams/index.js.map +1 -1
- package/dist/sources/webcampus/index.js +2 -1
- package/dist/sources/webcampus/index.js.map +1 -1
- package/dist/sources/webcampus/previos.js +3 -3
- package/dist/sources/webcampus/previos.js.map +1 -1
- package/dist/tools/common.js +2 -1
- package/dist/tools/common.js.map +1 -1
- package/dist/tools/materiales.js +64 -32
- package/dist/tools/materiales.js.map +1 -1
- package/dist/tools/novedades.js +4 -3
- package/dist/tools/novedades.js.map +1 -1
- package/dist/tools/pia.js +1 -1
- package/dist/tools/pia.js.map +1 -1
- package/dist/tools/secciones.js +2 -1
- package/dist/tools/secciones.js.map +1 -1
- package/dist/tools/teams.js +3 -2
- package/dist/tools/teams.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,7 +77,8 @@ que responda en castellano rioplatense, con fechas dd/mm/aaaa y horas de 24 h.
|
|
|
77
77
|
| `webcampus_attendance` | Presentes, faltas y detalle por clase |
|
|
78
78
|
| `webcampus_course_calendar` | Fechas de parciales, recuperatorio y final de cada materia |
|
|
79
79
|
| `webcampus_teachers` | Nombre y mail del equipo docente (nunca datos de compañeros) |
|
|
80
|
-
| `webcampus_course_materials` | Lista
|
|
80
|
+
| `webcampus_course_materials` | Lista y lee (PDF, Word, Excel, PowerPoint) los apuntes de "Materiales de clase"; no escribe nada |
|
|
81
|
+
| `webcampus_save_material` | Guarda una copia de un apunte en `Downloads/uade-mcp` (nunca pisa un archivo) |
|
|
81
82
|
| `teams_channel_news` | Lo último que se publicó en el canal General de una materia (experimental) |
|
|
82
83
|
| `webcampus_consultation_classes` | Clases de consulta programadas para tu carrera: materias, días y horarios |
|
|
83
84
|
|
package/SECURITY.md
CHANGED
|
@@ -13,16 +13,18 @@ No abras un issue público para temas de seguridad.
|
|
|
13
13
|
| Bloqueos fijos (pagos, bajas, desvincularse, datos personales, buscador de personas, cerrar sesión) en URLs y postbacks | `src/net/policy.ts`, `src/net/session.ts` | `test/policy.test.ts`, `test/auditoria.test.ts` |
|
|
14
14
|
| Cookies y headers solo al host que corresponde; nada sale del origen de cada sitio | `src/net/http.ts`, `src/net/session.ts` | `test/webcampus-client.test.ts` |
|
|
15
15
|
| Nunca ve la contraseña: el login lo hace la persona en la página de Microsoft | `src/auth/login.ts` | — |
|
|
16
|
-
| Sesiones en el llavero; perfil de navegador propio en `~/.uade-mcp/browser-profile
|
|
16
|
+
| Sesiones en el llavero; perfil de navegador propio en `~/.uade-mcp/browser-profile`, cifrado con el llavero del sistema (sin el llavero de mentira de Playwright); `logout` borra todo | `src/auth/`, `src/cli/index.ts` | `test/auditoria.test.ts` |
|
|
17
17
|
| Renovación automática de sesión: una por pedido vencido, sin bucles | `src/net/session.ts` | `test/login.test.ts` |
|
|
18
18
|
| Copia local cifrada (AES-256-GCM, clave en el llavero) | `src/cache/cache.ts` | `test/cache.test.ts` |
|
|
19
19
|
| Nunca datos de compañeros (lista blanca de roles docentes) | `src/sources/webcampus/parse.ts` | `test/auditoria.test.ts` |
|
|
20
|
-
| Texto de terceros marcado como información, no instrucciones | `src/untrusted.ts`, `src/tools/*` | `test/auditoria.test.ts` |
|
|
20
|
+
| Texto de terceros marcado como información, no instrucciones: campo `aviso` en los resultados estructurados y bloque `<contenido_externo>` alrededor del texto plano (documentos, adjuntos, modo degradado) | `src/untrusted.ts`, `src/tools/*` | `test/auditoria.test.ts` |
|
|
21
21
|
| No envía inscripciones: el resumen es de lectura y la ventana de Inscripciones la usa la persona | `src/sources/pia/alta.ts`, `src/tools/pia.ts` | `test/pia.test.ts` |
|
|
22
22
|
| Mails solo como borrador a @uade.edu.ar; adjuntos solo de carpetas de documentos | `src/sources/mail/draft.ts`, `src/net/open-browser.ts` | `test/common.test.ts` |
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
23
|
+
| Lo único que escribe en tu disco va a `Downloads/uade-mcp`: nombre saneado, solo tipos de documento, nunca pisa un archivo, legible solo por vos; las tools que escriben o abren una ventana no se anuncian como solo lectura | `src/net/open-browser.ts`, `src/tools/materiales.ts`, `src/tools/pia.ts` | `test/materiales.test.ts`, `test/auditoria.test.ts` |
|
|
24
|
+
| Rutas de SharePoint ancladas a la carpeta habilitada; `folder` no acepta `..`, `.` ni segmentos vacíos | `src/sources/sharepoint/index.ts`, `src/tools/materiales.ts` | `test/materiales.test.ts` |
|
|
25
|
+
| Topes: 10 MB y 20 s por pedido, 5 redirecciones, 80 páginas por PDF, 60 MB descomprimidos por archivo contando bytes reales (xlsx, docx, pptx) y por PDF escaneado (imágenes, con tope por imagen); los PDFs se recorren en tiempo lineal | `src/sources/docs/`, `src/sources/webcampus/previos.ts` | `test/previos.test.ts`, `test/materiales.test.ts`, `test/pdf-imagenes.test.ts` |
|
|
26
|
+
| Reporte de errores opt-in (`reportes.errores`): campos fijos (versión, tool, tipo, página); el mensaje viaja solo de errores técnicos y tapado (mails, números largos, rutas, comillas); de los errores que nombran materias, archivos o carreras (`ErrorDeUso`) va solo el tipo; un envío por tool, tipo y página por día; único path permitido en planuade.ar | `src/report/errores.ts`, `src/error-de-uso.ts`, `src/net/policy.ts` | `test/reportes.test.ts` |
|
|
27
|
+
| Sin telemetría; dependencias directas con versión exacta (npm 12 ignora `npm-shrinkwrap.json`, así que las transitivas las fija el lockfile solo en desarrollo y CI); `npm audit` en cada commit | `package.json`, `.github/workflows/publicar.yml`, `scripts/revisar.mjs` | hook pre-commit, CI |
|
|
26
28
|
|
|
27
29
|
La auditoría completa (hallazgos, controles OWASP, NIST y ISO 27001, riesgos aceptados) está en
|
|
28
30
|
[docs/AUDITORIA.md](docs/AUDITORIA.md).
|
|
@@ -46,7 +48,10 @@ La auditoría completa (hallazgos, controles OWASP, NIST y ISO 27001, riesgos ac
|
|
|
46
48
|
- **Dependabot** avisa (y propone el PR) ante vulnerabilidades en dependencias o acciones; el escaneo de
|
|
47
49
|
secretos de GitHub, con protección al push, bloquea tokens que intenten entrar.
|
|
48
50
|
- **Dependencias con versión exacta** y `package-lock.json`; `npm ci --ignore-scripts` en CI: ninguna
|
|
49
|
-
dependencia corre código al instalarse.
|
|
51
|
+
dependencia corre código al instalarse. Límite conocido: npm 12, que es el que exige la publicación
|
|
52
|
+
en staging, no incluye ni respeta `npm-shrinkwrap.json`, así que `npx -y uade-mcp` fija las
|
|
53
|
+
dependencias directas (versión exacta en `package.json`) pero resuelve las transitivas al instalar.
|
|
54
|
+
`npm audit` corre en cada commit y en CI.
|
|
50
55
|
|
|
51
56
|
## Lo que queda fuera de estas garantías
|
|
52
57
|
|
|
@@ -54,6 +59,12 @@ La auditoría completa (hallazgos, controles OWASP, NIST y ISO 27001, riesgos ac
|
|
|
54
59
|
y git la ignora. Lo que corras ahí corre con tus credenciales y bajo tu responsabilidad.
|
|
55
60
|
- **Teams** se lee corriendo el Teams web real en el navegador del MCP: contacta dominios de Microsoft,
|
|
56
61
|
como si lo abrieras vos, y puede dejar de funcionar si Microsoft cambia la interfaz.
|
|
62
|
+
- **La sesión persistente de Microsoft** ("¿Mantener la sesión iniciada?" → Sí) vive en el perfil de
|
|
63
|
+
navegador del MCP, cifrada con el llavero del sistema. Esa sesión (`ESTSAUTHPERSISTENT`) y la cookie
|
|
64
|
+
`rtFa` de SharePoint no son solo de WebCampus: valen para todo Microsoft 365 de tu cuenta de UADE (mail,
|
|
65
|
+
Teams, OneDrive). El MCP solo las usa en los sitios de su allowlist, pero quien controle tu usuario de la
|
|
66
|
+
compu puede usarlas igual que vos. Por eso `uade-mcp logout` borra el perfil y el llavero, y conviene
|
|
67
|
+
correrlo en una compu compartida.
|
|
57
68
|
|
|
58
69
|
## Reglas para contribuir
|
|
59
70
|
|
package/dist/auth/login.js
CHANGED
|
@@ -17,6 +17,12 @@ import { SESSION_ACCOUNT, WEBCAMPUS } from '../sources/webcampus/client.js';
|
|
|
17
17
|
import { configDir } from './permissions.js';
|
|
18
18
|
import { saveSession } from './store.js';
|
|
19
19
|
const INTERACTIVO_MS = 10 * 60 * 1000;
|
|
20
|
+
// Playwright arranca Chromium con un llavero de mentira (--use-mock-keychain / --password-store=basic):
|
|
21
|
+
// las cookies del perfil quedan cifradas con una clave fija que cualquier programa conoce. Sin esos
|
|
22
|
+
// flags, el navegador usa el llavero del sistema ("Chrome Safe Storage" en macOS), como cuando lo
|
|
23
|
+
// abrís vos. Las cookies de UADE (WebCampus, Inscripciones, SharePoint) ya iban al llavero; esto cubre
|
|
24
|
+
// la sesión persistente de Microsoft que vive en el perfil.
|
|
25
|
+
export const SIN_LLAVERO_FALSO = ['--use-mock-keychain', '--password-store=basic'];
|
|
20
26
|
const SILENCIOSO_MS = 45 * 1000;
|
|
21
27
|
// Cookies de analytics que no hacen falta para la sesión y no guardamos.
|
|
22
28
|
const TRACKING = /^(_ga|_gid|_hj|__utm|_fbp|_gcl|ai_user|ai_session)/;
|
|
@@ -56,6 +62,7 @@ export async function abrirInscripciones() {
|
|
|
56
62
|
executablePath: findBrowser(),
|
|
57
63
|
headless: false,
|
|
58
64
|
viewport: null,
|
|
65
|
+
ignoreDefaultArgs: SIN_LLAVERO_FALSO,
|
|
59
66
|
args: ['--no-first-run', '--no-default-browser-check', '--start-maximized'],
|
|
60
67
|
});
|
|
61
68
|
ventana.on('close', () => { ventana = null; });
|
|
@@ -77,6 +84,7 @@ async function correr(op) {
|
|
|
77
84
|
const ctx = ventana ?? (await chromium.launchPersistentContext(browserProfileDir(), {
|
|
78
85
|
executablePath,
|
|
79
86
|
headless: !op.interactivo,
|
|
87
|
+
ignoreDefaultArgs: SIN_LLAVERO_FALSO,
|
|
80
88
|
args: ['--no-first-run', '--no-default-browser-check'],
|
|
81
89
|
}));
|
|
82
90
|
const guardadas = [];
|
package/dist/auth/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,gGAAgG;AAChG,8DAA8D;AAC9D,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,sGAAsG;AACtG,kGAAkG;AAClG,mDAAmD;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAuB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Error cuyo mensaje lleva datos del estudiante o contenido de UADE (nombre de una materia, de un
|
|
2
|
+
// archivo, de una carrera, texto de PIA): se le muestra a la persona tal cual, pero el reporte de
|
|
3
|
+
// errores opcional (src/report/errores.ts) manda solo el tipo, nunca el mensaje. Todo mensaje que
|
|
4
|
+
// interpole algo leído de la cuenta tiene que ser de esta clase (lo controla test/reportes.test.ts).
|
|
5
|
+
export class ErrorDeUso extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'ErrorDeUso';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=error-de-uso.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-de-uso.js","sourceRoot":"","sources":["../src/error-de-uso.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,kGAAkG;AAClG,kGAAkG;AAClG,qGAAqG;AACrG,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ if (args.length) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
|
-
const server = new McpServer({ name: 'uade-mcp', version: '0.2.
|
|
34
|
+
const server = new McpServer({ name: 'uade-mcp', version: '0.2.2' }, {
|
|
35
35
|
instructions: [
|
|
36
36
|
'Unofficial MCP for UADE (Universidad Argentina de la Empresa, Buenos Aires). All tools are read-only and read live data; prefer them over memory.',
|
|
37
37
|
'Answer in Argentine Spanish (vos). Dates dd/mm/aaaa, 24 h times, as tools return them.',
|
package/dist/net/browser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Encuentra un navegador Chromium instalado (Chrome, Edge, Brave o Chromium), para el login y
|
|
2
2
|
// para leer Teams. Se puede forzar con UADE_MCP_BROWSER=/ruta/al/navegador.
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
|
+
import { ErrorDeUso } from '../error-de-uso.js';
|
|
4
5
|
const CANDIDATES = {
|
|
5
6
|
darwin: [
|
|
6
7
|
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
@@ -19,7 +20,7 @@ export function findBrowser() {
|
|
|
19
20
|
const override = process.env.UADE_MCP_BROWSER;
|
|
20
21
|
if (override) {
|
|
21
22
|
if (!existsSync(override))
|
|
22
|
-
throw new
|
|
23
|
+
throw new ErrorDeUso(`UADE_MCP_BROWSER apunta a un archivo que no existe: ${override}`);
|
|
23
24
|
return override;
|
|
24
25
|
}
|
|
25
26
|
const found = (CANDIDATES[process.platform] ?? []).find((p) => existsSync(p));
|
package/dist/net/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/net/browser.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4EAA4E;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/net/browser.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4EAA4E;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,GAA6B;IAC3C,MAAM,EAAE;QACN,8DAA8D;QAC9D,gEAAgE;QAChE,8DAA8D;QAC9D,oDAAoD;KACrD;IACD,KAAK,EAAE;QACL,4DAA4D;QAC5D,mEAAmE;QACnE,yEAAyE;KAC1E;IACD,KAAK,EAAE,CAAC,wBAAwB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,2BAA2B,CAAC;CACzI,CAAC;AAEF,MAAM,UAAU,WAAW;IACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,uDAAuD,QAAQ,EAAE,CAAC,CAAC;QACnH,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mHAAmH,CAAC,CAAC;IACvI,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/net/open-browser.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Opens a URL in the student's default browser. Only a short list of sites (Plan UADE and
|
|
2
2
|
// Outlook web), only https, and without a shell (execFile), so a crafted URL cannot run commands.
|
|
3
3
|
import { execFile } from 'node:child_process';
|
|
4
|
-
import { existsSync, realpathSync, statSync } from 'node:fs';
|
|
4
|
+
import { existsSync, mkdirSync, realpathSync, statSync } from 'node:fs';
|
|
5
|
+
import { open } from 'node:fs/promises';
|
|
5
6
|
import { homedir } from 'node:os';
|
|
6
|
-
import { dirname, join, resolve, sep } from 'node:path';
|
|
7
|
+
import { basename, dirname, extname, join, resolve, sep } from 'node:path';
|
|
8
|
+
import { ErrorDeUso } from '../error-de-uso.js';
|
|
7
9
|
export const OPENABLE_ORIGINS = new Set(['https://planuade.ar', 'https://outlook.cloud.microsoft']);
|
|
8
10
|
export function assertOpenableUrl(raw) {
|
|
9
11
|
const u = new URL(raw);
|
|
@@ -34,29 +36,29 @@ export function openInBrowser(raw, exec = execFile) {
|
|
|
34
36
|
// arrastrarlos a un borrador. No sube ni lee el archivo. Solo archivos comunes dentro de tu
|
|
35
37
|
// carpeta personal y fuera de carpetas ocultas (.ssh, .config, …).
|
|
36
38
|
const CARPETAS_DOCUMENTOS = ['Desktop', 'Documents', 'Downloads', ['Library', 'Mobile Documents', 'com~apple~CloudDocs'].join(sep)];
|
|
37
|
-
const EXTENSIONES_DOCUMENTO = /\.(pdf|docx?|xlsx?|pptx?|odt|ods|odp|rtf|txt|csv|md|pages|numbers|key|png|jpe?g|gif|heic|zip)$/i;
|
|
39
|
+
export const EXTENSIONES_DOCUMENTO = /\.(pdf|docx?|xlsx?|pptx?|odt|ods|odp|rtf|txt|csv|md|pages|numbers|key|png|jpe?g|gif|heic|zip)$/i;
|
|
38
40
|
export function assertRevealablePath(raw, home = homedir()) {
|
|
39
41
|
const pedido = resolve(raw.replace(/^~(?=$|\/)/, home));
|
|
40
42
|
if (!existsSync(pedido))
|
|
41
|
-
throw new
|
|
43
|
+
throw new ErrorDeUso(`No encontré el archivo: ${raw}`);
|
|
42
44
|
// Se resuelven los atajos (symlinks): un atajo en Descargas no puede apuntar a ~/.ssh.
|
|
43
45
|
const p = realpathSync(pedido);
|
|
44
46
|
home = realpathSync(home);
|
|
45
47
|
if (!p.startsWith(home + sep))
|
|
46
|
-
throw new
|
|
48
|
+
throw new ErrorDeUso(`Solo se pueden mostrar archivos de tu carpeta personal: ${raw}`);
|
|
47
49
|
// Solo carpetas de documentos y tipos de documento: nunca ~/Library, perfiles de navegador, etc.
|
|
48
50
|
const rel = p.slice(home.length + 1);
|
|
49
51
|
if (!CARPETAS_DOCUMENTOS.some((c) => rel === c || rel.startsWith(c + sep))) {
|
|
50
|
-
throw new
|
|
52
|
+
throw new ErrorDeUso(`Solo muestro archivos de Escritorio, Documentos, Descargas o iCloud Drive: ${raw}`);
|
|
51
53
|
}
|
|
52
54
|
if (!EXTENSIONES_DOCUMENTO.test(p))
|
|
53
|
-
throw new
|
|
55
|
+
throw new ErrorDeUso(`Ese tipo de archivo no se adjunta desde acá: ${raw}`);
|
|
54
56
|
// Carpetas ocultas (.ssh, .config…) y, en Windows, AppData (perfiles de navegador, credenciales).
|
|
55
57
|
if (p.slice(home.length).split(/[\\/]/).some((part) => part.startsWith('.') || /^appdata$/i.test(part))) {
|
|
56
|
-
throw new
|
|
58
|
+
throw new ErrorDeUso(`No muestro archivos en carpetas ocultas o de sistema: ${raw}`);
|
|
57
59
|
}
|
|
58
60
|
if (!existsSync(p) || !statSync(p).isFile())
|
|
59
|
-
throw new
|
|
61
|
+
throw new ErrorDeUso(`No encontré el archivo: ${raw}`);
|
|
60
62
|
return p;
|
|
61
63
|
}
|
|
62
64
|
export function revealInFileManager(raw, exec = execFile) {
|
|
@@ -77,4 +79,40 @@ export function openGeneratedFile(raw, exec = execFile) {
|
|
|
77
79
|
const [cmd, args] = process.platform === 'darwin' ? ['open', [p]] : process.platform === 'win32' ? ['explorer.exe', [p]] : ['xdg-open', [p]];
|
|
78
80
|
return new Promise((ok, fail) => exec(cmd, args, { timeout: 10_000 }, (err) => (err && process.platform !== 'win32' ? fail(new Error('No pude abrir el archivo.')) : ok())));
|
|
79
81
|
}
|
|
82
|
+
// Guarda un archivo que bajó el MCP (un apunte de SharePoint) en su carpeta de salida, nunca en otro
|
|
83
|
+
// lado: nombre saneado (sin rutas, sin caracteres de control, sin empezar con punto), solo tipos de
|
|
84
|
+
// documento, sin pisar nada (si ya existe, agrega " (2)", " (3)"…) y solo legible por la persona.
|
|
85
|
+
export function nombreSeguro(nombre) {
|
|
86
|
+
const plano = basename(nombre.replace(/[\\/]/g, '_')).replace(/[\x00-\x1f\x7f]/g, '').replace(/\s+/g, ' ').trim().replace(/^\.+/, '');
|
|
87
|
+
if (!plano || !EXTENSIONES_DOCUMENTO.test(plano))
|
|
88
|
+
throw new ErrorDeUso(`No guardo archivos de ese tipo (${nombre || 'sin nombre'}): solo documentos, planillas, presentaciones, imágenes o zip.`);
|
|
89
|
+
const ext = extname(plano);
|
|
90
|
+
const base = plano.slice(0, plano.length - ext.length).slice(0, 100);
|
|
91
|
+
return base + ext;
|
|
92
|
+
}
|
|
93
|
+
export async function guardarEnSalida(nombre, bytes, home = homedir()) {
|
|
94
|
+
const dir = carpetaSalida(home);
|
|
95
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
96
|
+
const seguro = nombreSeguro(nombre);
|
|
97
|
+
const ext = extname(seguro);
|
|
98
|
+
const base = seguro.slice(0, seguro.length - ext.length);
|
|
99
|
+
for (let i = 1; i <= 50; i++) {
|
|
100
|
+
const ruta = join(dir, i === 1 ? seguro : `${base} (${i})${ext}`);
|
|
101
|
+
try {
|
|
102
|
+
const fh = await open(ruta, 'wx', 0o600); // wx: falla si existe, nunca pisa
|
|
103
|
+
try {
|
|
104
|
+
await fh.writeFile(bytes);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
await fh.close();
|
|
108
|
+
}
|
|
109
|
+
return ruta;
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (err.code !== 'EEXIST')
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
throw new Error('Ya hay demasiadas copias de ese archivo en Downloads/uade-mcp.');
|
|
117
|
+
}
|
|
80
118
|
//# sourceMappingURL=open-browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/net/open-browser.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,kGAAkG;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/net/open-browser.ts"],"names":[],"mappings":"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"}
|
package/dist/net/policy.js
CHANGED
|
@@ -51,7 +51,15 @@ export function assertAllowed(rawUrl) {
|
|
|
51
51
|
const host = url.hostname.toLowerCase();
|
|
52
52
|
if (!ALLOWED_HOSTS.has(host))
|
|
53
53
|
throw new PolicyError(`host fuera de la allowlist: ${host}`);
|
|
54
|
-
|
|
54
|
+
// Un "%" mal armado (p. ej. en una Location que devuelve el servidor) haría tirar URIError: se
|
|
55
|
+
// trata como URL inválida, no como excepción suelta.
|
|
56
|
+
let target;
|
|
57
|
+
try {
|
|
58
|
+
target = decodeURIComponent(host + url.pathname + url.search).toLowerCase();
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new PolicyError('URL inválida (escape mal formado)');
|
|
62
|
+
}
|
|
55
63
|
for (const rule of DENY_RULES) {
|
|
56
64
|
if (rule.pattern.test(target))
|
|
57
65
|
throw new PolicyError(`bloqueado por política: ${rule.motivo}`);
|
package/dist/net/policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/net/policy.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,qFAAqF;AACrF,oFAAoF;AAEpF,MAAM,CAAC,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC;IACxD,2BAA2B;IAC3B,2BAA2B;IAC3B,8BAA8B;IAC9B,0BAA0B,EAAE,yFAAyF;IACrH,iBAAiB,EAAE,4DAA4D;IAC/E,qBAAqB;IACrB,mGAAmG;IACnG,mFAAmF;IACnF,uBAAuB;IACvB,sGAAsG;IACtG,aAAa;IACb,2BAA2B;IAC3B,qBAAqB;CACtB,CAAC,CAAC;AAOH,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAwB;IAC7C,EAAE,OAAO,EAAE,4BAA4B,EAAE,MAAM,EAAE,qCAAqC,EAAE;IACxF,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,gCAAgC,EAAE;IACzE,EAAE,OAAO,EAAE,2CAA2C,EAAE,MAAM,EAAE,6BAA6B,EAAE;IAC/F,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,0CAA0C,EAAE;IACnF,EAAE,OAAO,EAAE,0CAA0C,EAAE,MAAM,EAAE,wBAAwB,EAAE;IACzF,EAAE,OAAO,EAAE,gCAAgC,EAAE,MAAM,EAAE,eAAe,EAAE;IACtE,EAAE,OAAO,EAAE,2CAA2C,EAAE,MAAM,EAAE,OAAO,EAAE;IACzE,EAAE,OAAO,EAAE,6BAA6B,EAAE,MAAM,EAAE,gCAAgC,EAAE;IACpF,EAAE,OAAO,EAAE,oCAAoC,EAAE,MAAM,EAAE,+DAA+D,EAAE;CAC3H,CAAC;AAEF,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,MAAoB;IAChD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,wBAAwB,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC9F,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,gCAAgC,CAAC,CAAC;IAC1F,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;QAAE,MAAM,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAEjF,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;IAE3F,
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/net/policy.ts"],"names":[],"mappings":"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"}
|
package/dist/report/errores.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Reporte de errores al proyecto, SOLO si la persona prendió el permiso `reportes.errores`.
|
|
2
2
|
// Qué se manda: versión del MCP, nombre de la tool, tipo de error, qué página de UADE cambió (si
|
|
3
|
-
// aplica),
|
|
3
|
+
// aplica), sistema operativo y versión de Node. Solo de los errores técnicos (TypeError, fetch, JSON,
|
|
4
|
+
// librerías) va además un detalle corto con mails, números largos, rutas y textos entre comillas
|
|
5
|
+
// tapados; de un ErrorDeUso (mensajes que nombran materias, archivos, carreras) no va el mensaje.
|
|
4
6
|
// Qué NO se manda nunca: la pregunta, datos de la persona, contenido de páginas, cookies.
|
|
5
7
|
// Se manda a https://planuade.ar/api/mcp-error (único path permitido en ese host), a lo sumo una
|
|
6
8
|
// vez por día por cada error, y si falla no molesta: el reporte es lo menos importante.
|
|
@@ -8,6 +10,7 @@ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
8
10
|
import { join } from 'node:path';
|
|
9
11
|
import { configDir } from '../auth/permissions.js';
|
|
10
12
|
import { ConfirmationError } from '../auth/confirm.js';
|
|
13
|
+
import { ErrorDeUso } from '../error-de-uso.js';
|
|
11
14
|
import { PermissionError } from '../auth/permissions.js';
|
|
12
15
|
import { safeFetch } from '../net/http.js';
|
|
13
16
|
import { PolicyError } from '../net/policy.js';
|
|
@@ -15,17 +18,24 @@ import { SessionExpiredError } from '../net/session.js';
|
|
|
15
18
|
import { PageChangedError } from '../sources/webcampus/parse.js';
|
|
16
19
|
import { toolActual } from './contexto.js';
|
|
17
20
|
export const REPORT_URL = 'https://planuade.ar/api/mcp-error';
|
|
18
|
-
export const VERSION = '0.2.
|
|
21
|
+
export const VERSION = '0.2.2';
|
|
19
22
|
// Errores esperables que no son bugs del MCP ni cambios de UADE: no se reportan.
|
|
20
23
|
const ESPERADOS = [SessionExpiredError, PermissionError, PolicyError, ConfirmationError];
|
|
21
|
-
// Tapa lo que podría identificar a alguien: mails, números largos (legajo, ids), rutas con usuario
|
|
24
|
+
// Tapa lo que podría identificar a alguien: mails, números largos (legajo, ids), rutas con usuario,
|
|
25
|
+
// y lo que va entre comillas (nombres de archivos, materias o carreras citados en un mensaje).
|
|
22
26
|
export function tapar(s) {
|
|
23
27
|
return s
|
|
28
|
+
.replace(/"[^"]*"|“[^”]*”/g, '"…"')
|
|
24
29
|
.replace(/[\w.+-]+@[\w-]+\.[\w.-]+/g, '<mail>')
|
|
25
30
|
.replace(/\d{5,}/g, '<n>')
|
|
26
31
|
.replace(/\/Users\/[^/\s]+|C:\\Users\\[^\\\s]+|\/home\/[^/\s]+/g, '<home>')
|
|
27
32
|
.slice(0, 200);
|
|
28
33
|
}
|
|
34
|
+
// Errores técnicos: de los que vale la pena saber el mensaje (un bug del MCP, una respuesta rara de
|
|
35
|
+
// UADE, una librería). Un ErrorDeUso lleva datos del estudiante en el mensaje; de él va solo el tipo.
|
|
36
|
+
export function esTecnico(err) {
|
|
37
|
+
return !(err instanceof ErrorDeUso) && !(err instanceof PageChangedError);
|
|
38
|
+
}
|
|
29
39
|
export function armarReporte(err, tool) {
|
|
30
40
|
const pagina = err instanceof PageChangedError ? err.pagina : null;
|
|
31
41
|
return {
|
|
@@ -33,13 +43,14 @@ export function armarReporte(err, tool) {
|
|
|
33
43
|
tool,
|
|
34
44
|
tipo: err.name || 'Error',
|
|
35
45
|
pagina,
|
|
36
|
-
// De un cambio de página alcanza con saber cuál; de
|
|
37
|
-
detalle:
|
|
46
|
+
// De un cambio de página alcanza con saber cuál; de un error de uso, el tipo; del resto, el mensaje tapado.
|
|
47
|
+
detalle: esTecnico(err) ? tapar(err.message) : '',
|
|
38
48
|
os: process.platform,
|
|
39
49
|
node: process.version,
|
|
40
50
|
};
|
|
41
51
|
}
|
|
42
|
-
|
|
52
|
+
// La clave de "ya se mandó hoy" no lleva el detalle: en disco tampoco quedan mensajes.
|
|
53
|
+
const clave = (r) => `${r.tool}|${r.tipo}|${r.pagina ?? ''}`;
|
|
43
54
|
function yaReportadoHoy(r, dir) {
|
|
44
55
|
const archivo = join(dir, 'reportes.json');
|
|
45
56
|
let d = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errores.js","sourceRoot":"","sources":["../../src/report/errores.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,iGAAiG;AACjG,
|
|
1
|
+
{"version":3,"file":"errores.js","sourceRoot":"","sources":["../../src/report/errores.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,iGAAiG;AACjG,sGAAsG;AACtG,iGAAiG;AACjG,kGAAkG;AAClG,0FAA0F;AAC1F,iGAAiG;AACjG,wFAAwF;AACxF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,mCAAmC,CAAC;AAC9D,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAY/B,iFAAiF;AACjF,MAAM,SAAS,GAAG,CAAC,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;AAEzF,oGAAoG;AACpG,+FAA+F;AAC/F,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC;SACL,OAAO,CAAC,kBAAkB,EAAE,KAAK,CAAC;SAClC,OAAO,CAAC,2BAA2B,EAAE,QAAQ,CAAC;SAC9C,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC;SACzB,OAAO,CAAC,uDAAuD,EAAE,QAAQ,CAAC;SAC1E,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,oGAAoG;AACpG,sGAAsG;AACtG,MAAM,UAAU,SAAS,CAAC,GAAU;IAClC,OAAO,CAAC,CAAC,GAAG,YAAY,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,gBAAgB,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAU,EAAE,IAAY;IACnD,MAAM,MAAM,GAAG,GAAG,YAAY,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI;QACJ,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,OAAO;QACzB,MAAM;QACN,4GAA4G;QAC5G,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QACjD,EAAE,EAAE,OAAO,CAAC,QAAQ;QACpB,IAAI,EAAE,OAAO,CAAC,OAAO;KACtB,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;AAEtE,SAAS,cAAc,CAAC,CAAU,EAAE,GAAW;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC3C,IAAI,CAAC,GAA2B,EAAE,CAAC;IACnC,IAAI,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC;QAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iCAAiC,CAAC,CAAC;IACjK,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,OAAgC,EAChC,IAAI,GAA+E,EAAE;IAErF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,EAAE,IAAI,aAAa,CAAC,CAAC;IACjF,IAAI,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxK,IAAI,CAAC;QAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,0CAA0C,CAAC,CAAC;IAC7E,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -6,13 +6,17 @@ import { readSheet } from 'read-excel-file/node';
|
|
|
6
6
|
import WordExtractor from 'word-extractor';
|
|
7
7
|
import { read as leerXls, utils as xlsUtils } from 'xlsx';
|
|
8
8
|
import { leerPdf } from '../calendario/index.js';
|
|
9
|
+
import { assertXlsxRazonable, MAX_DESCOMPRIMIDO } from '../webcampus/previos.js';
|
|
9
10
|
const MAX_TEXTO = 12000;
|
|
10
11
|
export function tipoLegible(nombre) {
|
|
11
12
|
return /\.(pdf|xlsx|xls|docx|doc|pptx|txt|csv|md)$/i.test(nombre);
|
|
12
13
|
}
|
|
13
|
-
// Lee archivos de un zip (docx/pptx
|
|
14
|
+
// Lee archivos de un zip (docx/pptx) cuyo nombre matchea `filtro`, concatenando su contenido.
|
|
15
|
+
// Cuenta los bytes REALES que salen (los tamaños que declara el zip se pueden falsear) y corta al
|
|
16
|
+
// pasar el tope: un "zip bomb" disfrazado de apunte no agota la memoria.
|
|
14
17
|
function partesDeZip(bytes, filtro) {
|
|
15
18
|
const partes = [];
|
|
19
|
+
let total = 0;
|
|
16
20
|
const unzip = new Unzip((file) => {
|
|
17
21
|
if (!filtro.test(file.name))
|
|
18
22
|
return; // no se arranca: fflate lo saltea
|
|
@@ -20,6 +24,9 @@ function partesDeZip(bytes, filtro) {
|
|
|
20
24
|
file.ondata = (err, chunk, final) => {
|
|
21
25
|
if (err)
|
|
22
26
|
throw err;
|
|
27
|
+
total += chunk.length;
|
|
28
|
+
if (total > MAX_DESCOMPRIMIDO)
|
|
29
|
+
throw new Error('El documento es sospechosamente grande al descomprimirlo; no se abrió.');
|
|
23
30
|
trozos.push(chunk);
|
|
24
31
|
if (final) {
|
|
25
32
|
const total = trozos.reduce((n, c) => n + c.length, 0);
|
|
@@ -62,6 +69,7 @@ export async function leerDocumento(nombre, bytes) {
|
|
|
62
69
|
texto = slides.map((x, i) => `[Diapositiva ${i + 1}] ${textoDeXml(x, 'a:t')}`).join('\n');
|
|
63
70
|
}
|
|
64
71
|
else if (ext === 'xlsx') {
|
|
72
|
+
assertXlsxRazonable(bytes, 'El Excel');
|
|
65
73
|
const rows = await readSheet(Buffer.from(bytes));
|
|
66
74
|
texto = rows.map((r) => r.map((c) => (c == null ? '' : String(c))).join('\t')).join('\n');
|
|
67
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leer.js","sourceRoot":"","sources":["../../../src/sources/docs/leer.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,8FAA8F;AAC9F,4FAA4F;AAC5F,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"leer.js","sourceRoot":"","sources":["../../../src/sources/docs/leer.ts"],"names":[],"mappings":"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"}
|