@kedaruma/revlm-client 1.0.46 → 1.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +54 -0
- package/dist/index.mjs +54 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -213,6 +213,8 @@ declare class Revlm {
|
|
|
213
213
|
private request;
|
|
214
214
|
private shouldSkipAuthRetry;
|
|
215
215
|
private shouldSkipCookieCheck;
|
|
216
|
+
private decodeJwtPayload;
|
|
217
|
+
private logTokenTtl;
|
|
216
218
|
private signIfNeeded;
|
|
217
219
|
private requestWithRetry;
|
|
218
220
|
login(authId: string, password: string): Promise<LoginResponse>;
|
package/dist/index.d.ts
CHANGED
|
@@ -213,6 +213,8 @@ declare class Revlm {
|
|
|
213
213
|
private request;
|
|
214
214
|
private shouldSkipAuthRetry;
|
|
215
215
|
private shouldSkipCookieCheck;
|
|
216
|
+
private decodeJwtPayload;
|
|
217
|
+
private logTokenTtl;
|
|
216
218
|
private signIfNeeded;
|
|
217
219
|
private requestWithRetry;
|
|
218
220
|
login(authId: string, password: string): Promise<LoginResponse>;
|
package/dist/index.js
CHANGED
|
@@ -240,6 +240,43 @@ var Revlm = class {
|
|
|
240
240
|
const pathname = path.startsWith("http") ? new URL(path).pathname : path;
|
|
241
241
|
return pathname.includes("/cookie-check");
|
|
242
242
|
}
|
|
243
|
+
decodeJwtPayload(token) {
|
|
244
|
+
if (!token) return null;
|
|
245
|
+
const parts = token.split(".");
|
|
246
|
+
const payloadPart = parts[1];
|
|
247
|
+
if (!payloadPart) return null;
|
|
248
|
+
const raw = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
249
|
+
const pad = raw.length % 4 ? "=".repeat(4 - raw.length % 4) : "";
|
|
250
|
+
const base64 = raw + pad;
|
|
251
|
+
let jsonText = null;
|
|
252
|
+
if (typeof atob === "function") {
|
|
253
|
+
jsonText = atob(base64);
|
|
254
|
+
} else if (typeof Buffer !== "undefined") {
|
|
255
|
+
jsonText = Buffer.from(base64, "base64").toString("utf8");
|
|
256
|
+
}
|
|
257
|
+
if (!jsonText) return null;
|
|
258
|
+
try {
|
|
259
|
+
const payload = JSON.parse(jsonText);
|
|
260
|
+
return { exp: payload?.exp, iat: payload?.iat };
|
|
261
|
+
} catch {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
logTokenTtl(event, path, tokenOverride) {
|
|
266
|
+
const token = tokenOverride || this._token;
|
|
267
|
+
if (!token) return;
|
|
268
|
+
const payload = this.decodeJwtPayload(token);
|
|
269
|
+
if (!payload || typeof payload.exp !== "number") return;
|
|
270
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
271
|
+
const ttlSec = payload.exp - now;
|
|
272
|
+
console.log("### token ttl", {
|
|
273
|
+
event,
|
|
274
|
+
path,
|
|
275
|
+
ttlSec,
|
|
276
|
+
exp: payload.exp,
|
|
277
|
+
iat: payload.iat
|
|
278
|
+
});
|
|
279
|
+
}
|
|
243
280
|
async signIfNeeded(_url, _method, headers, _body) {
|
|
244
281
|
return { signedUrl: _url, signedHeaders: headers };
|
|
245
282
|
}
|
|
@@ -269,6 +306,7 @@ var Revlm = class {
|
|
|
269
306
|
out.error = parsed?.reason || parsed?.message || "Unknown error";
|
|
270
307
|
}
|
|
271
308
|
if (allowAuthRetry && !retrying && res.status === 401 && !this.shouldSkipAuthRetry(path)) {
|
|
309
|
+
const beforePayload = this.decodeJwtPayload(this._token || "");
|
|
272
310
|
const refreshRes = await this.refreshToken();
|
|
273
311
|
if (!refreshRes.ok) {
|
|
274
312
|
console.warn("### refresh failed:", {
|
|
@@ -283,9 +321,23 @@ var Revlm = class {
|
|
|
283
321
|
}
|
|
284
322
|
}
|
|
285
323
|
if (refreshRes && refreshRes.ok && refreshRes.token) {
|
|
324
|
+
const afterPayload = this.decodeJwtPayload(refreshRes.token);
|
|
325
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
326
|
+
const oldExp = beforePayload?.exp;
|
|
327
|
+
const newExp = afterPayload?.exp;
|
|
328
|
+
console.log("### refresh success", {
|
|
329
|
+
path,
|
|
330
|
+
oldExp,
|
|
331
|
+
newExp,
|
|
332
|
+
oldTtlSec: typeof oldExp === "number" ? oldExp - now : void 0,
|
|
333
|
+
newTtlSec: typeof newExp === "number" ? newExp - now : void 0
|
|
334
|
+
});
|
|
286
335
|
return this.requestWithRetry(path, method, body, { allowAuthRetry: false, retrying: true });
|
|
287
336
|
}
|
|
288
337
|
}
|
|
338
|
+
if (out.ok && !this.shouldSkipCookieCheck(path)) {
|
|
339
|
+
this.logTokenTtl("request_ok", path);
|
|
340
|
+
}
|
|
289
341
|
return out;
|
|
290
342
|
} catch (err) {
|
|
291
343
|
if (err && err.revlmReason === "no_refresh_secret") {
|
|
@@ -337,11 +389,13 @@ var Revlm = class {
|
|
|
337
389
|
if (this.cookieCheckPromise) return this.cookieCheckPromise;
|
|
338
390
|
this.cookieCheckPromise = (async () => {
|
|
339
391
|
const first = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
392
|
+
console.log("### cookie check", { step: "first", ok: first.ok, reason: first.reason, status: first.status });
|
|
340
393
|
if (first.ok) return;
|
|
341
394
|
if (first.reason !== "cookie_missing") {
|
|
342
395
|
throw new Error(`Cookie check failed: ${first.reason || first.error || "unknown_error"}`);
|
|
343
396
|
}
|
|
344
397
|
const second = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
398
|
+
console.log("### cookie check", { step: "second", ok: second.ok, reason: second.reason, status: second.status });
|
|
345
399
|
if (!second.ok) {
|
|
346
400
|
throw new Error("Cookie support missing. Provide a cookie-aware fetch implementation for Node/RN.");
|
|
347
401
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -197,6 +197,43 @@ var Revlm = class {
|
|
|
197
197
|
const pathname = path.startsWith("http") ? new URL(path).pathname : path;
|
|
198
198
|
return pathname.includes("/cookie-check");
|
|
199
199
|
}
|
|
200
|
+
decodeJwtPayload(token) {
|
|
201
|
+
if (!token) return null;
|
|
202
|
+
const parts = token.split(".");
|
|
203
|
+
const payloadPart = parts[1];
|
|
204
|
+
if (!payloadPart) return null;
|
|
205
|
+
const raw = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
206
|
+
const pad = raw.length % 4 ? "=".repeat(4 - raw.length % 4) : "";
|
|
207
|
+
const base64 = raw + pad;
|
|
208
|
+
let jsonText = null;
|
|
209
|
+
if (typeof atob === "function") {
|
|
210
|
+
jsonText = atob(base64);
|
|
211
|
+
} else if (typeof Buffer !== "undefined") {
|
|
212
|
+
jsonText = Buffer.from(base64, "base64").toString("utf8");
|
|
213
|
+
}
|
|
214
|
+
if (!jsonText) return null;
|
|
215
|
+
try {
|
|
216
|
+
const payload = JSON.parse(jsonText);
|
|
217
|
+
return { exp: payload?.exp, iat: payload?.iat };
|
|
218
|
+
} catch {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
logTokenTtl(event, path, tokenOverride) {
|
|
223
|
+
const token = tokenOverride || this._token;
|
|
224
|
+
if (!token) return;
|
|
225
|
+
const payload = this.decodeJwtPayload(token);
|
|
226
|
+
if (!payload || typeof payload.exp !== "number") return;
|
|
227
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
228
|
+
const ttlSec = payload.exp - now;
|
|
229
|
+
console.log("### token ttl", {
|
|
230
|
+
event,
|
|
231
|
+
path,
|
|
232
|
+
ttlSec,
|
|
233
|
+
exp: payload.exp,
|
|
234
|
+
iat: payload.iat
|
|
235
|
+
});
|
|
236
|
+
}
|
|
200
237
|
async signIfNeeded(_url, _method, headers, _body) {
|
|
201
238
|
return { signedUrl: _url, signedHeaders: headers };
|
|
202
239
|
}
|
|
@@ -226,6 +263,7 @@ var Revlm = class {
|
|
|
226
263
|
out.error = parsed?.reason || parsed?.message || "Unknown error";
|
|
227
264
|
}
|
|
228
265
|
if (allowAuthRetry && !retrying && res.status === 401 && !this.shouldSkipAuthRetry(path)) {
|
|
266
|
+
const beforePayload = this.decodeJwtPayload(this._token || "");
|
|
229
267
|
const refreshRes = await this.refreshToken();
|
|
230
268
|
if (!refreshRes.ok) {
|
|
231
269
|
console.warn("### refresh failed:", {
|
|
@@ -240,9 +278,23 @@ var Revlm = class {
|
|
|
240
278
|
}
|
|
241
279
|
}
|
|
242
280
|
if (refreshRes && refreshRes.ok && refreshRes.token) {
|
|
281
|
+
const afterPayload = this.decodeJwtPayload(refreshRes.token);
|
|
282
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
283
|
+
const oldExp = beforePayload?.exp;
|
|
284
|
+
const newExp = afterPayload?.exp;
|
|
285
|
+
console.log("### refresh success", {
|
|
286
|
+
path,
|
|
287
|
+
oldExp,
|
|
288
|
+
newExp,
|
|
289
|
+
oldTtlSec: typeof oldExp === "number" ? oldExp - now : void 0,
|
|
290
|
+
newTtlSec: typeof newExp === "number" ? newExp - now : void 0
|
|
291
|
+
});
|
|
243
292
|
return this.requestWithRetry(path, method, body, { allowAuthRetry: false, retrying: true });
|
|
244
293
|
}
|
|
245
294
|
}
|
|
295
|
+
if (out.ok && !this.shouldSkipCookieCheck(path)) {
|
|
296
|
+
this.logTokenTtl("request_ok", path);
|
|
297
|
+
}
|
|
246
298
|
return out;
|
|
247
299
|
} catch (err) {
|
|
248
300
|
if (err && err.revlmReason === "no_refresh_secret") {
|
|
@@ -294,11 +346,13 @@ var Revlm = class {
|
|
|
294
346
|
if (this.cookieCheckPromise) return this.cookieCheckPromise;
|
|
295
347
|
this.cookieCheckPromise = (async () => {
|
|
296
348
|
const first = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
349
|
+
console.log("### cookie check", { step: "first", ok: first.ok, reason: first.reason, status: first.status });
|
|
297
350
|
if (first.ok) return;
|
|
298
351
|
if (first.reason !== "cookie_missing") {
|
|
299
352
|
throw new Error(`Cookie check failed: ${first.reason || first.error || "unknown_error"}`);
|
|
300
353
|
}
|
|
301
354
|
const second = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
355
|
+
console.log("### cookie check", { step: "second", ok: second.ok, reason: second.reason, status: second.status });
|
|
302
356
|
if (!second.ok) {
|
|
303
357
|
throw new Error("Cookie support missing. Provide a cookie-aware fetch implementation for Node/RN.");
|
|
304
358
|
}
|