ecwt 0.2.1-beta.6 → 0.2.4

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/main.cjs CHANGED
@@ -1,461 +1,275 @@
1
1
  "use strict";
2
+ //#region rolldown:runtime
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __getProtoOf = Object.getPrototypeOf;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
9
  var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
19
18
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/main.js
31
- var main_exports = {};
32
- __export(main_exports, {
33
- Ecwt: () => Ecwt,
34
- EcwtExpiredError: () => EcwtExpiredError,
35
- EcwtFactory: () => EcwtFactory,
36
- EcwtInvalidError: () => EcwtInvalidError,
37
- EcwtParseError: () => EcwtParseError,
38
- EcwtRevokedError: () => EcwtRevokedError
39
- });
40
- module.exports = __toCommonJS(main_exports);
41
-
42
- // src/factory.js
43
- var import_snowflake = require("@kirick/snowflake");
44
- var import_cbor_x = require("cbor-x");
45
- var import_evilcrypt = require("evilcrypt");
46
- var import_lru_cache = require("lru-cache");
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
47
23
 
48
- // src/utils/time.js
49
- function toSeconds(value) {
50
- return Math.floor(value / 1e3);
51
- }
24
+ //#endregion
25
+ const cbor_x = __toESM(require("cbor-x"));
26
+ const evilcrypt = __toESM(require("evilcrypt"));
27
+ const base_x = __toESM(require("base-x"));
52
28
 
53
- // src/token.js
29
+ //#region src/token.ts
54
30
  var Ecwt = class {
55
- /**
56
- * Token string representation.
57
- * @type {string}
58
- * @readonly
59
- */
60
- token;
61
- /**
62
- * Token ID.
63
- * @type {string}
64
- * @readonly
65
- */
66
- id;
67
- /**
68
- * Snowflake associated with token.
69
- * @type {Snowflake}
70
- * @readonly
71
- */
72
- snowflake;
73
- /**
74
- * Timestamp when token expires in seconds.
75
- * @type {number?}
76
- * @readonly
77
- */
78
- ts_expired;
79
- /**
80
- * Data stored in token.
81
- * @type {D}
82
- * @readonly
83
- */
84
- data;
85
- /** @type {EcwtFactory} */
86
- #ecwtFactory;
87
- /** @type {number | null} */
88
- #ttl_initial;
89
- /**
90
- * @param {EcwtFactory} ecwtFactory -
91
- * @param {object} options -
92
- * @param {string} options.token String representation of token.
93
- * @param {Snowflake} options.snowflake -
94
- * @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
95
- * @param {D} options.data Data stored in token.
96
- */
97
- constructor(ecwtFactory, {
98
- token,
99
- snowflake,
100
- ttl_initial,
101
- data
102
- }) {
103
- this.#ecwtFactory = ecwtFactory;
104
- this.#ttl_initial = ttl_initial;
105
- this.token = token;
106
- this.id = snowflake.toBase62();
107
- this.snowflake = snowflake;
108
- this.ts_expired = this.#getTimestampExpired();
109
- this.data = Object.freeze(data);
110
- }
111
- #getTimestampExpired() {
112
- if (this.#ttl_initial === null) {
113
- return null;
114
- }
115
- return toSeconds(this.snowflake.timestamp) + this.#ttl_initial;
116
- }
117
- /**
118
- * Actual time to live in seconds.
119
- * @returns {number | null} -
120
- */
121
- getTTL() {
122
- if (this.#ttl_initial === null) {
123
- return null;
124
- }
125
- return this.#ttl_initial - toSeconds(Date.now() - this.snowflake.timestamp);
126
- }
127
- /**
128
- * Revokes token.
129
- * @returns {Promise<void>} -
130
- */
131
- /* async */
132
- revoke() {
133
- return this.#ecwtFactory._revoke({
134
- token_id: this.id,
135
- ts_ms_created: this.snowflake.timestamp,
136
- ttl_initial: this.#ttl_initial
137
- });
138
- }
31
+ /** Token string representation. */
32
+ token;
33
+ /** Token ID. */
34
+ id;
35
+ /** Snowflake associated with token. */
36
+ snowflake;
37
+ /** Data stored in token. */
38
+ data;
39
+ ecwtFactory;
40
+ ttl_initial;
41
+ /**
42
+ * @param {EcwtFactory} ecwtFactory -
43
+ * @param {object} options -
44
+ * @param {string} options.token String representation of token.
45
+ * @param {Snowflake} options.snowflake -
46
+ * @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
47
+ * @param {D} options.data Data stored in token.
48
+ */
49
+ constructor(ecwtFactory, options) {
50
+ this.token = options.token;
51
+ this.id = options.snowflake.toBase62();
52
+ this.snowflake = options.snowflake;
53
+ this.data = Object.freeze(options.data);
54
+ this.ecwtFactory = ecwtFactory;
55
+ this.ttl_initial = options.ttl_initial;
56
+ }
57
+ /**
58
+ * Unix timestamp of token expiration in seconds.
59
+ * @returns -
60
+ */
61
+ get ts_expired() {
62
+ if (this.ttl_initial === null) return null;
63
+ return Math.floor(this.snowflake.timestamp / 1e3) + this.ttl_initial;
64
+ }
65
+ /**
66
+ * Actual time to live in seconds.
67
+ * @returns -
68
+ */
69
+ getTTL() {
70
+ if (this.ttl_initial === null) return null;
71
+ return this.ttl_initial - Math.floor((Date.now() - this.snowflake.timestamp) / 1e3);
72
+ }
73
+ /**
74
+ * Revokes token.
75
+ * @returns {} -
76
+ */
77
+ revoke() {
78
+ return this.ecwtFactory._revoke(this.id, this.snowflake.timestamp, this.ttl_initial);
79
+ }
139
80
  };
140
81
 
141
- // src/utils/base62.js
142
- var import_base_x = __toESM(require("base-x"), 1);
143
- var base62 = (0, import_base_x.default)("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
82
+ //#endregion
83
+ //#region src/utils.ts
84
+ const base62 = (0, base_x.default)("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
144
85
 
145
- // src/utils/errors.js
146
- var InvalidPackageInstanceError = class extends TypeError {
147
- /**
148
- * @param {string} property -
149
- * @param {string} class_name -
150
- * @param {string} package_name -
151
- */
152
- constructor(property, class_name, package_name) {
153
- super(
154
- `Value ${property} must be an instance of ${class_name} from package "${package_name}". That error is probably caused by two separate installations of "${package_name}". Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`
155
- );
156
- }
157
- };
86
+ //#endregion
87
+ //#region src/errors.ts
88
+ /** Error thrown when string token cannot be parsed to Ecwt. */
158
89
  var EcwtParseError = class extends Error {
159
- constructor() {
160
- super("Cannot parse data to Ecwt token.");
161
- }
90
+ constructor() {
91
+ super("Cannot parse data to Ecwt token.");
92
+ }
162
93
  };
94
+ /** Error thrown when parsed Ecwt is invalid. */
163
95
  var EcwtInvalidError = class extends Error {
164
- message = "Ecwt token is invalid.";
165
- /**
166
- * @param {Ecwt} ecwt -
167
- */
168
- constructor(ecwt) {
169
- super();
170
- this.ecwt = ecwt;
171
- }
96
+ message = "Ecwt token is invalid.";
97
+ constructor(ecwt) {
98
+ super();
99
+ this.ecwt = ecwt;
100
+ }
172
101
  };
102
+ /** Error thrown when parsed Ecwt is expired. */
173
103
  var EcwtExpiredError = class extends EcwtInvalidError {
174
- message = "Ecwt is expired.";
104
+ message = "Ecwt is expired.";
175
105
  };
106
+ /** Error thrown when parsed Ecwt is revoked. */
176
107
  var EcwtRevokedError = class extends EcwtInvalidError {
177
- message = "Ecwt is revoked.";
108
+ message = "Ecwt is revoked.";
178
109
  };
179
110
 
180
- // src/factory.js
181
- var REDIS_PREFIX = "@ecwt:";
111
+ //#endregion
112
+ //#region src/factory.ts
113
+ const REDIS_PREFIX = "@ecwt:";
182
114
  var EcwtFactory = class {
183
- #redisClient;
184
- #lruCache;
185
- #snowflakeFactory;
186
- #redis_key_revoked;
187
- #encryption_key;
188
- #validator;
189
- /** @type {CborEncoder | null} */
190
- #cborEncoder = null;
191
- /**
192
- * @param {object} param0 -
193
- * @param {import('redis').RedisClientType<import('redis').RedisModules, import('redis').RedisFunctions, import('redis').RedisScripts>} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
194
- * @param {LRUCache<string, CacheValue>} [param0.lruCache] LRUCache instance. If not provided, tokens will be decrypted every time they are verified.
195
- * @param {SnowflakeFactory} param0.snowflakeFactory SnowflakeFactory instance.
196
- * @param {object} param0.options -
197
- * @param {string} [param0.options.namespace] Namespace for Redis keys.
198
- * @param {Buffer} param0.options.key Encryption key, 64 bytes
199
- * @param {(value: unknown) => D} [param0.options.validator] Validator for token data. Should return validated value or throw an error.
200
- * @param {Record<string, number>} [param0.options.senml_key_map] Payload object keys mapped for their SenML keys.
201
- */
202
- constructor({
203
- redisClient,
204
- lruCache,
205
- snowflakeFactory,
206
- options: {
207
- namespace,
208
- key,
209
- validator,
210
- senml_key_map
211
- }
212
- }) {
213
- this.#redisClient = redisClient;
214
- if (lruCache !== void 0 && lruCache instanceof import_lru_cache.LRUCache !== true) {
215
- throw new InvalidPackageInstanceError(
216
- "lruCache",
217
- "LRUCache",
218
- "lru-cache"
219
- );
220
- }
221
- this.#lruCache = lruCache;
222
- if (snowflakeFactory instanceof import_snowflake.SnowflakeFactory !== true) {
223
- throw new InvalidPackageInstanceError(
224
- "snowflakeFactory",
225
- "SnowflakeFactory",
226
- "@kirick/snowflake"
227
- );
228
- }
229
- this.#snowflakeFactory = snowflakeFactory;
230
- this.#redis_key_revoked = `${REDIS_PREFIX}${namespace}:revoked`;
231
- this.#encryption_key = key;
232
- this.#validator = validator;
233
- if (senml_key_map) {
234
- this.#cborEncoder = new import_cbor_x.Encoder({
235
- keyMap: senml_key_map
236
- });
237
- }
238
- }
239
- /**
240
- * Creates new token.
241
- * @async
242
- * @param {D} data Data to be stored in token.
243
- * @param {object} [options] -
244
- * @param {number | null} [options.ttl] Time to live in seconds. By default, token will never expire.
245
- * @returns {Promise<Ecwt<D>>} -
246
- */
247
- async create(data, {
248
- ttl = null
249
- } = {}) {
250
- if (typeof this.#validator === "function") {
251
- data = this.#validator(data);
252
- }
253
- if (typeof ttl !== "number" && Number.isNaN(ttl) !== true && ttl !== null) {
254
- throw new TypeError("TTL must be a number or null.");
255
- }
256
- const snowflake = await this.#snowflakeFactory.createSafe();
257
- const payload = [
258
- snowflake.toBuffer(),
259
- ttl,
260
- data
261
- ];
262
- const token_raw = this.#cborEncoder ? this.#cborEncoder.encode(payload) : (0, import_cbor_x.encode)(payload);
263
- const token_encrypted = await import_evilcrypt.v2.encrypt(
264
- token_raw,
265
- this.#encryption_key
266
- );
267
- const token = base62.encode(token_encrypted);
268
- this.#setCache(
269
- token,
270
- {
271
- snowflake,
272
- ttl_initial: ttl,
273
- data
274
- }
275
- );
276
- return new Ecwt(
277
- this,
278
- {
279
- token,
280
- snowflake,
281
- ttl_initial: ttl,
282
- data
283
- }
284
- );
285
- }
286
- /**
287
- * Sets data to cache.
288
- * @param {string} token String representation of token.
289
- * @param {CacheValue} cache_value Data to be stored in cache.
290
- */
291
- #setCache(token, cache_value) {
292
- this.#lruCache?.set(
293
- token,
294
- cache_value,
295
- cache_value.ttl_initial === null ? void 0 : {
296
- ttl: cache_value.ttl_initial * 1e3
297
- }
298
- );
299
- }
300
- /**
301
- * Parses token.
302
- * @async
303
- * @param {string} token String representation of token.
304
- * @returns {Promise<Ecwt<D>>} -
305
- */
306
- async verify(token) {
307
- if (typeof token !== "string") {
308
- throw new TypeError("Token must be a string.");
309
- }
310
- let snowflake;
311
- let ttl_initial;
312
- let data;
313
- const cached_entry = this.#lruCache?.info(token);
314
- if (cached_entry === void 0) {
315
- const token_encrypted = Buffer.from(
316
- base62.decode(token)
317
- );
318
- let token_raw;
319
- try {
320
- token_raw = await (0, import_evilcrypt.decrypt)(
321
- token_encrypted,
322
- this.#encryption_key
323
- );
324
- } catch {
325
- throw new EcwtParseError();
326
- }
327
- const payload = this.#cborEncoder ? this.#cborEncoder.decode(token_raw) : (0, import_cbor_x.decode)(token_raw);
328
- const [snowflake_buffer] = payload;
329
- [
330
- ,
331
- ttl_initial,
332
- data
333
- ] = payload;
334
- snowflake = this.#snowflakeFactory.parse(snowflake_buffer);
335
- if (typeof this.#validator === "function") {
336
- try {
337
- data = this.#validator(data);
338
- } catch {
339
- throw new EcwtParseError();
340
- }
341
- }
342
- this.#setCache(
343
- token,
344
- {
345
- snowflake,
346
- ttl_initial,
347
- data
348
- }
349
- );
350
- } else {
351
- ({
352
- snowflake,
353
- ttl_initial,
354
- data
355
- } = cached_entry.value);
356
- }
357
- const ecwt = new Ecwt(
358
- this,
359
- {
360
- token,
361
- snowflake,
362
- ttl_initial,
363
- data
364
- }
365
- );
366
- if (typeof ttl_initial === "number" && Number.isNaN(ttl_initial) !== true && snowflake.timestamp + ttl_initial * 1e3 < Date.now()) {
367
- throw new EcwtExpiredError(ecwt);
368
- }
369
- if (this.#redisClient) {
370
- const score = await this.#redisClient.ZSCORE(
371
- this.#redis_key_revoked,
372
- ecwt.id
373
- );
374
- if (score !== null) {
375
- throw new EcwtRevokedError(ecwt);
376
- }
377
- }
378
- return ecwt;
379
- }
380
- /**
381
- * Parses token without throwing errors.
382
- * @async
383
- * @param {string} token String representation of token.
384
- * @returns {Promise<{ success: true, ecwt: Ecwt<D> } | { success: false, ecwt: Ecwt<D> | null }>} Returns whether token was parsed and verified successfully and Ecwt if parsed.
385
- */
386
- async safeVerify(token) {
387
- let ecwt = null;
388
- try {
389
- ecwt = await this.verify(token);
390
- return {
391
- success: true,
392
- ecwt
393
- };
394
- } catch (error) {
395
- if (error instanceof EcwtParseError) {
396
- return {
397
- success: false,
398
- ecwt: null
399
- };
400
- }
401
- if (error instanceof EcwtInvalidError) {
402
- return {
403
- success: false,
404
- ecwt
405
- };
406
- }
407
- throw error;
408
- }
409
- }
410
- /**
411
- * Revokes token.
412
- * @async
413
- * @param {object} options -
414
- * @param {string} options.token_id -
415
- * @param {number} options.ts_ms_created -
416
- * @param {number | null} options.ttl_initial -
417
- * @returns {Promise<void>} -
418
- */
419
- async _revoke({
420
- token_id,
421
- ts_ms_created,
422
- ttl_initial
423
- }) {
424
- if (this.#redisClient) {
425
- ttl_initial ??= Number.MAX_SAFE_INTEGER;
426
- const ts_ms_expired = ts_ms_created + ttl_initial * 1e3;
427
- if (ts_ms_expired > Date.now()) {
428
- await this.#redisClient.MULTI().addCommand([
429
- "ZADD",
430
- this.#redis_key_revoked,
431
- String(ts_ms_expired),
432
- token_id
433
- ]).addCommand([
434
- "ZREMRANGEBYSCORE",
435
- this.#redis_key_revoked,
436
- "-inf",
437
- String(Date.now())
438
- ]).EXEC();
439
- }
440
- } else {
441
- console.warn("[ecwt] Redis client is not provided. Tokens cannot be revoked.");
442
- }
443
- }
444
- /**
445
- * Purges cache.
446
- * @private
447
- * @returns {void} -
448
- */
449
- _purgeCache() {
450
- this.#lruCache?.clear();
451
- }
115
+ redisClient;
116
+ lruCache;
117
+ snowflakeFactory;
118
+ redis_key_revoked;
119
+ encryption_key;
120
+ validator;
121
+ cborEncoder = null;
122
+ constructor({ redisClient, lruCache, snowflakeFactory, options }) {
123
+ this.redisClient = redisClient;
124
+ this.lruCache = lruCache;
125
+ this.snowflakeFactory = snowflakeFactory;
126
+ this.redis_key_revoked = `${REDIS_PREFIX}${options.namespace}:revoked`;
127
+ this.encryption_key = options.key;
128
+ this.validator = options.validator;
129
+ if (options.senml_key_map) this.cborEncoder = new cbor_x.Encoder({ keyMap: options.senml_key_map });
130
+ }
131
+ /**
132
+ * Creates new token.
133
+ * @async
134
+ * @param data - Data to be stored in token.
135
+ * @param options -
136
+ * @param options.ttl - Time to live in seconds. If not defined, token will never expire.
137
+ * @returns -
138
+ */
139
+ async create(data, options = {}) {
140
+ if (typeof this.validator === "function") data = this.validator(data);
141
+ const ttl = options.ttl ?? null;
142
+ const snowflake = await this.snowflakeFactory.createSafe();
143
+ const payload = [
144
+ snowflake.toBuffer(),
145
+ ttl,
146
+ data
147
+ ];
148
+ const token_raw = this.cborEncoder ? this.cborEncoder.encode(payload) : (0, cbor_x.encode)(payload);
149
+ const token_encrypted = await evilcrypt.v2.encrypt(token_raw, this.encryption_key);
150
+ const token = base62.encode(token_encrypted);
151
+ this.setCache(token, {
152
+ snowflake,
153
+ ttl_initial: ttl,
154
+ data
155
+ });
156
+ return new Ecwt(this, {
157
+ token,
158
+ snowflake,
159
+ ttl_initial: ttl,
160
+ data
161
+ });
162
+ }
163
+ /**
164
+ * Sets data to cache.
165
+ * @param token - String representation of token.
166
+ * @param cache_value - Data to be stored in cache.
167
+ */
168
+ setCache(token, cache_value) {
169
+ this.lruCache?.set(token, cache_value, cache_value.ttl_initial === null ? void 0 : { ttl: cache_value.ttl_initial * 1e3 });
170
+ }
171
+ /**
172
+ * Parses token.
173
+ * @param token String representation of token.
174
+ * @returns -
175
+ */
176
+ async verify(token) {
177
+ if (typeof token !== "string") throw new TypeError("Token must be a string.");
178
+ let snowflake;
179
+ let ttl_initial;
180
+ let data;
181
+ const cached_entry = this.lruCache?.info(token);
182
+ if (cached_entry === void 0) {
183
+ const token_encrypted = Buffer.from(base62.decode(token));
184
+ let token_raw;
185
+ try {
186
+ token_raw = await (0, evilcrypt.decrypt)(token_encrypted, this.encryption_key);
187
+ } catch {
188
+ throw new EcwtParseError();
189
+ }
190
+ const payload = this.cborEncoder ? this.cborEncoder.decode(token_raw) : (0, cbor_x.decode)(token_raw);
191
+ const [snowflake_buffer] = payload;
192
+ [, ttl_initial, data] = payload;
193
+ snowflake = this.snowflakeFactory.parse(snowflake_buffer);
194
+ if (typeof this.validator === "function") try {
195
+ data = this.validator(data);
196
+ } catch {
197
+ throw new EcwtParseError();
198
+ }
199
+ this.setCache(token, {
200
+ snowflake,
201
+ ttl_initial,
202
+ data
203
+ });
204
+ } else ({snowflake, ttl_initial, data} = cached_entry.value);
205
+ const ecwt = new Ecwt(this, {
206
+ token,
207
+ snowflake,
208
+ ttl_initial,
209
+ data
210
+ });
211
+ if (typeof ttl_initial === "number" && Number.isNaN(ttl_initial) !== true && snowflake.timestamp + ttl_initial * 1e3 < Date.now()) throw new EcwtExpiredError(ecwt);
212
+ if (this.redisClient) {
213
+ const score = await this.redisClient.ZSCORE(this.redis_key_revoked, ecwt.id);
214
+ if (score !== null) throw new EcwtRevokedError(ecwt);
215
+ }
216
+ return ecwt;
217
+ }
218
+ /**
219
+ * Parses token without throwing errors.
220
+ * @param token - String representation of token.
221
+ * @returns Returns whether token was parsed and verified successfully and Ecwt if parsed.
222
+ */
223
+ async safeVerify(token) {
224
+ let ecwt = null;
225
+ try {
226
+ ecwt = await this.verify(token);
227
+ return {
228
+ success: true,
229
+ ecwt
230
+ };
231
+ } catch (error) {
232
+ if (error instanceof EcwtParseError) return {
233
+ success: false,
234
+ ecwt: null
235
+ };
236
+ if (error instanceof EcwtInvalidError) return {
237
+ success: false,
238
+ ecwt
239
+ };
240
+ throw error;
241
+ }
242
+ }
243
+ /**
244
+ * Revokes token.
245
+ * @param token_id -
246
+ * @param ts_ms_created -
247
+ * @param ttl_initial -
248
+ * @returns -
249
+ */
250
+ async _revoke(token_id, ts_ms_created, ttl_initial) {
251
+ if (this.redisClient) {
252
+ ttl_initial ??= Number.MAX_SAFE_INTEGER;
253
+ const ts_ms_expired = ts_ms_created + ttl_initial * 1e3;
254
+ if (ts_ms_expired > Date.now()) await this.redisClient.MULTI().ZADD(this.redis_key_revoked, {
255
+ score: ts_ms_expired,
256
+ value: token_id
257
+ }).ZREMRANGEBYSCORE(this.redis_key_revoked, "-inf", Date.now()).EXEC();
258
+ } else console.warn("[ecwt] Redis client is not provided. Tokens cannot be revoked.");
259
+ }
260
+ /**
261
+ * Purges LRU cache.
262
+ * @returns {void} -
263
+ */
264
+ _purgeCache() {
265
+ this.lruCache?.clear();
266
+ }
452
267
  };
453
- // Annotate the CommonJS export names for ESM import in node:
454
- 0 && (module.exports = {
455
- Ecwt,
456
- EcwtExpiredError,
457
- EcwtFactory,
458
- EcwtInvalidError,
459
- EcwtParseError,
460
- EcwtRevokedError
461
- });
268
+
269
+ //#endregion
270
+ exports.Ecwt = Ecwt
271
+ exports.EcwtExpiredError = EcwtExpiredError
272
+ exports.EcwtFactory = EcwtFactory
273
+ exports.EcwtInvalidError = EcwtInvalidError
274
+ exports.EcwtParseError = EcwtParseError
275
+ exports.EcwtRevokedError = EcwtRevokedError