@albertomarturelo/sii-core 0.9.0 → 0.11.0
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/CHANGELOG.md +101 -0
- package/dist/adapters/fake/index.d.ts +20 -4
- package/dist/adapters/fake/index.d.ts.map +1 -1
- package/dist/adapters/fake/index.js +38 -4
- package/dist/adapters/fake/index.js.map +1 -1
- package/dist/adapters/node/cookie-jar.d.ts +35 -0
- package/dist/adapters/node/cookie-jar.d.ts.map +1 -0
- package/dist/adapters/node/cookie-jar.js +211 -0
- package/dist/adapters/node/cookie-jar.js.map +1 -0
- package/dist/adapters/node/http.d.ts +12 -0
- package/dist/adapters/node/http.d.ts.map +1 -0
- package/dist/adapters/node/http.js +262 -0
- package/dist/adapters/node/http.js.map +1 -0
- package/dist/adapters/node/portal.d.ts.map +1 -1
- package/dist/adapters/node/portal.js +18 -8
- package/dist/adapters/node/portal.js.map +1 -1
- package/dist/adapters/node/response.d.ts +12 -4
- package/dist/adapters/node/response.d.ts.map +1 -1
- package/dist/adapters/node/response.js +36 -8
- package/dist/adapters/node/response.js.map +1 -1
- package/dist/auth/auth.d.ts +55 -6
- package/dist/auth/auth.d.ts.map +1 -1
- package/dist/auth/auth.js +238 -56
- package/dist/auth/auth.js.map +1 -1
- package/dist/auth/datos-cntr.d.ts +23 -0
- package/dist/auth/datos-cntr.d.ts.map +1 -0
- package/dist/auth/datos-cntr.js +81 -0
- package/dist/auth/datos-cntr.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/login-block.d.ts +23 -0
- package/dist/auth/login-block.d.ts.map +1 -0
- package/dist/auth/login-block.js +53 -0
- package/dist/auth/login-block.js.map +1 -0
- package/dist/auth/login-error.d.ts +20 -3
- package/dist/auth/login-error.d.ts.map +1 -1
- package/dist/auth/login-error.js +20 -5
- package/dist/auth/login-error.js.map +1 -1
- package/dist/auth/session.d.ts +29 -2
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +35 -2
- package/dist/auth/session.js.map +1 -1
- package/dist/auth/www2-login.d.ts +28 -0
- package/dist/auth/www2-login.d.ts.map +1 -0
- package/dist/auth/www2-login.js +101 -0
- package/dist/auth/www2-login.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/config.d.ts +21 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +21 -0
- package/dist/config/config.js.map +1 -1
- package/dist/errors/errors.d.ts +59 -2
- package/dist/errors/errors.d.ts.map +1 -1
- package/dist/errors/errors.js +55 -2
- package/dist/errors/errors.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +7 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +10 -4
- package/dist/node.js.map +1 -1
- package/dist/portal/carpeta-tributaria-regular.d.ts +30 -0
- package/dist/portal/carpeta-tributaria-regular.d.ts.map +1 -0
- package/dist/portal/carpeta-tributaria-regular.js +142 -0
- package/dist/portal/carpeta-tributaria-regular.js.map +1 -0
- package/dist/portal/www2-session.d.ts +13 -0
- package/dist/portal/www2-session.d.ts.map +1 -0
- package/dist/portal/www2-session.js +61 -0
- package/dist/portal/www2-session.js.map +1 -0
- package/dist/seams/index.d.ts +7 -0
- package/dist/seams/index.d.ts.map +1 -1
- package/dist/tasks/auth.d.ts +23 -6
- package/dist/tasks/auth.d.ts.map +1 -1
- package/dist/tasks/auth.js +20 -5
- package/dist/tasks/auth.js.map +1 -1
- package/dist/tasks/bte.d.ts.map +1 -1
- package/dist/tasks/bte.js +4 -2
- package/dist/tasks/bte.js.map +1 -1
- package/dist/tasks/carpeta.d.ts +9 -0
- package/dist/tasks/carpeta.d.ts.map +1 -0
- package/dist/tasks/carpeta.js +49 -0
- package/dist/tasks/carpeta.js.map +1 -0
- package/dist/tasks/dte.js +8 -8
- package/dist/tasks/dte.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// The DEFAULT PortalDriver since ADR-027: a browser-free adapter over Node `fetch` plus
|
|
2
|
+
// the in-house CookieJar. A live spike (2026-10-17, one attempt, no browser) confirmed the
|
|
3
|
+
// classic SII login works as a plain POST and the resulting jar reaches Mi SII and the www4
|
|
4
|
+
// SDI facades — so every surface that does NOT run SII's own page JS needs no Chromium.
|
|
5
|
+
//
|
|
6
|
+
// What it CANNOT do: `evaluate` (run page JS) and `interactiveLogin` (a human at SII's page).
|
|
7
|
+
// Both throw BrowserRequiredError; a surface that needs them asks withSession for the
|
|
8
|
+
// `browser` engine (the lazy Playwright driver), which is the only thing that still needs
|
|
9
|
+
// Chromium (BTE inline maps, MIPYME `validaFacEx`). ADR-027.
|
|
10
|
+
//
|
|
11
|
+
// Auth detection stays URL-based (sii-py ADR-009) with ONE documented exception: the login
|
|
12
|
+
// POST itself answers 200 on `zeusr` for BOTH success and failure (observed 2026-10-17), so
|
|
13
|
+
// credentialLogin decides from the body (SII's error código) + the session cookie, not the host.
|
|
14
|
+
import { LOGIN_HOST, LOGIN_POST_URL, QUEUE_IT_HOST, loginUrl } from '../../config/index.js';
|
|
15
|
+
import { LoginFailedError, LoginQueuedError, BrowserRequiredError } from '../../errors/index.js';
|
|
16
|
+
import { parseSiiLoginErrorDetail } from '../../auth/login-error.js';
|
|
17
|
+
import { Rut } from '../../rut/index.js';
|
|
18
|
+
import { charsetOf, formLoginWallError, nonJsonResponseError } from './response.js';
|
|
19
|
+
import { CookieJar } from './cookie-jar.js';
|
|
20
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
21
|
+
const MAX_REDIRECTS = 10;
|
|
22
|
+
// A browser-like User-Agent is REQUIRED on the authenticated requests: Playwright's
|
|
23
|
+
// APIRequestContext sent the Chromium UA automatically, and SII's www4 WAF bounces a UA-less
|
|
24
|
+
// client to the login wall even with a valid session cookie — misiir is laxer, which masked it
|
|
25
|
+
// (observed 2026-10-18, GH live validation of ADR-027; the 2026-10-17 spike worked only because
|
|
26
|
+
// it set a Chrome UA). A caller's explicit `User-Agent` still wins.
|
|
27
|
+
const BROWSER_HEADERS = {
|
|
28
|
+
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ' +
|
|
29
|
+
'(KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
|
|
30
|
+
'accept-language': 'es-CL,es;q=0.9',
|
|
31
|
+
};
|
|
32
|
+
const BROWSER_ONLY = 'Esta operación necesita el motor de navegador (JS de la página de SII). El PortalDriver ' +
|
|
33
|
+
'HTTP no puede ejecutarlo (ADR-027). Instala y usa el motor Playwright: `npm i playwright` + ' +
|
|
34
|
+
'`npx playwright install chromium`.';
|
|
35
|
+
/** A fetch that carries a CookieJar across MANUAL redirects: Node `fetch` would neither apply
|
|
36
|
+
* `Set-Cookie` per hop nor re-attach our jar, and SII sets the session cookies mid-redirect
|
|
37
|
+
* (login) and detects a dead jar by bouncing to `LOGIN_HOST`. Each hop applies Set-Cookie into
|
|
38
|
+
* the jar and re-sends the jar's Cookie header; the landed URL is what the caller checks. */
|
|
39
|
+
async function fetchWithJar(fetchImpl, jar, startUrl, init) {
|
|
40
|
+
let url = startUrl;
|
|
41
|
+
let method = init.method;
|
|
42
|
+
let body = init.body;
|
|
43
|
+
let headers = { ...init.headers };
|
|
44
|
+
for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {
|
|
45
|
+
const cookie = jar.header(url);
|
|
46
|
+
// Build the headers CASE-INSENSITIVELY via Headers.set: a facade passes `Content-Type`
|
|
47
|
+
// while BROWSER_HEADERS/`jsonHeaders` use `content-type`, and a plain object would keep
|
|
48
|
+
// BOTH keys — undici then appends them into `application/json, application/json`, which
|
|
49
|
+
// www4 answers with HTTP 500. `set` lowercases and overwrites, so each header is sent once.
|
|
50
|
+
// Browser headers first so a caller's explicit value wins. (ADR-027, GH live validation.)
|
|
51
|
+
const sent = new Headers();
|
|
52
|
+
for (const [k, v] of Object.entries({ ...BROWSER_HEADERS, ...headers }))
|
|
53
|
+
sent.set(k, v);
|
|
54
|
+
if (cookie)
|
|
55
|
+
sent.set('cookie', cookie);
|
|
56
|
+
const res = await fetchImpl(url, {
|
|
57
|
+
method,
|
|
58
|
+
redirect: 'manual',
|
|
59
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
60
|
+
...(body !== undefined ? { body } : {}),
|
|
61
|
+
headers: sent,
|
|
62
|
+
});
|
|
63
|
+
jar.applySetCookies(url, res.headers.getSetCookie?.() ?? []);
|
|
64
|
+
const location = res.headers.get('location');
|
|
65
|
+
if (res.status >= 300 && res.status < 400 && location) {
|
|
66
|
+
url = new URL(location, url).href;
|
|
67
|
+
// A 303, or a 301/302 after a POST, continues as GET without the body (fetch semantics).
|
|
68
|
+
if (res.status !== 307 && res.status !== 308) {
|
|
69
|
+
method = 'GET';
|
|
70
|
+
body = undefined;
|
|
71
|
+
headers = stripBodyHeaders(headers);
|
|
72
|
+
}
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const buffer = await res.arrayBuffer();
|
|
76
|
+
return {
|
|
77
|
+
finalUrl: res.url || url,
|
|
78
|
+
status: res.status,
|
|
79
|
+
contentType: res.headers.get('content-type'),
|
|
80
|
+
bytes: new Uint8Array(buffer),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`Demasiadas redirecciones (> ${MAX_REDIRECTS}) desde ${startUrl}`);
|
|
84
|
+
}
|
|
85
|
+
function stripBodyHeaders(headers) {
|
|
86
|
+
const out = {};
|
|
87
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
88
|
+
if (k.toLowerCase() === 'content-type')
|
|
89
|
+
continue;
|
|
90
|
+
out[k] = v;
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
const decode = (r) => new TextDecoder(charsetOf(r.contentType)).decode(r.bytes);
|
|
95
|
+
const landedOn = (url, host) => new URL(url).hostname === host;
|
|
96
|
+
class HttpPortalSession {
|
|
97
|
+
fetchImpl;
|
|
98
|
+
jar;
|
|
99
|
+
constructor(fetchImpl, jar) {
|
|
100
|
+
this.fetchImpl = fetchImpl;
|
|
101
|
+
this.jar = jar;
|
|
102
|
+
}
|
|
103
|
+
async goto(url) {
|
|
104
|
+
const r = await fetchWithJar(this.fetchImpl, this.jar, url, { method: 'GET' });
|
|
105
|
+
return r.finalUrl;
|
|
106
|
+
}
|
|
107
|
+
evaluate(_expression) {
|
|
108
|
+
// The HTTP driver cannot run page JS (ADR-027). A surface that needs it (BTE inline maps,
|
|
109
|
+
// MIPYME validaFacEx) must acquire the browser engine via withSession.
|
|
110
|
+
return Promise.reject(new BrowserRequiredError(BROWSER_ONLY));
|
|
111
|
+
}
|
|
112
|
+
async requestJson(url, options = {}) {
|
|
113
|
+
const headers = options.body !== undefined ? jsonHeaders(options.headers) : options.headers;
|
|
114
|
+
const r = await fetchWithJar(this.fetchImpl, this.jar, url, {
|
|
115
|
+
method: options.method ?? 'POST',
|
|
116
|
+
...(headers ? { headers } : {}),
|
|
117
|
+
...(options.body !== undefined ? { body: JSON.stringify(options.body) } : {}),
|
|
118
|
+
});
|
|
119
|
+
const text = decode(r);
|
|
120
|
+
try {
|
|
121
|
+
return JSON.parse(text);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Same classification as the Playwright adapter: a login-wall bounce / HTML body ⇒
|
|
125
|
+
// SessionExpiredError; anything else ⇒ UnexpectedResponseError naming endpoint + body.
|
|
126
|
+
throw nonJsonResponseError(r.finalUrl, r.contentType ?? '', r.status, text);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async requestForm(url, options = {}) {
|
|
130
|
+
const headers = { ...options.headers };
|
|
131
|
+
let body;
|
|
132
|
+
if (options.form) {
|
|
133
|
+
body = new URLSearchParams(options.form).toString();
|
|
134
|
+
headers['content-type'] ??= 'application/x-www-form-urlencoded';
|
|
135
|
+
}
|
|
136
|
+
const r = await fetchWithJar(this.fetchImpl, this.jar, url, {
|
|
137
|
+
method: options.method ?? 'POST',
|
|
138
|
+
headers,
|
|
139
|
+
...(body !== undefined ? { body } : {}),
|
|
140
|
+
});
|
|
141
|
+
const wall = formLoginWallError(r.finalUrl);
|
|
142
|
+
if (wall)
|
|
143
|
+
throw wall;
|
|
144
|
+
return { status: r.status, body: decode(r) };
|
|
145
|
+
}
|
|
146
|
+
async requestText(url, options = {}) {
|
|
147
|
+
const r = await fetchWithJar(this.fetchImpl, this.jar, url, {
|
|
148
|
+
method: options.method ?? 'POST',
|
|
149
|
+
...(options.headers ? { headers: options.headers } : {}),
|
|
150
|
+
...(options.body !== undefined ? { body: options.body } : {}),
|
|
151
|
+
});
|
|
152
|
+
const wall = formLoginWallError(r.finalUrl);
|
|
153
|
+
if (wall)
|
|
154
|
+
throw wall;
|
|
155
|
+
return { status: r.status, body: decode(r) };
|
|
156
|
+
}
|
|
157
|
+
async requestBinary(url, options = {}) {
|
|
158
|
+
const r = await fetchWithJar(this.fetchImpl, this.jar, url, {
|
|
159
|
+
method: options.method ?? 'GET',
|
|
160
|
+
...(options.headers ? { headers: options.headers } : {}),
|
|
161
|
+
...(options.body !== undefined ? { body: options.body } : {}),
|
|
162
|
+
});
|
|
163
|
+
const wall = formLoginWallError(r.finalUrl);
|
|
164
|
+
if (wall)
|
|
165
|
+
throw wall;
|
|
166
|
+
return { status: r.status, contentType: r.contentType, bytes: r.bytes };
|
|
167
|
+
}
|
|
168
|
+
cookie(url, name) {
|
|
169
|
+
return Promise.resolve(this.jar.value(url, name));
|
|
170
|
+
}
|
|
171
|
+
storageState() {
|
|
172
|
+
return Promise.resolve(this.jar.toStorageState());
|
|
173
|
+
}
|
|
174
|
+
close() {
|
|
175
|
+
return Promise.resolve(); // no browser to tear down
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function jsonHeaders(headers) {
|
|
179
|
+
const h = { ...headers };
|
|
180
|
+
h['content-type'] ??= 'application/json';
|
|
181
|
+
return h;
|
|
182
|
+
}
|
|
183
|
+
export class HttpPortalDriver {
|
|
184
|
+
fetchImpl;
|
|
185
|
+
constructor(fetchImpl = globalThis.fetch) {
|
|
186
|
+
this.fetchImpl = fetchImpl;
|
|
187
|
+
}
|
|
188
|
+
interactiveLogin(_options) {
|
|
189
|
+
// A headed browser login is the MCP's job (ADR-027); the HTTP CLI uses credentialLogin.
|
|
190
|
+
return Promise.reject(new BrowserRequiredError(BROWSER_ONLY));
|
|
191
|
+
}
|
|
192
|
+
async credentialLogin(options) {
|
|
193
|
+
const jar = new CookieJar();
|
|
194
|
+
// 1. Warm-up GET of the login page — collects the F5 WAF's `TS*` cookies BEFORE the POST
|
|
195
|
+
// (observed 2026-10-17: the GET sets them and the POST is accepted with them present).
|
|
196
|
+
await fetchWithJar(this.fetchImpl, jar, loginUrl(options.destination), { method: 'GET' });
|
|
197
|
+
// 2. The exact five form fields the page JS computes (auth-login.md, re-confirmed
|
|
198
|
+
// 2026-10-17): the RUT split into body (leading zeros dropped) + DV, the dotted RUT in
|
|
199
|
+
// `rutcntr`, the destination in `referencia`, `411` empty, and the Clave.
|
|
200
|
+
const rut = Rut.parse(options.rut);
|
|
201
|
+
const form = new URLSearchParams({
|
|
202
|
+
rut: String(rut.body),
|
|
203
|
+
dv: rut.dv,
|
|
204
|
+
referencia: options.destination,
|
|
205
|
+
'411': '',
|
|
206
|
+
rutcntr: rut.formatted,
|
|
207
|
+
clave: options.clave,
|
|
208
|
+
});
|
|
209
|
+
const r = await fetchWithJar(this.fetchImpl, jar, LOGIN_POST_URL, {
|
|
210
|
+
method: 'POST',
|
|
211
|
+
headers: {
|
|
212
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
213
|
+
origin: `https://${LOGIN_HOST}`,
|
|
214
|
+
referer: loginUrl(options.destination),
|
|
215
|
+
},
|
|
216
|
+
body: form.toString(),
|
|
217
|
+
});
|
|
218
|
+
// 3. Queue-it waiting room ⇒ stop (an HTTP client cannot pass it).
|
|
219
|
+
if (landedOn(r.finalUrl, QUEUE_IT_HOST)) {
|
|
220
|
+
throw new LoginQueuedError('El SII está derivando el ingreso a su sala de espera (salaespera.sii.cl). ' +
|
|
221
|
+
'Intenta más tarde; no se reintenta automáticamente.');
|
|
222
|
+
}
|
|
223
|
+
// 4. Success vs rejection. SII answers 200 on `zeusr` either way (observed 2026-10-17), so
|
|
224
|
+
// the body is the signal: a rejected Clave renders the error código page. Parse it and
|
|
225
|
+
// surface SII's verbatim message + the typed reason/código (#124). ONE attempt, never
|
|
226
|
+
// retried (ADR-004). A changed shape with no session cookie falls through to the generic
|
|
227
|
+
// "not completed" below — the caller's Mi SII identity read is the final proof.
|
|
228
|
+
const detail = parseSiiLoginErrorDetail(decode(r));
|
|
229
|
+
if (detail.message !== null) {
|
|
230
|
+
throw new LoginFailedError(detail.message, { reason: detail.reason, codigo: detail.codigo });
|
|
231
|
+
}
|
|
232
|
+
return new HttpPortalSession(this.fetchImpl, jar);
|
|
233
|
+
}
|
|
234
|
+
restore(storageState) {
|
|
235
|
+
return Promise.resolve(new HttpPortalSession(this.fetchImpl, CookieJar.fromStorageState(storageState)));
|
|
236
|
+
}
|
|
237
|
+
async requestPublic(url, options = {}) {
|
|
238
|
+
// UNAUTHENTICATED public consulta (ADR-014): a cold request, no jar, no session. Headers are
|
|
239
|
+
// built through `Headers` (case-insensitive) so a caller-supplied `content-type` can't collide
|
|
240
|
+
// with the default and get appended into a duplicate — the class of bug that 500'd www4 on the
|
|
241
|
+
// authenticated path (GH live validation 2026-10-18); `Headers.has` is case-insensitive.
|
|
242
|
+
const headers = new Headers();
|
|
243
|
+
for (const [k, v] of Object.entries(options.headers ?? {}))
|
|
244
|
+
headers.set(k, v);
|
|
245
|
+
let body;
|
|
246
|
+
if (options.form) {
|
|
247
|
+
body = new URLSearchParams(options.form).toString();
|
|
248
|
+
if (!headers.has('content-type'))
|
|
249
|
+
headers.set('content-type', 'application/x-www-form-urlencoded');
|
|
250
|
+
}
|
|
251
|
+
const response = await this.fetchImpl(url, {
|
|
252
|
+
method: options.method ?? 'POST',
|
|
253
|
+
headers,
|
|
254
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
255
|
+
...(body !== undefined ? { body } : {}),
|
|
256
|
+
});
|
|
257
|
+
const buffer = await response.arrayBuffer();
|
|
258
|
+
const text = new TextDecoder(charsetOf(response.headers.get('content-type'))).decode(buffer);
|
|
259
|
+
return { status: response.status, body: text };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/adapters/node/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/portal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/portal.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAGV,sBAAsB,EAEtB,uBAAuB,EAEvB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAqL9B,qBAAa,sBAAuB,YAAW,YAAY;IACnD,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;IAuB1E,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC;IAwCxE,OAAO,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBtD,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;CA0BvF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LOGIN_HOST, loginUrl } from '../../config/index.js';
|
|
2
2
|
import { LoginFailedError } from '../../errors/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { parseSiiLoginErrorDetail } from '../../auth/login-error.js';
|
|
4
4
|
import { charsetOf, formLoginWallError, nonJsonResponseError } from './response.js';
|
|
5
5
|
/** Lazy-load playwright — an OPTIONAL peer since ADR-016. Only the launch paths of
|
|
6
6
|
* this default driver need it, so a consumer that injects its own PortalDriver (or
|
|
@@ -36,10 +36,12 @@ async function readLoginError(page) {
|
|
|
36
36
|
// Pull the rendered body text and parse in Node (testable; keeps the DOM out
|
|
37
37
|
// of core). The string expr returns a string, so the boundary cast is safe.
|
|
38
38
|
const body = (await page.evaluate('(document.body && document.body.innerText) || ""'));
|
|
39
|
-
|
|
39
|
+
const d = parseSiiLoginErrorDetail(body);
|
|
40
|
+
// A changed shape (message null) ⇒ fallback text, reason 'unknown', no código.
|
|
41
|
+
return { message: d.message ?? fallback, reason: d.reason, codigo: d.codigo };
|
|
40
42
|
}
|
|
41
43
|
catch {
|
|
42
|
-
return fallback;
|
|
44
|
+
return { message: fallback, reason: 'unknown', codigo: null };
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
/** A session owns its browser; close() tears the whole instance down. */
|
|
@@ -70,15 +72,22 @@ class PlaywrightPortalSession {
|
|
|
70
72
|
...(options.headers ? { headers: options.headers } : {}),
|
|
71
73
|
...(options.body !== undefined ? { data: JSON.stringify(options.body) } : {}),
|
|
72
74
|
});
|
|
75
|
+
// Read the body as text ONCE (Playwright's response.json() is JSON.parse over the
|
|
76
|
+
// same text) so a parse failure can carry a verbatim snippet into the error.
|
|
77
|
+
const text = await response.text();
|
|
73
78
|
try {
|
|
74
|
-
return
|
|
79
|
+
return JSON.parse(text);
|
|
75
80
|
}
|
|
76
81
|
catch {
|
|
77
|
-
// A non-JSON body from an authenticated SDI POST means the dead session was
|
|
82
|
+
// A non-JSON body from an authenticated SDI POST usually means the dead session was
|
|
78
83
|
// bounced to SII's login wall — surface an actionable SessionExpiredError, not a
|
|
79
|
-
// parse error. No extra round-trip: this first SDI POST IS the liveness test.
|
|
84
|
+
// parse error. No extra round-trip: this first SDI POST IS the liveness test. But
|
|
85
|
+
// NOT every non-JSON body is a wall: a live session on the wrong endpoint gets a
|
|
86
|
+
// 200 `text/plain` bare URL (cte-api obtenerValorParametro, observed 2026-09-11) —
|
|
87
|
+
// that is an UnexpectedResponseError naming the endpoint + body, never a raw-string
|
|
88
|
+
// result (the seam resolves parsed JSON only).
|
|
80
89
|
// Classification is a pure helper so it is unit-tested (nonJsonResponseError).
|
|
81
|
-
throw nonJsonResponseError(response.url(), response.headers()['content-type'] ?? '', response.status());
|
|
90
|
+
throw nonJsonResponseError(response.url(), response.headers()['content-type'] ?? '', response.status(), text);
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
async requestForm(url, options = {}) {
|
|
@@ -205,7 +214,8 @@ export class PlaywrightPortalDriver {
|
|
|
205
214
|
]);
|
|
206
215
|
if (new URL(page.url()).hostname === LOGIN_HOST) {
|
|
207
216
|
// Rejected — surface SII's verbatim message (CONVENTIONS); do NOT retry.
|
|
208
|
-
|
|
217
|
+
const e = await readLoginError(page);
|
|
218
|
+
throw new LoginFailedError(e.message, { reason: e.reason, codigo: e.codigo });
|
|
209
219
|
}
|
|
210
220
|
return new PlaywrightPortalSession(browser, context, page);
|
|
211
221
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../src/adapters/node/portal.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../src/adapters/node/portal.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAepF;;;;;+DAK+D;AAC/D,KAAK,UAAU,YAAY;IACzB,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,kBAAkB,CAAC;QAChF,IAAI,QAAQ,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CACb,8EAA8E;gBAC5E,kEAAkE;gBAClE,oCAAoC,CACvC,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;kDAKkD;AAClD,KAAK,UAAU,cAAc,CAC3B,IAAU;IAEV,MAAM,QAAQ,GACZ,yFAAyF;QACzF,wFAAwF,CAAC;IAC3F,IAAI,CAAC;QACH,6EAA6E;QAC7E,4EAA4E;QAC5E,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAC/B,kDAAkD,CACnD,CAAW,CAAC;QACb,MAAM,CAAC,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACzC,+EAA+E;QAC/E,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAChE,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,uBAAuB;IAER;IACA;IACA;IAHnB,YACmB,OAAgB,EAChB,OAAuB,EACvB,IAAU;QAFV,YAAO,GAAP,OAAO,CAAS;QAChB,YAAO,GAAP,OAAO,CAAgB;QACvB,SAAI,GAAJ,IAAI,CAAM;IAC1B,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,qEAAqE;QACrE,0DAA0D;QAC1D,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAI,UAAkB;QAClC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAM,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,UAAuB,EAAE;QACtD,+EAA+E;QAC/E,kFAAkF;QAClF,uEAAuE;QACvE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QACH,kFAAkF;QAClF,6EAA6E;QAC7E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,oFAAoF;YACpF,iFAAiF;YACjF,kFAAkF;YAClF,iFAAiF;YACjF,mFAAmF;YACnF,oFAAoF;YACpF,+CAA+C;YAC/C,+EAA+E;YAC/E,MAAM,oBAAoB,CACxB,QAAQ,CAAC,GAAG,EAAE,EACd,QAAQ,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,EACxC,QAAQ,CAAC,MAAM,EAAE,EACjB,IAAI,CACL,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,UAAuB,EAAE;QACtD,iFAAiF;QACjF,iFAAiF;QACjF,4EAA4E;QAC5E,gFAAgF;QAChF,iFAAiF;QACjF,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI;YAAE,MAAM,IAAI,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3F,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,UAAuB,EAAE;QACtD,mFAAmF;QACnF,yFAAyF;QACzF,oFAAoF;QACpF,yFAAyF;QACzF,gFAAgF;QAChF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI;YAAE,MAAM,IAAI,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3F,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,UAAyB,EAAE;QAC1D,mFAAmF;QACnF,uFAAuF;QACvF,yEAAyE;QACzE,EAAE;QACF,iFAAiF;QACjF,uFAAuF;QACvF,uFAAuF;QACvF,qFAAqF;QACrF,eAAe;QACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YAC/B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI;YAAE,MAAM,IAAI,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE;YACzB,WAAW,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,IAAI,IAAI;YACvD,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,IAAY;QACpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,4EAA4E;QAC5E,uCAAuC;QACvC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAChD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,sBAAsB;IACjC,KAAK,CAAC,gBAAgB,CAAC,OAAgC;QACrD,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAClF,wEAAwE;YACxE,iEAAiE;YACjE,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE;gBAC1D,OAAO,EAAE,OAAO,CAAC,SAAS;aAC3B,CAAC,CAAC;YACH,OAAO,IAAI,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,6EAA6E;YAC7E,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,gBAAgB,CACxB,qFAAqF,CACtF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAA+B;QACnD,gFAAgF;QAChF,+EAA+E;QAC/E,iFAAiF;QACjF,gFAAgF;QAChF,6EAA6E;QAC7E,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAClF,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,8EAA8E;YAC9E,gFAAgF;YAChF,wEAAwE;YACxE,+EAA+E;YAC/E,gFAAgF;YAChF,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,IAAI,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;gBACrF,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;aAC3B,CAAC,CAAC;YACH,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;gBAChD,yEAAyE;gBACzE,MAAM,CAAC,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,IAAI,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,IAAI,GAAG,YAAY,gBAAgB;gBAAE,MAAM,GAAG,CAAC,CAAC,gCAAgC;YAChF,MAAM,IAAI,gBAAgB,CACxB,gFAAgF;gBAC9E,6DAA6D,CAChE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,YAAqB;QACjC,sEAAsE;QACtE,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;gBACvC,YAAY,EAAE,YAAkE;aACjF,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,OAAO,IAAI,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,4EAA4E;YAC5E,oEAAoE;YACpE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,UAAyB,EAAE;QAC1D,kFAAkF;QAClF,oFAAoF;QACpF,oFAAoF;QACpF,qFAAqF;QACrF,kFAAkF;QAClF,yEAAyE;QACzE,MAAM,OAAO,GAA2B,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/D,IAAI,IAAwB,CAAC;QAC7B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,IAAI,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpD,OAAO,CAAC,cAAc,CAAC,KAAK,mCAAmC,CAAC;QAClE,CAAC;QACD,6EAA6E;QAC7E,iFAAiF;QACjF,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,OAAO;YACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;YACnC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7F,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC;CACF"}
|
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
* SDI POST get bounced to SII's login wall (HTML) instead of JSON; detect it the same
|
|
3
3
|
* URL-based way the rest of the auth flow does — landing on `LOGIN_HOST`, with an
|
|
4
4
|
* HTML content-type fallback for a same-host wall (ADR-009) — and return an ACTIONABLE
|
|
5
|
-
* `SessionExpiredError`. Anything else is a genuinely unexpected response →
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
5
|
+
* `SessionExpiredError`. Anything else is a genuinely unexpected response →
|
|
6
|
+
* `UnexpectedResponseError` naming the endpoint, status, content-type and the first
|
|
7
|
+
* chars of the body verbatim. Observed at
|
|
8
|
+
* https://www2.sii.cl/app/cte-api-carpetatributaria/{rut}/recurso/v2/carpeta-tributaria/obtenerValorParametro
|
|
9
|
+
* on 2026-09-11 (GH-111): a live session gets HTTP 200 `text/plain;charset=utf-8` with
|
|
10
|
+
* the bare URL of the "modificar email" SPA — the wrong endpoint, NOT a login wall, and
|
|
11
|
+
* the old message (status + content-type only) hid exactly the body that says so. A json-labelled
|
|
12
|
+
* non-JSON body gets the same treatment, spelled out (the content-type lied). Neither
|
|
13
|
+
* is something `requestJson` may return (the seam resolves parsed JSON only — ADR-003;
|
|
14
|
+
* a facade's zod envelope is where a bare string would fail, ADR-011). Pure, so it is
|
|
15
|
+
* unit-tested without launching Playwright. */
|
|
16
|
+
export declare function nonJsonResponseError(finalUrl: string, contentType: string, status: number, body?: string): Error;
|
|
9
17
|
/** Login-wall detection for an authenticated FORM POST (ADR-017). Unlike `requestJson`,
|
|
10
18
|
* an HTML body is EXPECTED (the `TMBECN_*` emit CGIs render HTML), so the content-type
|
|
11
19
|
* heuristic can't apply — a dead session is detected purely by the response landing on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/response.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/response.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;gDAcgD;AAChD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,SAAK,GACR,KAAK,CAmBP;AAQD;;;;kDAIkD;AAClD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAIjE;AAED;;;;qFAIqF;AACrF,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAYxE"}
|
|
@@ -1,19 +1,47 @@
|
|
|
1
1
|
import { LOGIN_HOST } from '../../config/index.js';
|
|
2
|
-
import { SessionExpiredError } from '../../errors/index.js';
|
|
2
|
+
import { SessionExpiredError, UnexpectedResponseError } from '../../errors/index.js';
|
|
3
|
+
/** How much of a non-JSON body the error carries. Enough to recognise the quirk (a bare
|
|
4
|
+
* URL, an HTML fragment, a SII notice) without dumping a whole page into a message that
|
|
5
|
+
* reaches the terminal or an MCP client (the audit log never records error messages —
|
|
6
|
+
* a failed task audits ids/periods only). */
|
|
7
|
+
const BODY_SNIPPET_CHARS = 80;
|
|
3
8
|
/** Classify a non-JSON SDI response. A dead/expired session makes an authenticated
|
|
4
9
|
* SDI POST get bounced to SII's login wall (HTML) instead of JSON; detect it the same
|
|
5
10
|
* URL-based way the rest of the auth flow does — landing on `LOGIN_HOST`, with an
|
|
6
11
|
* HTML content-type fallback for a same-host wall (ADR-009) — and return an ACTIONABLE
|
|
7
|
-
* `SessionExpiredError`. Anything else is a genuinely unexpected response →
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
12
|
+
* `SessionExpiredError`. Anything else is a genuinely unexpected response →
|
|
13
|
+
* `UnexpectedResponseError` naming the endpoint, status, content-type and the first
|
|
14
|
+
* chars of the body verbatim. Observed at
|
|
15
|
+
* https://www2.sii.cl/app/cte-api-carpetatributaria/{rut}/recurso/v2/carpeta-tributaria/obtenerValorParametro
|
|
16
|
+
* on 2026-09-11 (GH-111): a live session gets HTTP 200 `text/plain;charset=utf-8` with
|
|
17
|
+
* the bare URL of the "modificar email" SPA — the wrong endpoint, NOT a login wall, and
|
|
18
|
+
* the old message (status + content-type only) hid exactly the body that says so. A json-labelled
|
|
19
|
+
* non-JSON body gets the same treatment, spelled out (the content-type lied). Neither
|
|
20
|
+
* is something `requestJson` may return (the seam resolves parsed JSON only — ADR-003;
|
|
21
|
+
* a facade's zod envelope is where a bare string would fail, ADR-011). Pure, so it is
|
|
22
|
+
* unit-tested without launching Playwright. */
|
|
23
|
+
export function nonJsonResponseError(finalUrl, contentType, status, body = '') {
|
|
11
24
|
const ct = contentType.toLowerCase();
|
|
12
|
-
const
|
|
13
|
-
|
|
25
|
+
const url = new URL(finalUrl);
|
|
26
|
+
const bouncedToLogin = url.hostname === LOGIN_HOST;
|
|
27
|
+
// A real login wall is a 2xx/3xx HTML page (a same-host bounce). A 5xx HTML body is a SERVER
|
|
28
|
+
// error, not an expired session — don't mislabel it "sesión expiró" (observed 2026-10-18: www4
|
|
29
|
+
// answered HTTP 500 text/html to a malformed request; ADR-027 GH live validation).
|
|
30
|
+
if (bouncedToLogin || (ct.includes('text/html') && status < 500)) {
|
|
14
31
|
return new SessionExpiredError('La sesión expiró. Ejecuta `sii auth login`.');
|
|
15
32
|
}
|
|
16
|
-
|
|
33
|
+
const snippet = bodySnippet(body);
|
|
34
|
+
const claimsJson = ct.includes('json');
|
|
35
|
+
const what = claimsJson
|
|
36
|
+
? `SII declaró content-type ${ct} pero el cuerpo no es JSON`
|
|
37
|
+
: `Respuesta no-JSON de SII (${ct || 'sin content-type'})`;
|
|
38
|
+
return new UnexpectedResponseError(`${what} — HTTP ${status} en ${url.host}${url.pathname}` +
|
|
39
|
+
(snippet ? `: "${snippet}"` : ' (cuerpo vacío)'));
|
|
40
|
+
}
|
|
41
|
+
/** The first chars of a body, whitespace-collapsed, for an error message. */
|
|
42
|
+
function bodySnippet(body) {
|
|
43
|
+
const flat = body.replace(/\s+/g, ' ').trim();
|
|
44
|
+
return flat.length > BODY_SNIPPET_CHARS ? `${flat.slice(0, BODY_SNIPPET_CHARS)}…` : flat;
|
|
17
45
|
}
|
|
18
46
|
/** Login-wall detection for an authenticated FORM POST (ADR-017). Unlike `requestJson`,
|
|
19
47
|
* an HTML body is EXPECTED (the `TMBECN_*` emit CGIs render HTML), so the content-type
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/adapters/node/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/adapters/node/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErF;;;8CAG8C;AAC9C,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;gDAcgD;AAChD,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,WAAmB,EACnB,MAAc,EACd,IAAI,GAAG,EAAE;IAET,MAAM,EAAE,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,KAAK,UAAU,CAAC;IACnD,6FAA6F;IAC7F,+FAA+F;IAC/F,mFAAmF;IACnF,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;QACjE,OAAO,IAAI,mBAAmB,CAAC,6CAA6C,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,UAAU;QACrB,CAAC,CAAC,4BAA4B,EAAE,4BAA4B;QAC5D,CAAC,CAAC,6BAA6B,EAAE,IAAI,kBAAkB,GAAG,CAAC;IAC7D,OAAO,IAAI,uBAAuB,CAChC,GAAG,IAAI,WAAW,MAAM,OAAO,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE;QACtD,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC;AAED;;;;kDAIkD;AAClD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK,UAAU;QAC9C,CAAC,CAAC,IAAI,mBAAmB,CAAC,6CAA6C,CAAC;QACxE,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED;;;;qFAIqF;AACrF,MAAM,UAAU,SAAS,CAAC,WAAsC;IAC9D,MAAM,KAAK,GAAG,kBAAkB;SAC7B,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,EAAE,IAAI,EAAE;SACP,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,uDAAuD;QAC/E,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC"}
|
package/dist/auth/auth.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Rut } from '../rut/index.js';
|
|
2
2
|
import type { AccountType } from '../identity/index.js';
|
|
3
3
|
import type { Runtime } from '../seams/index.js';
|
|
4
|
+
import type { LoginBlockEntry } from './login-block.js';
|
|
4
5
|
export interface AuthIdentity {
|
|
5
6
|
readonly rut: string;
|
|
6
7
|
readonly nombre: string | null;
|
|
7
8
|
readonly accountType: AccountType;
|
|
8
9
|
}
|
|
10
|
+
/** `statusRefresh`: the live identity plus the www2 layer read LIVE (`/app/session/status`). */
|
|
11
|
+
export interface AuthIdentityRefresh extends AuthIdentity {
|
|
12
|
+
readonly www2: AuthWww2Status;
|
|
13
|
+
}
|
|
9
14
|
/** `whoami` — the AUTHENTICATED principal's own identity + contact. Session-keyed:
|
|
10
15
|
* it reads the login principal's `DatosCntrNow`, NOT the operate pointer (operate
|
|
11
16
|
* changes which RUT you ACT as, never who you ARE). PII by nature. */
|
|
@@ -16,27 +21,55 @@ export interface AuthWhoami {
|
|
|
16
21
|
readonly nombre: string | null;
|
|
17
22
|
readonly email: string | null;
|
|
18
23
|
}
|
|
24
|
+
/** The www2 APP-SESSION layer as reported by status (ADR-026). LOCAL: `authenticated` means the
|
|
25
|
+
* layer was minted and its cookie has not expired by the clock — not a server-side claim. */
|
|
26
|
+
export interface AuthWww2Status {
|
|
27
|
+
readonly authenticated: boolean;
|
|
28
|
+
readonly expiresAt: string | null;
|
|
29
|
+
}
|
|
19
30
|
export interface AuthStatusLocal {
|
|
20
31
|
/** LOCAL-only: a cookie jar exists on disk. NOT a server-side liveness claim. */
|
|
21
32
|
readonly authenticated: boolean;
|
|
22
33
|
readonly rut: string | null;
|
|
23
34
|
readonly sessionSource: 'cached' | 'none';
|
|
35
|
+
readonly www2: AuthWww2Status;
|
|
36
|
+
/** The rejection latch (ADR-028): RUTs whose last unattended login the SII rejected, with
|
|
37
|
+
* when and SII's código. Non-empty ⇒ env/stdin/keyring logins for those RUTs refuse without
|
|
38
|
+
* contacting SII until a person lifts it. Reported here so a caller checks it before it
|
|
39
|
+
* tries. Independent of the session: a live session keeps working while latched. */
|
|
40
|
+
readonly loginBlocked: readonly LoginBlockEntry[];
|
|
24
41
|
}
|
|
42
|
+
/** Where the Clave came from. Audited on every login (never the value — ADR-028); `browser` is
|
|
43
|
+
* the user typing at SII's own page (the MCP's `auth_login`). */
|
|
44
|
+
export type LoginSource = 'browser' | 'console' | 'keyring' | 'env' | 'stdin';
|
|
45
|
+
type FreshLoginReason = `${LoginSource}_login`;
|
|
25
46
|
export interface AuthLoginResult {
|
|
26
47
|
readonly authenticated: true;
|
|
27
48
|
readonly rut: string;
|
|
28
|
-
readonly reason:
|
|
49
|
+
readonly reason: FreshLoginReason | 'already_authenticated';
|
|
50
|
+
/** Set when `--www2` was requested: the www2 layer's state after this call (ADR-026). */
|
|
51
|
+
readonly www2?: AuthWww2Status;
|
|
29
52
|
}
|
|
30
53
|
export interface AuthLogoutResult {
|
|
31
54
|
readonly loggedOut: boolean;
|
|
32
55
|
readonly serverClosed: boolean;
|
|
56
|
+
/** Best-effort close of the www2 app session, when one was stored (ADR-026). */
|
|
57
|
+
readonly www2Closed: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Pure local read — NO portal call (sii-py "local-only" labelling). `now` decides whether the
|
|
60
|
+
* stored www2 layer is still within its cookie's own expiry. */
|
|
61
|
+
export declare function localStatus(store: Runtime['store'], now: Date): Promise<AuthStatusLocal>;
|
|
62
|
+
export interface LoginOptions {
|
|
63
|
+
/** Also mint the www2 APP-SESSION layer (ADR-026): after the classic login, the same headed
|
|
64
|
+
* browser opens the www2 app page and the user completes SII's OAuth login there. */
|
|
65
|
+
readonly www2?: boolean;
|
|
33
66
|
}
|
|
34
|
-
/** Pure local read — NO portal call (sii-py "local-only" labelling). */
|
|
35
|
-
export declare function localStatus(store: Runtime['store']): Promise<AuthStatusLocal>;
|
|
36
67
|
/** Browser cookies-only login (ADR-006). Only this + `consoleLogin` mint a session
|
|
37
68
|
* (ADR-019 lineage). Idempotent: a live cached session returns
|
|
38
|
-
* `already_authenticated` without opening a window.
|
|
39
|
-
|
|
69
|
+
* `already_authenticated` without opening a window. With `www2`, both layers must be live
|
|
70
|
+
* for that shortcut; otherwise the headed flow runs in full (classic login, then the www2
|
|
71
|
+
* step in the same browser — the classic page is what carries the user into SII). */
|
|
72
|
+
export declare function login(runtime: Runtime, options?: LoginOptions): Promise<AuthLoginResult>;
|
|
40
73
|
/** CLI-only console login (ADR-010): the Clave is typed into the TERMINAL, used
|
|
41
74
|
* once to fill SII's real form headless, and never persisted — only cookies are
|
|
42
75
|
* stored, exactly like the browser path. ONE attempt, never retried (ADR-004).
|
|
@@ -45,6 +78,16 @@ export declare function consoleLogin(runtime: Runtime, credentials: {
|
|
|
45
78
|
rut: string;
|
|
46
79
|
clave: string;
|
|
47
80
|
}): Promise<AuthLoginResult>;
|
|
81
|
+
/** CLI-only non-interactive login (ADR-028): the SURFACE read the Clave from an environment
|
|
82
|
+
* variable it was told to read (`--clave-env <VAR>`) or from piped stdin (`--clave-stdin`),
|
|
83
|
+
* and `source` records which. Everything else matches `consoleLogin`, plus the rejection
|
|
84
|
+
* latch: no one is at the keyboard to notice a stale Clave, so a latched RUT is refused
|
|
85
|
+
* without contacting SII. */
|
|
86
|
+
export declare function suppliedClaveLogin(runtime: Runtime, args: {
|
|
87
|
+
rut: string;
|
|
88
|
+
clave: string;
|
|
89
|
+
source: 'env' | 'stdin';
|
|
90
|
+
}): Promise<AuthLoginResult>;
|
|
48
91
|
/** The RUT renderings a human plausibly stored the entry under, in lookup order. The
|
|
49
92
|
* keyring is populated BY HAND (`secret-tool`, Seahorse, Keychain Access), so the code
|
|
50
93
|
* adapts to the human rather than the reverse (ADR-025). `Rut.parse` already upper-cases
|
|
@@ -57,16 +100,22 @@ export declare function keyringAccounts(rut: Rut): string[];
|
|
|
57
100
|
export declare function keyringLogin(runtime: Runtime, args: {
|
|
58
101
|
rut: string;
|
|
59
102
|
}): Promise<AuthLoginResult>;
|
|
103
|
+
/** Lift the rejection latch (ADR-028) for one RUT, or for all when none is given. A local
|
|
104
|
+
* wipe: nothing is sent to SII. Returns the RUTs that were latched. */
|
|
105
|
+
export declare function unblockLogin(runtime: Runtime, args?: {
|
|
106
|
+
rut?: string;
|
|
107
|
+
}): Promise<string[]>;
|
|
60
108
|
/** Server-side close (best-effort) + wipe local session + operate context. */
|
|
61
109
|
export declare function logout(runtime: Runtime): Promise<AuthLogoutResult>;
|
|
62
110
|
/** Curated identity readback from the portal. Requires a live session (no implicit
|
|
63
111
|
* login) — acquired via `withSession`; here an expired jar is an explicit
|
|
64
112
|
* NotAuthenticated (URL-based detection), since the whole job is the readback. */
|
|
65
|
-
export declare function statusRefresh(runtime: Runtime): Promise<
|
|
113
|
+
export declare function statusRefresh(runtime: Runtime): Promise<AuthIdentityRefresh>;
|
|
66
114
|
/** whoami — the session PRINCIPAL's own razón social/nombre + email, read live from
|
|
67
115
|
* the portal (like `statusRefresh`, plus the email). Session-keyed: ignores the
|
|
68
116
|
* operate pointer (no `--rut`). The audit records ONLY that a whoami read happened
|
|
69
117
|
* (keyed by rut) — never the razón social / email VALUES: that PII stays off the
|
|
70
118
|
* receipt, the LLM-facing MCP description declares the exposure instead (ADR-006). */
|
|
71
119
|
export declare function whoami(runtime: Runtime): Promise<AuthWhoami>;
|
|
120
|
+
export {};
|
|
72
121
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"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"}
|