aziendasanitaria-utils 1.2.72 → 1.2.73
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/package.json +1 -1
- package/src/narTsServices/Nar2.js +38 -9
package/package.json
CHANGED
|
@@ -236,10 +236,23 @@ export class Nar2 {
|
|
|
236
236
|
password: this._password
|
|
237
237
|
}, {
|
|
238
238
|
headers: {
|
|
239
|
-
'Content-Type': 'application/json'
|
|
239
|
+
'Content-Type': 'application/json',
|
|
240
|
+
// NAR2 valida l'header Origin sul login (controllo CSRF): SENZA,
|
|
241
|
+
// risponde 200 con body "error" e nessun token. Nel browser è
|
|
242
|
+
// automatico; da Node lo impostiamo a mano. (Diagnosi 13/06/2026.)
|
|
243
|
+
'Origin': new URL(Nar2.LOGIN_URL).origin
|
|
240
244
|
}
|
|
241
245
|
});
|
|
242
|
-
Nar2.#token = out.data.accessToken;
|
|
246
|
+
Nar2.#token = (out.data && typeof out.data === "object") ? out.data.accessToken : undefined;
|
|
247
|
+
if (!Nar2.#token) {
|
|
248
|
+
// Login andato in 200 ma SENZA token (es. body letterale "error"):
|
|
249
|
+
// il login username/password potrebbe non essere più attivo (NAR2 via
|
|
250
|
+
// SPID). Mostro l'indicazione del server e ritorno undefined: il
|
|
251
|
+
// chiamante può richiedere un token esterno (setTokenEsterno).
|
|
252
|
+
const ind = typeof out.data === "string" ? out.data : JSON.stringify(out.data ?? null);
|
|
253
|
+
console.log(`[getToken] Login NAR2 SENZA accessToken (HTTP ${out.status}, risposta: ${String(ind).slice(0, 200)}). ` +
|
|
254
|
+
`Login username/password non attivo? Imposta un token con Nar2.setTokenEsterno(<bearer SPID>).`);
|
|
255
|
+
}
|
|
243
256
|
return Nar2.#token;
|
|
244
257
|
} else {
|
|
245
258
|
const data = {username: this._username, password: this._password, type: "token"};
|
|
@@ -456,14 +469,17 @@ export class Nar2 {
|
|
|
456
469
|
* @returns {Promise<{ok:boolean, data:Array<Object>|null, error?:string}>}
|
|
457
470
|
*/
|
|
458
471
|
async getMotiviScelta(saId, config = {}) {
|
|
459
|
-
|
|
472
|
+
// Dropdown non critico: l'endpoint motiviOperazioneFiltered è spesso lento/intermittente.
|
|
473
|
+
// Timeout breve e pochi retry → se non risponde fallisce in fretta e il chiamante usa il
|
|
474
|
+
// default, invece di restare appeso (prima fino a ~4×10 tentativi senza timeout).
|
|
475
|
+
const {soloScelta = true, semplifica = false, retryVuoto = 0, timeout = 8000, maxRetry = 1} = config;
|
|
460
476
|
let data = null;
|
|
461
477
|
let lastRes = null;
|
|
462
478
|
for (let i = 0; i <= retryVuoto; i++) {
|
|
463
479
|
// NB: endpoint con envelope {status, result} → modalità default (unwrap di result),
|
|
464
480
|
// a differenza di getMotiviOperazione il cui endpoint risponde con array nudo.
|
|
465
481
|
const res = await this.#getDataFromUrlIdOrParams(Nar2.MOTIVI_OPERAZIONE_FILTERED, {
|
|
466
|
-
replaceFromUrl: {sa_id: saId}
|
|
482
|
+
replaceFromUrl: {sa_id: saId}, timeout, maxRetry
|
|
467
483
|
});
|
|
468
484
|
lastRes = res;
|
|
469
485
|
if (res.ok && Array.isArray(res.data)) {
|
|
@@ -2028,7 +2044,9 @@ export class Nar2 {
|
|
|
2028
2044
|
console.log("[getDatiAssistitoNar2FromCf] Eccezione durante recupero Nar2:", e.message);
|
|
2029
2045
|
}
|
|
2030
2046
|
if (datiAssistito && datiAssistito.ok) break;
|
|
2031
|
-
else console.log("[getDatiAssistitoNar2FromCf] Errore Nar2, tentativi rimanenti:" + (retry - i)
|
|
2047
|
+
else console.log("[getDatiAssistitoNar2FromCf] Errore Nar2, tentativi rimanenti:" + (retry - i)
|
|
2048
|
+
+ (datiIdAssistito?.error ? ` | indicazione: ${datiIdAssistito.error}` : "")
|
|
2049
|
+
+ (datiIdAssistito?.errorDetail?.statusCode ? ` (HTTP ${datiIdAssistito.errorDetail.statusCode})` : ""));
|
|
2032
2050
|
}
|
|
2033
2051
|
if (datiAssistito && datiAssistito.ok) {
|
|
2034
2052
|
try {
|
|
@@ -2189,6 +2207,8 @@ export class Nar2 {
|
|
|
2189
2207
|
getParams = null,
|
|
2190
2208
|
replaceFromUrl = null,
|
|
2191
2209
|
rawResponse = false, // se true, accetta risposte non incapsulate in {status, result}
|
|
2210
|
+
timeout = 30000, // ms: evita hang indefiniti su endpoint NAR2 lenti/intermittenti
|
|
2211
|
+
maxRetry = this._maxRetry,
|
|
2192
2212
|
} = config;
|
|
2193
2213
|
let out = {ok: false, data: null, error: null, errorDetail: null};
|
|
2194
2214
|
let ok = false;
|
|
@@ -2208,7 +2228,7 @@ export class Nar2 {
|
|
|
2208
2228
|
finalUrl = finalUrl.replace(`{${key}}`, (value === null || typeof value === "undefined") ? "null" : value.toString());
|
|
2209
2229
|
}
|
|
2210
2230
|
|
|
2211
|
-
for (let i = 0; i <
|
|
2231
|
+
for (let i = 0; i < maxRetry && !ok; i++) {
|
|
2212
2232
|
try {
|
|
2213
2233
|
await this.getToken();
|
|
2214
2234
|
let response = null;
|
|
@@ -2217,6 +2237,7 @@ export class Nar2 {
|
|
|
2217
2237
|
headers: {
|
|
2218
2238
|
Authorization: `Bearer ${Nar2.#token}`,
|
|
2219
2239
|
},
|
|
2240
|
+
timeout,
|
|
2220
2241
|
});
|
|
2221
2242
|
else
|
|
2222
2243
|
response = await axios.get(finalUrl, {
|
|
@@ -2224,6 +2245,7 @@ export class Nar2 {
|
|
|
2224
2245
|
Authorization: `Bearer ${Nar2.#token}`,
|
|
2225
2246
|
},
|
|
2226
2247
|
params: params,
|
|
2248
|
+
timeout,
|
|
2227
2249
|
});
|
|
2228
2250
|
|
|
2229
2251
|
// Caso 1: risposta raw (array nudo o oggetto senza envelope)
|
|
@@ -3037,7 +3059,10 @@ export class Nar2 {
|
|
|
3037
3059
|
assistito = new Assistito();
|
|
3038
3060
|
}
|
|
3039
3061
|
|
|
3040
|
-
|
|
3062
|
+
// Sogei va spesso in 500 lato server (consistente): bastano pochi tentativi prima di
|
|
3063
|
+
// passare al fallback legacy TS — inutile insistere 10 volte.
|
|
3064
|
+
const maxTentativiSogei = 2;
|
|
3065
|
+
for (let i = 0; i < maxTentativiSogei && !ok; i++) {
|
|
3041
3066
|
try {
|
|
3042
3067
|
await this.getToken({fallback});
|
|
3043
3068
|
let out = null;
|
|
@@ -3087,12 +3112,16 @@ export class Nar2 {
|
|
|
3087
3112
|
};
|
|
3088
3113
|
}
|
|
3089
3114
|
} catch (e) {
|
|
3090
|
-
|
|
3115
|
+
const stHttp = e.response?.status;
|
|
3116
|
+
const body = e.response?.data;
|
|
3117
|
+
const ind = typeof body === "string" ? body.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim().slice(0, 200)
|
|
3118
|
+
: (body ? JSON.stringify(body).slice(0, 200) : "");
|
|
3119
|
+
console.log(`[getDatiAssistitoFromCfSuSogeiNew] Errore tentativo Sogei: HTTP ${stHttp ?? "?"} — ${e.message}${ind ? ` | risposta: ${ind}` : ""}`);
|
|
3091
3120
|
await this.getToken({fallback});
|
|
3092
3121
|
}
|
|
3093
3122
|
}
|
|
3094
3123
|
if (!ok) {
|
|
3095
|
-
console.log(`[getDatiAssistitoFromCfSuSogeiNew] Sogei fallito dopo ${
|
|
3124
|
+
console.log(`[getDatiAssistitoFromCfSuSogeiNew] Sogei fallito dopo ${maxTentativiSogei} tentativi per CF: ${cf?.substring(0, 6)}*** — provo fallback legacy TS`);
|
|
3096
3125
|
try {
|
|
3097
3126
|
const fb = await this.#fallbackLegacyTsToP801(cf, assistito);
|
|
3098
3127
|
if (fb) {
|