ecwt 0.2.1-beta.6 → 0.2.5
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/README.md +197 -157
- package/bun.lock +948 -0
- package/dist/main.cjs +249 -435
- package/dist/main.d.ts +160 -0
- package/dist/main.js +246 -0
- package/package.json +28 -23
- package/bun.lockb +0 -0
- package/dist/types/factory.d.ts +0 -97
- package/dist/types/main.d.ts +0 -4
- package/dist/types/token.d.ts +0 -66
- package/dist/types/utils/base62.d.ts +0 -2
- package/dist/types/utils/errors.d.ts +0 -38
- package/dist/types/utils/time.d.ts +0 -6
- package/src/factory.js +0 -385
- package/src/main.js +0 -13
- package/src/token.js +0 -106
- package/src/utils/base62.js +0 -4
- package/src/utils/errors.js +0 -58
- package/src/utils/time.js +0 -17
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('../token.js').Ecwt} Ecwt
|
|
3
|
-
*/
|
|
4
|
-
export class InvalidPackageInstanceError extends TypeError {
|
|
5
|
-
/**
|
|
6
|
-
* @param {string} property -
|
|
7
|
-
* @param {string} class_name -
|
|
8
|
-
* @param {string} package_name -
|
|
9
|
-
*/
|
|
10
|
-
constructor(property: string, class_name: string, package_name: string);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Error thrown when string token cannot be parsed to Ecwt.
|
|
14
|
-
*/
|
|
15
|
-
export class EcwtParseError extends Error {
|
|
16
|
-
constructor();
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Error thrown when parsed Ecwt is invalid.
|
|
20
|
-
*/
|
|
21
|
-
export class EcwtInvalidError extends Error {
|
|
22
|
-
/**
|
|
23
|
-
* @param {Ecwt} ecwt -
|
|
24
|
-
*/
|
|
25
|
-
constructor(ecwt: Ecwt);
|
|
26
|
-
ecwt: import("../token.js").Ecwt<Record<string, any>>;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Error thrown when parsed Ecwt is expired.
|
|
30
|
-
*/
|
|
31
|
-
export class EcwtExpiredError extends EcwtInvalidError {
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Error thrown when parsed Ecwt is revoked.
|
|
35
|
-
*/
|
|
36
|
-
export class EcwtRevokedError extends EcwtInvalidError {
|
|
37
|
-
}
|
|
38
|
-
export type Ecwt = import("../token.js").Ecwt;
|
package/src/factory.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {import('@kirick/snowflake').Snowflake} Snowflake
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {object} CacheValue
|
|
7
|
-
* @property {Snowflake} snowflake -
|
|
8
|
-
* @property {number | null} ttl_initial -
|
|
9
|
-
* @property {Record<string, any>} data -
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { SnowflakeFactory } from '@kirick/snowflake';
|
|
13
|
-
import {
|
|
14
|
-
Encoder as CborEncoder,
|
|
15
|
-
encode as cborEncode,
|
|
16
|
-
decode as cborDecode,
|
|
17
|
-
} from 'cbor-x';
|
|
18
|
-
import {
|
|
19
|
-
decrypt as evilcryptDecrypt,
|
|
20
|
-
v2 as evilcryptV2,
|
|
21
|
-
} from 'evilcrypt';
|
|
22
|
-
import { LRUCache } from 'lru-cache';
|
|
23
|
-
import { Ecwt } from './token.js';
|
|
24
|
-
import { base62 } from './utils/base62.js';
|
|
25
|
-
import {
|
|
26
|
-
InvalidPackageInstanceError,
|
|
27
|
-
EcwtInvalidError,
|
|
28
|
-
EcwtExpiredError,
|
|
29
|
-
EcwtRevokedError,
|
|
30
|
-
EcwtParseError,
|
|
31
|
-
} from './utils/errors.js';
|
|
32
|
-
|
|
33
|
-
const REDIS_PREFIX = '@ecwt:';
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @template {Record<string, any>} [D=Record<string, any>]
|
|
37
|
-
*/
|
|
38
|
-
export class EcwtFactory {
|
|
39
|
-
#redisClient;
|
|
40
|
-
#lruCache;
|
|
41
|
-
#snowflakeFactory;
|
|
42
|
-
#redis_key_revoked;
|
|
43
|
-
#encryption_key;
|
|
44
|
-
#validator;
|
|
45
|
-
/** @type {CborEncoder | null} */
|
|
46
|
-
#cborEncoder = null;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @param {object} param0 -
|
|
50
|
-
* @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.
|
|
51
|
-
* @param {LRUCache<string, CacheValue>} [param0.lruCache] LRUCache instance. If not provided, tokens will be decrypted every time they are verified.
|
|
52
|
-
* @param {SnowflakeFactory} param0.snowflakeFactory SnowflakeFactory instance.
|
|
53
|
-
* @param {object} param0.options -
|
|
54
|
-
* @param {string} [param0.options.namespace] Namespace for Redis keys.
|
|
55
|
-
* @param {Buffer} param0.options.key Encryption key, 64 bytes
|
|
56
|
-
* @param {(value: unknown) => D} [param0.options.validator] Validator for token data. Should return validated value or throw an error.
|
|
57
|
-
* @param {Record<string, number>} [param0.options.senml_key_map] Payload object keys mapped for their SenML keys.
|
|
58
|
-
*/
|
|
59
|
-
constructor({
|
|
60
|
-
redisClient,
|
|
61
|
-
lruCache,
|
|
62
|
-
snowflakeFactory,
|
|
63
|
-
options: {
|
|
64
|
-
namespace,
|
|
65
|
-
key,
|
|
66
|
-
validator,
|
|
67
|
-
senml_key_map,
|
|
68
|
-
},
|
|
69
|
-
}) {
|
|
70
|
-
this.#redisClient = redisClient;
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
lruCache !== undefined
|
|
74
|
-
&& lruCache instanceof LRUCache !== true
|
|
75
|
-
) {
|
|
76
|
-
throw new InvalidPackageInstanceError(
|
|
77
|
-
'lruCache',
|
|
78
|
-
'LRUCache',
|
|
79
|
-
'lru-cache',
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.#lruCache = lruCache;
|
|
84
|
-
|
|
85
|
-
if (snowflakeFactory instanceof SnowflakeFactory !== true) {
|
|
86
|
-
throw new InvalidPackageInstanceError(
|
|
87
|
-
'snowflakeFactory',
|
|
88
|
-
'SnowflakeFactory',
|
|
89
|
-
'@kirick/snowflake',
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.#snowflakeFactory = snowflakeFactory;
|
|
94
|
-
|
|
95
|
-
this.#redis_key_revoked = `${REDIS_PREFIX}${namespace}:revoked`;
|
|
96
|
-
|
|
97
|
-
this.#encryption_key = key;
|
|
98
|
-
|
|
99
|
-
this.#validator = validator;
|
|
100
|
-
|
|
101
|
-
if (senml_key_map) {
|
|
102
|
-
this.#cborEncoder = new CborEncoder({
|
|
103
|
-
keyMap: senml_key_map,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates new token.
|
|
110
|
-
* @async
|
|
111
|
-
* @param {D} data Data to be stored in token.
|
|
112
|
-
* @param {object} [options] -
|
|
113
|
-
* @param {number | null} [options.ttl] Time to live in seconds. By default, token will never expire.
|
|
114
|
-
* @returns {Promise<Ecwt<D>>} -
|
|
115
|
-
*/
|
|
116
|
-
async create(
|
|
117
|
-
data,
|
|
118
|
-
{
|
|
119
|
-
ttl = null,
|
|
120
|
-
} = {},
|
|
121
|
-
) {
|
|
122
|
-
if (typeof this.#validator === 'function') {
|
|
123
|
-
data = this.#validator(data);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
typeof ttl !== 'number'
|
|
128
|
-
&& Number.isNaN(ttl) !== true
|
|
129
|
-
&& ttl !== null
|
|
130
|
-
) {
|
|
131
|
-
throw new TypeError('TTL must be a number or null.');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const snowflake = await this.#snowflakeFactory.createSafe();
|
|
135
|
-
|
|
136
|
-
const payload = [
|
|
137
|
-
snowflake.toBuffer(),
|
|
138
|
-
ttl,
|
|
139
|
-
data,
|
|
140
|
-
];
|
|
141
|
-
const token_raw = this.#cborEncoder
|
|
142
|
-
? this.#cborEncoder.encode(payload)
|
|
143
|
-
: cborEncode(payload);
|
|
144
|
-
|
|
145
|
-
const token_encrypted = await evilcryptV2.encrypt(
|
|
146
|
-
token_raw,
|
|
147
|
-
this.#encryption_key,
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
const token = base62.encode(token_encrypted);
|
|
151
|
-
|
|
152
|
-
this.#setCache(
|
|
153
|
-
token,
|
|
154
|
-
{
|
|
155
|
-
snowflake,
|
|
156
|
-
ttl_initial: ttl,
|
|
157
|
-
data,
|
|
158
|
-
},
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
return new Ecwt(
|
|
162
|
-
this,
|
|
163
|
-
{
|
|
164
|
-
token,
|
|
165
|
-
snowflake,
|
|
166
|
-
ttl_initial: ttl,
|
|
167
|
-
data,
|
|
168
|
-
},
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Sets data to cache.
|
|
174
|
-
* @param {string} token String representation of token.
|
|
175
|
-
* @param {CacheValue} cache_value Data to be stored in cache.
|
|
176
|
-
*/
|
|
177
|
-
#setCache(token, cache_value) {
|
|
178
|
-
this.#lruCache?.set(
|
|
179
|
-
token,
|
|
180
|
-
cache_value,
|
|
181
|
-
cache_value.ttl_initial === null
|
|
182
|
-
? undefined
|
|
183
|
-
: {
|
|
184
|
-
ttl: cache_value.ttl_initial * 1000,
|
|
185
|
-
},
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Parses token.
|
|
191
|
-
* @async
|
|
192
|
-
* @param {string} token String representation of token.
|
|
193
|
-
* @returns {Promise<Ecwt<D>>} -
|
|
194
|
-
*/
|
|
195
|
-
async verify(token) {
|
|
196
|
-
if (typeof token !== 'string') {
|
|
197
|
-
throw new TypeError('Token must be a string.');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
let snowflake;
|
|
201
|
-
let ttl_initial;
|
|
202
|
-
let data;
|
|
203
|
-
|
|
204
|
-
const cached_entry = this.#lruCache?.info(token);
|
|
205
|
-
// token is not cached
|
|
206
|
-
if (cached_entry === undefined) {
|
|
207
|
-
const token_encrypted = Buffer.from(
|
|
208
|
-
base62.decode(token),
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
let token_raw;
|
|
212
|
-
try {
|
|
213
|
-
token_raw = await evilcryptDecrypt(
|
|
214
|
-
token_encrypted,
|
|
215
|
-
this.#encryption_key,
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
catch {
|
|
219
|
-
throw new EcwtParseError();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const payload = this.#cborEncoder
|
|
223
|
-
? this.#cborEncoder.decode(token_raw)
|
|
224
|
-
: cborDecode(token_raw);
|
|
225
|
-
|
|
226
|
-
const [ snowflake_buffer ] = payload;
|
|
227
|
-
[
|
|
228
|
-
,
|
|
229
|
-
ttl_initial,
|
|
230
|
-
data,
|
|
231
|
-
] = payload;
|
|
232
|
-
|
|
233
|
-
snowflake = this.#snowflakeFactory.parse(snowflake_buffer);
|
|
234
|
-
|
|
235
|
-
if (typeof this.#validator === 'function') {
|
|
236
|
-
try {
|
|
237
|
-
data = this.#validator(data);
|
|
238
|
-
}
|
|
239
|
-
catch {
|
|
240
|
-
throw new EcwtParseError();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
this.#setCache(
|
|
245
|
-
token,
|
|
246
|
-
{
|
|
247
|
-
snowflake,
|
|
248
|
-
ttl_initial,
|
|
249
|
-
data,
|
|
250
|
-
},
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
({
|
|
255
|
-
snowflake,
|
|
256
|
-
ttl_initial,
|
|
257
|
-
data,
|
|
258
|
-
} = cached_entry.value);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// console.log('snowflake', snowflake);
|
|
262
|
-
// console.log('ttl', ttl);
|
|
263
|
-
// console.log('data', data);
|
|
264
|
-
|
|
265
|
-
const ecwt = new Ecwt(
|
|
266
|
-
this,
|
|
267
|
-
{
|
|
268
|
-
token,
|
|
269
|
-
snowflake,
|
|
270
|
-
ttl_initial,
|
|
271
|
-
data,
|
|
272
|
-
},
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
typeof ttl_initial === 'number'
|
|
277
|
-
&& Number.isNaN(ttl_initial) !== true
|
|
278
|
-
&& snowflake.timestamp + (ttl_initial * 1000) < Date.now()
|
|
279
|
-
) {
|
|
280
|
-
throw new EcwtExpiredError(ecwt);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (this.#redisClient) {
|
|
284
|
-
const score = await this.#redisClient.ZSCORE(
|
|
285
|
-
this.#redis_key_revoked,
|
|
286
|
-
ecwt.id,
|
|
287
|
-
);
|
|
288
|
-
if (score !== null) {
|
|
289
|
-
throw new EcwtRevokedError(ecwt);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return ecwt;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Parses token without throwing errors.
|
|
298
|
-
* @async
|
|
299
|
-
* @param {string} token String representation of token.
|
|
300
|
-
* @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.
|
|
301
|
-
*/
|
|
302
|
-
async safeVerify(token) {
|
|
303
|
-
let ecwt = null;
|
|
304
|
-
try {
|
|
305
|
-
ecwt = await this.verify(token);
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
success: true,
|
|
309
|
-
ecwt,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
catch (error) {
|
|
313
|
-
if (error instanceof EcwtParseError) {
|
|
314
|
-
return {
|
|
315
|
-
success: false,
|
|
316
|
-
ecwt: null,
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (error instanceof EcwtInvalidError) {
|
|
321
|
-
return {
|
|
322
|
-
success: false,
|
|
323
|
-
ecwt,
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
throw error;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Revokes token.
|
|
333
|
-
* @async
|
|
334
|
-
* @param {object} options -
|
|
335
|
-
* @param {string} options.token_id -
|
|
336
|
-
* @param {number} options.ts_ms_created -
|
|
337
|
-
* @param {number | null} options.ttl_initial -
|
|
338
|
-
* @returns {Promise<void>} -
|
|
339
|
-
*/
|
|
340
|
-
async _revoke({
|
|
341
|
-
token_id,
|
|
342
|
-
ts_ms_created,
|
|
343
|
-
ttl_initial,
|
|
344
|
-
}) {
|
|
345
|
-
if (this.#redisClient) {
|
|
346
|
-
ttl_initial ??= Number.MAX_SAFE_INTEGER;
|
|
347
|
-
|
|
348
|
-
const ts_ms_expired = ts_ms_created + (ttl_initial * 1000);
|
|
349
|
-
if (ts_ms_expired > Date.now()) {
|
|
350
|
-
// await this.#redisClient.sendCommand([
|
|
351
|
-
// 'ZADD',
|
|
352
|
-
// this.#redis_keys.revoked,
|
|
353
|
-
// String(ts_ms_expired),
|
|
354
|
-
// token_id,
|
|
355
|
-
// ]);
|
|
356
|
-
await this.#redisClient.MULTI()
|
|
357
|
-
.addCommand([
|
|
358
|
-
'ZADD',
|
|
359
|
-
this.#redis_key_revoked,
|
|
360
|
-
String(ts_ms_expired),
|
|
361
|
-
token_id,
|
|
362
|
-
])
|
|
363
|
-
.addCommand([
|
|
364
|
-
'ZREMRANGEBYSCORE',
|
|
365
|
-
this.#redis_key_revoked,
|
|
366
|
-
'-inf',
|
|
367
|
-
String(Date.now()),
|
|
368
|
-
])
|
|
369
|
-
.EXEC();
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
console.warn('[ecwt] Redis client is not provided. Tokens cannot be revoked.');
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Purges cache.
|
|
379
|
-
* @private
|
|
380
|
-
* @returns {void} -
|
|
381
|
-
*/
|
|
382
|
-
_purgeCache() {
|
|
383
|
-
this.#lruCache?.clear();
|
|
384
|
-
}
|
|
385
|
-
}
|
package/src/main.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {import('./factory.js').CacheValue} CacheValue
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export { EcwtFactory } from './factory.js';
|
|
7
|
-
export { Ecwt } from './token.js';
|
|
8
|
-
export {
|
|
9
|
-
EcwtParseError,
|
|
10
|
-
EcwtInvalidError,
|
|
11
|
-
EcwtExpiredError,
|
|
12
|
-
EcwtRevokedError,
|
|
13
|
-
} from './utils/errors.js';
|
package/src/token.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { toSeconds } from './utils/time.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {import('@kirick/snowflake').Snowflake} Snowflake
|
|
6
|
-
* @typedef {import('./factory.js').EcwtFactory} EcwtFactory
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @template {Record<string, any>} [D=Record<string, any>]
|
|
11
|
-
*/
|
|
12
|
-
export class Ecwt {
|
|
13
|
-
/**
|
|
14
|
-
* Token string representation.
|
|
15
|
-
* @type {string}
|
|
16
|
-
* @readonly
|
|
17
|
-
*/
|
|
18
|
-
token;
|
|
19
|
-
/**
|
|
20
|
-
* Token ID.
|
|
21
|
-
* @type {string}
|
|
22
|
-
* @readonly
|
|
23
|
-
*/
|
|
24
|
-
id;
|
|
25
|
-
/**
|
|
26
|
-
* Snowflake associated with token.
|
|
27
|
-
* @type {Snowflake}
|
|
28
|
-
* @readonly
|
|
29
|
-
*/
|
|
30
|
-
snowflake;
|
|
31
|
-
/**
|
|
32
|
-
* Timestamp when token expires in seconds.
|
|
33
|
-
* @type {number?}
|
|
34
|
-
* @readonly
|
|
35
|
-
*/
|
|
36
|
-
ts_expired;
|
|
37
|
-
/**
|
|
38
|
-
* Data stored in token.
|
|
39
|
-
* @type {D}
|
|
40
|
-
* @readonly
|
|
41
|
-
*/
|
|
42
|
-
data;
|
|
43
|
-
/** @type {EcwtFactory} */
|
|
44
|
-
#ecwtFactory;
|
|
45
|
-
/** @type {number | null} */
|
|
46
|
-
#ttl_initial;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @param {EcwtFactory} ecwtFactory -
|
|
50
|
-
* @param {object} options -
|
|
51
|
-
* @param {string} options.token String representation of token.
|
|
52
|
-
* @param {Snowflake} options.snowflake -
|
|
53
|
-
* @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
|
|
54
|
-
* @param {D} options.data Data stored in token.
|
|
55
|
-
*/
|
|
56
|
-
constructor(
|
|
57
|
-
ecwtFactory,
|
|
58
|
-
{
|
|
59
|
-
token,
|
|
60
|
-
snowflake,
|
|
61
|
-
ttl_initial,
|
|
62
|
-
data,
|
|
63
|
-
},
|
|
64
|
-
) {
|
|
65
|
-
this.#ecwtFactory = ecwtFactory;
|
|
66
|
-
this.#ttl_initial = ttl_initial;
|
|
67
|
-
|
|
68
|
-
this.token = token;
|
|
69
|
-
this.id = snowflake.toBase62();
|
|
70
|
-
this.snowflake = snowflake;
|
|
71
|
-
this.ts_expired = this.#getTimestampExpired();
|
|
72
|
-
this.data = Object.freeze(data);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#getTimestampExpired() {
|
|
76
|
-
if (this.#ttl_initial === null) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return toSeconds(this.snowflake.timestamp) + this.#ttl_initial;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Actual time to live in seconds.
|
|
85
|
-
* @returns {number | null} -
|
|
86
|
-
*/
|
|
87
|
-
getTTL() {
|
|
88
|
-
if (this.#ttl_initial === null) {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return this.#ttl_initial - toSeconds(Date.now() - this.snowflake.timestamp);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Revokes token.
|
|
97
|
-
* @returns {Promise<void>} -
|
|
98
|
-
*/
|
|
99
|
-
/* async */ revoke() {
|
|
100
|
-
return this.#ecwtFactory._revoke({
|
|
101
|
-
token_id: this.id,
|
|
102
|
-
ts_ms_created: this.snowflake.timestamp,
|
|
103
|
-
ttl_initial: this.#ttl_initial,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
package/src/utils/base62.js
DELETED
package/src/utils/errors.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {import('../token.js').Ecwt} Ecwt
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export class InvalidPackageInstanceError extends TypeError {
|
|
7
|
-
/**
|
|
8
|
-
* @param {string} property -
|
|
9
|
-
* @param {string} class_name -
|
|
10
|
-
* @param {string} package_name -
|
|
11
|
-
*/
|
|
12
|
-
constructor(property, class_name, package_name) {
|
|
13
|
-
super(
|
|
14
|
-
`Value ${property} must be an instance of ${class_name} from package "${package_name}".`
|
|
15
|
-
+ ` That error is probably caused by two separate installations of "${package_name}".`
|
|
16
|
-
+ ` Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`,
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Error thrown when string token cannot be parsed to Ecwt.
|
|
23
|
-
*/
|
|
24
|
-
export class EcwtParseError extends Error {
|
|
25
|
-
constructor() {
|
|
26
|
-
super('Cannot parse data to Ecwt token.');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Error thrown when parsed Ecwt is invalid.
|
|
32
|
-
*/
|
|
33
|
-
export class EcwtInvalidError extends Error {
|
|
34
|
-
message = 'Ecwt token is invalid.';
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @param {Ecwt} ecwt -
|
|
38
|
-
*/
|
|
39
|
-
constructor(ecwt) {
|
|
40
|
-
super();
|
|
41
|
-
|
|
42
|
-
this.ecwt = ecwt;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Error thrown when parsed Ecwt is expired.
|
|
48
|
-
*/
|
|
49
|
-
export class EcwtExpiredError extends EcwtInvalidError {
|
|
50
|
-
message = 'Ecwt is expired.';
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Error thrown when parsed Ecwt is revoked.
|
|
55
|
-
*/
|
|
56
|
-
export class EcwtRevokedError extends EcwtInvalidError {
|
|
57
|
-
message = 'Ecwt is revoked.';
|
|
58
|
-
}
|
package/src/utils/time.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Convert timestamp in seconds to milliseconds.
|
|
4
|
-
* @param {*} value Timestamp in milliseconds.
|
|
5
|
-
* @returns {number} Timestamp in seconds.
|
|
6
|
-
*/
|
|
7
|
-
export function toSeconds(value) {
|
|
8
|
-
return Math.floor(value / 1000);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// /**
|
|
12
|
-
// * Returns current timestamp in seconds.
|
|
13
|
-
// * @returns {number} Timestamp in seconds.
|
|
14
|
-
// */
|
|
15
|
-
// export function unixtime() {
|
|
16
|
-
// return toSeconds(Date.now());
|
|
17
|
-
// }
|