@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 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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kedaruma/revlm-client",
3
- "version": "1.0.46",
3
+ "version": "1.0.48",
4
4
  "private": false,
5
5
  "description": "TypeScript client SDK for talking to the Revlm server replacement for MongoDB Realm.",
6
6
  "keywords": [