@dereekb/calcom 13.10.8 → 13.11.0
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/nestjs/index.cjs.js +274 -179
- package/nestjs/index.esm.js +276 -181
- package/nestjs/package.json +5 -5
- package/nestjs/src/lib/oauth/oauth.service.d.ts +15 -4
- package/package.json +4 -4
package/nestjs/index.cjs.js
CHANGED
|
@@ -3,19 +3,18 @@
|
|
|
3
3
|
var common = require('@nestjs/common');
|
|
4
4
|
var calcom = require('@dereekb/calcom');
|
|
5
5
|
var util = require('@dereekb/util');
|
|
6
|
+
var nestjs = require('@dereekb/nestjs');
|
|
6
7
|
var node_crypto = require('node:crypto');
|
|
7
8
|
var node_path = require('node:path');
|
|
8
|
-
var node_fs = require('node:fs');
|
|
9
9
|
var config = require('@nestjs/config');
|
|
10
|
-
var nestjs = require('@dereekb/nestjs');
|
|
11
10
|
|
|
12
|
-
function _type_of(obj) {
|
|
11
|
+
function _type_of$1(obj) {
|
|
13
12
|
"@swc/helpers - typeof";
|
|
14
13
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
15
14
|
}
|
|
16
15
|
function __decorate(decorators, target, key, desc) {
|
|
17
16
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
18
|
-
if ((typeof Reflect === "undefined" ? "undefined" : _type_of(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
+
if ((typeof Reflect === "undefined" ? "undefined" : _type_of$1(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
19
18
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
20
19
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
21
20
|
}
|
|
@@ -47,7 +46,7 @@ function _create_class$6(Constructor, protoProps, staticProps) {
|
|
|
47
46
|
if (staticProps) _defineProperties$6(Constructor, staticProps);
|
|
48
47
|
return Constructor;
|
|
49
48
|
}
|
|
50
|
-
function _define_property$
|
|
49
|
+
function _define_property$8(obj, key, value) {
|
|
51
50
|
if (key in obj) {
|
|
52
51
|
Object.defineProperty(obj, key, {
|
|
53
52
|
value: value,
|
|
@@ -70,8 +69,8 @@ var CALCOM_API_KEY_CONFIG_KEY = 'CALCOM_API_KEY';
|
|
|
70
69
|
*/ var CalcomOAuthServiceConfig = /*#__PURE__*/ function() {
|
|
71
70
|
function CalcomOAuthServiceConfig() {
|
|
72
71
|
_class_call_check$8(this, CalcomOAuthServiceConfig);
|
|
73
|
-
_define_property$
|
|
74
|
-
_define_property$
|
|
72
|
+
_define_property$8(this, "calcomOAuth", void 0);
|
|
73
|
+
_define_property$8(this, "factoryConfig", void 0);
|
|
75
74
|
}
|
|
76
75
|
_create_class$6(CalcomOAuthServiceConfig, null, [
|
|
77
76
|
{
|
|
@@ -158,6 +157,27 @@ function _class_call_check$7(instance, Constructor) {
|
|
|
158
157
|
throw new TypeError("Cannot call a class as a function");
|
|
159
158
|
}
|
|
160
159
|
}
|
|
160
|
+
function _define_property$7(obj, key, value) {
|
|
161
|
+
if (key in obj) {
|
|
162
|
+
Object.defineProperty(obj, key, {
|
|
163
|
+
value: value,
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
166
|
+
writable: true
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
obj[key] = value;
|
|
170
|
+
}
|
|
171
|
+
return obj;
|
|
172
|
+
}
|
|
173
|
+
function _instanceof(left, right) {
|
|
174
|
+
"@swc/helpers - instanceof";
|
|
175
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
176
|
+
return !!right[Symbol.hasInstance](left);
|
|
177
|
+
} else {
|
|
178
|
+
return left instanceof right;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
161
181
|
function _iterable_to_array$3(iter) {
|
|
162
182
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
163
183
|
}
|
|
@@ -191,12 +211,50 @@ function _non_iterable_rest() {
|
|
|
191
211
|
function _non_iterable_spread$3() {
|
|
192
212
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
193
213
|
}
|
|
214
|
+
function _object_spread$2(target) {
|
|
215
|
+
for(var i = 1; i < arguments.length; i++){
|
|
216
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
217
|
+
var ownKeys = Object.keys(source);
|
|
218
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
219
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
220
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
ownKeys.forEach(function(key) {
|
|
224
|
+
_define_property$7(target, key, source[key]);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return target;
|
|
228
|
+
}
|
|
229
|
+
function ownKeys$2(object, enumerableOnly) {
|
|
230
|
+
var keys = Object.keys(object);
|
|
231
|
+
if (Object.getOwnPropertySymbols) {
|
|
232
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
233
|
+
keys.push.apply(keys, symbols);
|
|
234
|
+
}
|
|
235
|
+
return keys;
|
|
236
|
+
}
|
|
237
|
+
function _object_spread_props$2(target, source) {
|
|
238
|
+
source = source != null ? source : {};
|
|
239
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
240
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
241
|
+
} else {
|
|
242
|
+
ownKeys$2(Object(source)).forEach(function(key) {
|
|
243
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return target;
|
|
247
|
+
}
|
|
194
248
|
function _sliced_to_array(arr, i) {
|
|
195
249
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest();
|
|
196
250
|
}
|
|
197
251
|
function _to_consumable_array$3(arr) {
|
|
198
252
|
return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
|
|
199
253
|
}
|
|
254
|
+
function _type_of(obj) {
|
|
255
|
+
"@swc/helpers - typeof";
|
|
256
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
257
|
+
}
|
|
200
258
|
function _unsupported_iterable_to_array$3(o, minLen) {
|
|
201
259
|
if (!o) return;
|
|
202
260
|
if (typeof o === "string") return _array_like_to_array$3(o, minLen);
|
|
@@ -326,6 +384,56 @@ exports.CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
326
384
|
*/ function calcomRefreshTokenCacheKey(refreshToken) {
|
|
327
385
|
return node_crypto.createHash('sha256').update(refreshToken).digest('hex').substring(0, 16);
|
|
328
386
|
}
|
|
387
|
+
// MARK: Merge
|
|
388
|
+
function buildCalcomReadAdapter(cache) {
|
|
389
|
+
return {
|
|
390
|
+
load: function load() {
|
|
391
|
+
return _async_to_generator$2(function() {
|
|
392
|
+
var value;
|
|
393
|
+
return _ts_generator$2(this, function(_state) {
|
|
394
|
+
switch(_state.label){
|
|
395
|
+
case 0:
|
|
396
|
+
return [
|
|
397
|
+
4,
|
|
398
|
+
cache.loadCachedToken().catch(function() {
|
|
399
|
+
return undefined;
|
|
400
|
+
})
|
|
401
|
+
];
|
|
402
|
+
case 1:
|
|
403
|
+
value = _state.sent();
|
|
404
|
+
return [
|
|
405
|
+
2,
|
|
406
|
+
value != null && !util.isExpired(value) ? value : undefined
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
})();
|
|
411
|
+
},
|
|
412
|
+
update: function update(token) {
|
|
413
|
+
return cache.updateCachedToken(token);
|
|
414
|
+
},
|
|
415
|
+
clear: function clear() {
|
|
416
|
+
return _async_to_generator$2(function() {
|
|
417
|
+
return _ts_generator$2(this, function(_state) {
|
|
418
|
+
return [
|
|
419
|
+
2
|
|
420
|
+
];
|
|
421
|
+
});
|
|
422
|
+
// CalcomAccessTokenCache does not expose a clear method.
|
|
423
|
+
})();
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function updateCalcomCacheCapturingError(cache, accessToken) {
|
|
428
|
+
return cache.updateCachedToken(accessToken).then(function() {
|
|
429
|
+
return null;
|
|
430
|
+
}).catch(function(e) {
|
|
431
|
+
return [
|
|
432
|
+
cache,
|
|
433
|
+
e
|
|
434
|
+
];
|
|
435
|
+
});
|
|
436
|
+
}
|
|
329
437
|
/**
|
|
330
438
|
* Default error logging function for {@link mergeCalcomOAuthAccessTokenCacheServices}.
|
|
331
439
|
* Logs a warning for each cache that failed to update.
|
|
@@ -344,6 +452,11 @@ exports.CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
344
452
|
* If one source fails retrieval, the next will be tried.
|
|
345
453
|
* When updating a cached token, it will update the token across all services.
|
|
346
454
|
*
|
|
455
|
+
* Read fall-through is delegated to {@link mergeAsyncValueCaches} after wrapping each
|
|
456
|
+
* underlying cache with an {@link isExpired}-aware filter, so an expired cached token
|
|
457
|
+
* never short-circuits the lookup. Updates run across all services in parallel via
|
|
458
|
+
* `Promise.allSettled`, mirroring the previous behavior, with optional error logging.
|
|
459
|
+
*
|
|
347
460
|
* @param inputServicesToMerge Must include at least one service. Empty arrays will throw an error.
|
|
348
461
|
* @param logError - optional error logging configuration; pass a function, true for default logging, or false to disable
|
|
349
462
|
* @returns a merged CalcomOAuthAccessTokenCacheService that delegates across all input services
|
|
@@ -353,60 +466,44 @@ exports.CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
353
466
|
if (allServices.length === 0) {
|
|
354
467
|
throw new Error('mergeCalcomOAuthAccessTokenCacheServices() input cannot be empty.');
|
|
355
468
|
}
|
|
356
|
-
|
|
357
|
-
var
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
return x.loadCachedToken().catch(function() {
|
|
361
|
-
return null;
|
|
362
|
-
}).then(function(x) {
|
|
363
|
-
var result = undefined;
|
|
364
|
-
if (x && !util.isPast(x.expiresAt)) {
|
|
365
|
-
result = x; // only return from cache if it is not expired
|
|
366
|
-
}
|
|
367
|
-
return result;
|
|
368
|
-
});
|
|
369
|
-
};
|
|
370
|
-
}),
|
|
371
|
-
successOnMaybe: false,
|
|
372
|
-
throwErrors: false
|
|
373
|
-
});
|
|
374
|
-
var cacheForService = {
|
|
469
|
+
function mergeCachesForService(accessCachesForServices) {
|
|
470
|
+
var readAdapters = accessCachesForServices.map(buildCalcomReadAdapter);
|
|
471
|
+
var merged = util.mergeAsyncValueCaches(readAdapters);
|
|
472
|
+
return {
|
|
375
473
|
loadCachedToken: function loadCachedToken() {
|
|
376
|
-
return
|
|
474
|
+
return merged.load();
|
|
377
475
|
},
|
|
378
476
|
updateCachedToken: function updateCachedToken(accessToken) {
|
|
379
477
|
return _async_to_generator$2(function() {
|
|
478
|
+
var settled, failedUpdates;
|
|
380
479
|
return _ts_generator$2(this, function(_state) {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
});
|
|
392
|
-
})).then(function(x) {
|
|
393
|
-
// only find the failures if we're logging
|
|
480
|
+
switch(_state.label){
|
|
481
|
+
case 0:
|
|
482
|
+
return [
|
|
483
|
+
4,
|
|
484
|
+
Promise.allSettled(accessCachesForServices.map(function(cache) {
|
|
485
|
+
return updateCalcomCacheCapturingError(cache, accessToken);
|
|
486
|
+
}))
|
|
487
|
+
];
|
|
488
|
+
case 1:
|
|
489
|
+
settled = _state.sent();
|
|
394
490
|
if (logErrorFunction != null) {
|
|
395
|
-
|
|
491
|
+
failedUpdates = util.filterMaybeArrayValues(settled.map(function(y) {
|
|
396
492
|
return y.value;
|
|
397
493
|
}));
|
|
398
494
|
if (failedUpdates.length) {
|
|
399
495
|
logErrorFunction(failedUpdates);
|
|
400
496
|
}
|
|
401
497
|
}
|
|
402
|
-
|
|
403
|
-
|
|
498
|
+
return [
|
|
499
|
+
2
|
|
500
|
+
];
|
|
501
|
+
}
|
|
404
502
|
});
|
|
405
503
|
})();
|
|
406
504
|
}
|
|
407
505
|
};
|
|
408
|
-
|
|
409
|
-
};
|
|
506
|
+
}
|
|
410
507
|
var allServiceAccessTokenCaches = allServices.map(function(x) {
|
|
411
508
|
return x.loadCalcomAccessTokenCache();
|
|
412
509
|
});
|
|
@@ -417,206 +514,204 @@ exports.CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
417
514
|
var allCaches = allServicesWithCacheForRefreshToken.map(function(x) {
|
|
418
515
|
return x.cacheForRefreshToken(refreshToken);
|
|
419
516
|
});
|
|
420
|
-
return
|
|
517
|
+
return mergeCachesForService(allCaches);
|
|
421
518
|
} : undefined;
|
|
422
519
|
var service = {
|
|
423
|
-
loadCalcomAccessTokenCache: function
|
|
424
|
-
return
|
|
520
|
+
loadCalcomAccessTokenCache: function loadCalcomAccessTokenCache() {
|
|
521
|
+
return mergeCachesForService(allServiceAccessTokenCaches);
|
|
425
522
|
},
|
|
426
523
|
cacheForRefreshToken: cacheForRefreshToken
|
|
427
524
|
};
|
|
428
525
|
return service;
|
|
429
526
|
}
|
|
430
527
|
// MARK: Memory Access Token Cache
|
|
528
|
+
/**
|
|
529
|
+
* Adapts an {@link AsyncValueCache} to a {@link CalcomAccessTokenCache}, optionally logging cache reads/writes to the console.
|
|
530
|
+
*
|
|
531
|
+
* @param cache - underlying single-value cache for the access token
|
|
532
|
+
* @param logAccessToConsole - when true, logs reads and writes to the console
|
|
533
|
+
* @returns the CalcomAccessTokenCache backed by the given async cache
|
|
534
|
+
*/ function calcomAccessTokenCacheFromAsyncValueCache(cache, logAccessToConsole) {
|
|
535
|
+
return {
|
|
536
|
+
loadCachedToken: function loadCachedToken() {
|
|
537
|
+
return _async_to_generator$2(function() {
|
|
538
|
+
var token;
|
|
539
|
+
return _ts_generator$2(this, function(_state) {
|
|
540
|
+
switch(_state.label){
|
|
541
|
+
case 0:
|
|
542
|
+
return [
|
|
543
|
+
4,
|
|
544
|
+
cache.load()
|
|
545
|
+
];
|
|
546
|
+
case 1:
|
|
547
|
+
token = _state.sent();
|
|
548
|
+
if (logAccessToConsole) {
|
|
549
|
+
console.log('retrieving access token from memory: ', {
|
|
550
|
+
hit: token != null,
|
|
551
|
+
expiresAt: token === null || token === void 0 ? void 0 : token.expiresAt
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
return [
|
|
555
|
+
2,
|
|
556
|
+
token
|
|
557
|
+
];
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
})();
|
|
561
|
+
},
|
|
562
|
+
updateCachedToken: function updateCachedToken(accessToken) {
|
|
563
|
+
return _async_to_generator$2(function() {
|
|
564
|
+
return _ts_generator$2(this, function(_state) {
|
|
565
|
+
switch(_state.label){
|
|
566
|
+
case 0:
|
|
567
|
+
return [
|
|
568
|
+
4,
|
|
569
|
+
cache.update(accessToken)
|
|
570
|
+
];
|
|
571
|
+
case 1:
|
|
572
|
+
_state.sent();
|
|
573
|
+
if (logAccessToConsole) {
|
|
574
|
+
console.log('updating access token in memory: ', {
|
|
575
|
+
expiresAt: accessToken === null || accessToken === void 0 ? void 0 : accessToken.expiresAt
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
return [
|
|
579
|
+
2
|
|
580
|
+
];
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
})();
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
}
|
|
431
587
|
/**
|
|
432
588
|
* Creates a CalcomOAuthAccessTokenCacheService that uses in-memory storage.
|
|
433
|
-
*
|
|
589
|
+
*
|
|
590
|
+
* The server-level token is held in a single-slot {@link inMemoryAsyncValueCache};
|
|
591
|
+
* per-user tokens are held in an {@link inMemoryAsyncKeyedValueCache} keyed by the
|
|
592
|
+
* sha256-truncated refresh token hash.
|
|
434
593
|
*
|
|
435
594
|
* @param existingToken - optional pre-existing server-level access token to seed the cache
|
|
436
595
|
* @param logAccessToConsole - when true, logs all cache reads and writes to console
|
|
437
|
-
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory
|
|
596
|
+
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory caches
|
|
438
597
|
*/ function memoryCalcomOAuthAccessTokenCacheService(existingToken, logAccessToConsole) {
|
|
439
|
-
var
|
|
440
|
-
var
|
|
441
|
-
function
|
|
598
|
+
var serverCache = util.inMemoryAsyncValueCache(existingToken);
|
|
599
|
+
var userCache = util.inMemoryAsyncKeyedValueCache();
|
|
600
|
+
function userCacheView(key) {
|
|
442
601
|
return {
|
|
443
|
-
|
|
444
|
-
return
|
|
445
|
-
var token;
|
|
446
|
-
return _ts_generator$2(this, function(_state) {
|
|
447
|
-
token = getToken();
|
|
448
|
-
if (logAccessToConsole) {
|
|
449
|
-
console.log('retrieving access token from memory: ', {
|
|
450
|
-
token: token
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
return [
|
|
454
|
-
2,
|
|
455
|
-
token
|
|
456
|
-
];
|
|
457
|
-
});
|
|
458
|
-
})();
|
|
602
|
+
load: function load() {
|
|
603
|
+
return userCache.get(key);
|
|
459
604
|
},
|
|
460
|
-
|
|
461
|
-
return
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
console.log('updating access token in memory: ', {
|
|
466
|
-
accessToken: accessToken
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
return [
|
|
470
|
-
2
|
|
471
|
-
];
|
|
472
|
-
});
|
|
473
|
-
})();
|
|
605
|
+
update: function update(token) {
|
|
606
|
+
return userCache.set(key, token);
|
|
607
|
+
},
|
|
608
|
+
clear: function clear() {
|
|
609
|
+
return userCache.remove(key);
|
|
474
610
|
}
|
|
475
611
|
};
|
|
476
612
|
}
|
|
477
613
|
return {
|
|
478
614
|
loadCalcomAccessTokenCache: function loadCalcomAccessTokenCache() {
|
|
479
|
-
return
|
|
480
|
-
return serverToken;
|
|
481
|
-
}, function(t) {
|
|
482
|
-
serverToken = t;
|
|
483
|
-
});
|
|
615
|
+
return calcomAccessTokenCacheFromAsyncValueCache(serverCache, logAccessToConsole);
|
|
484
616
|
},
|
|
485
617
|
cacheForRefreshToken: function cacheForRefreshToken(refreshToken) {
|
|
486
618
|
var key = calcomRefreshTokenCacheKey(refreshToken);
|
|
487
|
-
return
|
|
488
|
-
return userTokens.get(key);
|
|
489
|
-
}, function(t) {
|
|
490
|
-
return userTokens.set(key, t);
|
|
491
|
-
});
|
|
619
|
+
return calcomAccessTokenCacheFromAsyncValueCache(userCacheView(key), logAccessToConsole);
|
|
492
620
|
}
|
|
493
621
|
};
|
|
494
622
|
}
|
|
495
623
|
// MARK: File System Access Token Cache
|
|
496
624
|
var DEFAULT_FILE_CALCOM_ACCESS_TOKEN_CACHE_DIR = '.tmp/calcom-tokens';
|
|
497
625
|
var CALCOM_SERVER_TOKEN_FILE_KEY = 'server';
|
|
626
|
+
/**
|
|
627
|
+
* Reviver applied to the cached file payload on load so `expiresAt` is always a `Date`
|
|
628
|
+
* regardless of how it was serialized.
|
|
629
|
+
*
|
|
630
|
+
* @param raw - the raw JSON-parsed file payload
|
|
631
|
+
* @returns the revived CalcomAccessToken, or undefined when the payload is empty/invalid
|
|
632
|
+
*/ function reviveCalcomAccessTokenFile(raw) {
|
|
633
|
+
if (raw == null || (typeof raw === "undefined" ? "undefined" : _type_of(raw)) !== 'object') {
|
|
634
|
+
return undefined;
|
|
635
|
+
}
|
|
636
|
+
var wrapper = raw;
|
|
637
|
+
var token = wrapper.token;
|
|
638
|
+
if (token == null) {
|
|
639
|
+
return undefined;
|
|
640
|
+
}
|
|
641
|
+
var rawExpiresAt = token.expiresAt;
|
|
642
|
+
var expiresAt = rawExpiresAt != null && !_instanceof(rawExpiresAt, Date) ? new Date(rawExpiresAt) : rawExpiresAt;
|
|
643
|
+
return _object_spread_props$2(_object_spread$2({}, token), {
|
|
644
|
+
expiresAt: expiresAt
|
|
645
|
+
});
|
|
646
|
+
}
|
|
498
647
|
/**
|
|
499
648
|
* Creates a CalcomOAuthAccessTokenCacheService that reads and writes access tokens
|
|
500
|
-
* to the file system. Each user gets their own file, keyed by an
|
|
649
|
+
* to the file system. Each user gets their own file, keyed by an sha256 hash of their refresh token.
|
|
650
|
+
*
|
|
651
|
+
* Backed by {@link createMemoizedJsonFileAsyncValueCache} for each key, so reads after
|
|
652
|
+
* the first hit memory.
|
|
501
653
|
*
|
|
502
654
|
* File structure:
|
|
503
655
|
* ```
|
|
504
656
|
* <cacheDir>/
|
|
505
657
|
* server.json — server-level token
|
|
506
|
-
* user-<
|
|
658
|
+
* user-<sha256hash>.json — per-user tokens (hash of initial refresh token)
|
|
507
659
|
* ```
|
|
508
660
|
*
|
|
509
661
|
* @param cacheDir Directory to store token files. Defaults to `.tmp/calcom-tokens`.
|
|
510
662
|
* @returns a CalcomOAuthAccessTokenCacheService backed by the file system
|
|
511
663
|
*/ function fileCalcomOAuthAccessTokenCacheService() {
|
|
512
664
|
var cacheDir = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : DEFAULT_FILE_CALCOM_ACCESS_TOKEN_CACHE_DIR;
|
|
513
|
-
var
|
|
514
|
-
function
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (!err) {
|
|
525
|
-
try {
|
|
526
|
-
result = JSON.parse(data.toString());
|
|
527
|
-
if (result === null || result === void 0 ? void 0 : result.token) {
|
|
528
|
-
result.token.expiresAt = new Date(result.token.expiresAt);
|
|
529
|
-
}
|
|
530
|
-
} catch (e) {
|
|
531
|
-
console.error("Failed reading token file ".concat(filePath, ": "), e);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
resolve(result);
|
|
535
|
-
});
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
function writeTokenFile(filePath, content) {
|
|
539
|
-
return new Promise(function(resolve, reject) {
|
|
540
|
-
node_fs.mkdirSync(node_path.dirname(filePath), {
|
|
541
|
-
recursive: true
|
|
542
|
-
});
|
|
543
|
-
node_fs.writeFile(filePath, JSON.stringify(content, null, 2), {}, function(err) {
|
|
544
|
-
if (!err) {
|
|
545
|
-
resolve();
|
|
546
|
-
} else {
|
|
547
|
-
reject(err);
|
|
665
|
+
var cachesByKey = new Map();
|
|
666
|
+
function cacheForKey(fileKey) {
|
|
667
|
+
var cache = cachesByKey.get(fileKey);
|
|
668
|
+
if (cache == null) {
|
|
669
|
+
cache = nestjs.createMemoizedJsonFileAsyncValueCache({
|
|
670
|
+
filePath: node_path.join(cacheDir, "".concat(fileKey, ".json")),
|
|
671
|
+
reviver: reviveCalcomAccessTokenFile,
|
|
672
|
+
replacer: function replacer(token) {
|
|
673
|
+
return {
|
|
674
|
+
token: token
|
|
675
|
+
};
|
|
548
676
|
}
|
|
549
677
|
});
|
|
550
|
-
|
|
678
|
+
cachesByKey.set(fileKey, cache);
|
|
679
|
+
}
|
|
680
|
+
return cache;
|
|
551
681
|
}
|
|
552
682
|
function makeCacheForKey(fileKey) {
|
|
553
|
-
var
|
|
683
|
+
var cache = cacheForKey(fileKey);
|
|
554
684
|
return {
|
|
555
685
|
loadCachedToken: function loadCachedToken() {
|
|
556
|
-
return
|
|
557
|
-
var memoryEntry, fileContent;
|
|
558
|
-
return _ts_generator$2(this, function(_state) {
|
|
559
|
-
switch(_state.label){
|
|
560
|
-
case 0:
|
|
561
|
-
// Check memory first
|
|
562
|
-
memoryEntry = memoryTokens.get(fileKey);
|
|
563
|
-
if (memoryEntry !== undefined) {
|
|
564
|
-
return [
|
|
565
|
-
2,
|
|
566
|
-
memoryEntry === null || memoryEntry === void 0 ? void 0 : memoryEntry.token
|
|
567
|
-
];
|
|
568
|
-
}
|
|
569
|
-
return [
|
|
570
|
-
4,
|
|
571
|
-
readTokenFile(filePath)
|
|
572
|
-
];
|
|
573
|
-
case 1:
|
|
574
|
-
fileContent = _state.sent();
|
|
575
|
-
memoryTokens.set(fileKey, fileContent !== null && fileContent !== void 0 ? fileContent : null);
|
|
576
|
-
return [
|
|
577
|
-
2,
|
|
578
|
-
fileContent === null || fileContent === void 0 ? void 0 : fileContent.token
|
|
579
|
-
];
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
})();
|
|
686
|
+
return cache.load();
|
|
583
687
|
},
|
|
584
688
|
updateCachedToken: function updateCachedToken(accessToken) {
|
|
585
689
|
return _async_to_generator$2(function() {
|
|
586
|
-
var
|
|
690
|
+
var e;
|
|
587
691
|
return _ts_generator$2(this, function(_state) {
|
|
588
692
|
switch(_state.label){
|
|
589
693
|
case 0:
|
|
590
|
-
content = {
|
|
591
|
-
token: accessToken
|
|
592
|
-
};
|
|
593
|
-
memoryTokens.set(fileKey, content);
|
|
594
|
-
_state.label = 1;
|
|
595
|
-
case 1:
|
|
596
694
|
_state.trys.push([
|
|
597
|
-
|
|
598
|
-
|
|
695
|
+
0,
|
|
696
|
+
2,
|
|
599
697
|
,
|
|
600
|
-
|
|
698
|
+
3
|
|
601
699
|
]);
|
|
602
700
|
return [
|
|
603
701
|
4,
|
|
604
|
-
|
|
702
|
+
cache.update(accessToken)
|
|
605
703
|
];
|
|
606
|
-
case
|
|
704
|
+
case 1:
|
|
607
705
|
_state.sent();
|
|
608
706
|
return [
|
|
609
707
|
3,
|
|
610
|
-
|
|
708
|
+
3
|
|
611
709
|
];
|
|
612
|
-
case
|
|
710
|
+
case 2:
|
|
613
711
|
e = _state.sent();
|
|
614
|
-
console.error("Failed updating token file ".concat(
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
4
|
|
618
|
-
];
|
|
619
|
-
case 4:
|
|
712
|
+
console.error("Failed updating token file for ".concat(fileKey, ": "), e);
|
|
713
|
+
throw e;
|
|
714
|
+
case 3:
|
|
620
715
|
return [
|
|
621
716
|
2
|
|
622
717
|
];
|
package/nestjs/index.esm.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { Injectable, Inject, Logger, Post, Res, Req, Controller, Module } from '@nestjs/common';
|
|
2
2
|
import { calcomOAuthFactory, exchangeAuthorizationCode, calcomFactory, getMe, getSchedules, createBooking, getBooking, cancelBooking, getEventTypes, createEventType, updateEventType, deleteEventType, getCalendars, getBusyTimes, createWebhook, getWebhooks, getWebhook, updateWebhook, deleteWebhook, getAvailableSlots } from '@dereekb/calcom';
|
|
3
|
-
import {
|
|
3
|
+
import { inMemoryAsyncValueCache, inMemoryAsyncKeyedValueCache, mergeAsyncValueCaches, isExpired, filterMaybeArrayValues, cachedGetter, handlerFactory, handlerConfigurerFactory, handlerMappedSetFunctionFactory } from '@dereekb/util';
|
|
4
|
+
import { createMemoizedJsonFileAsyncValueCache, RawBody } from '@dereekb/nestjs';
|
|
4
5
|
import { createHash, createHmac } from 'node:crypto';
|
|
5
|
-
import { join
|
|
6
|
-
import { mkdirSync, writeFile, readFile } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
7
|
import { ConfigService, ConfigModule } from '@nestjs/config';
|
|
8
|
-
import { RawBody } from '@dereekb/nestjs';
|
|
9
8
|
|
|
10
|
-
function _type_of(obj) {
|
|
9
|
+
function _type_of$1(obj) {
|
|
11
10
|
"@swc/helpers - typeof";
|
|
12
11
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
13
12
|
}
|
|
14
13
|
function __decorate(decorators, target, key, desc) {
|
|
15
14
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
-
if ((typeof Reflect === "undefined" ? "undefined" : _type_of(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
15
|
+
if ((typeof Reflect === "undefined" ? "undefined" : _type_of$1(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
16
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
18
17
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
18
|
}
|
|
@@ -45,7 +44,7 @@ function _create_class$6(Constructor, protoProps, staticProps) {
|
|
|
45
44
|
if (staticProps) _defineProperties$6(Constructor, staticProps);
|
|
46
45
|
return Constructor;
|
|
47
46
|
}
|
|
48
|
-
function _define_property$
|
|
47
|
+
function _define_property$8(obj, key, value) {
|
|
49
48
|
if (key in obj) {
|
|
50
49
|
Object.defineProperty(obj, key, {
|
|
51
50
|
value: value,
|
|
@@ -68,8 +67,8 @@ var CALCOM_API_KEY_CONFIG_KEY = 'CALCOM_API_KEY';
|
|
|
68
67
|
*/ var CalcomOAuthServiceConfig = /*#__PURE__*/ function() {
|
|
69
68
|
function CalcomOAuthServiceConfig() {
|
|
70
69
|
_class_call_check$8(this, CalcomOAuthServiceConfig);
|
|
71
|
-
_define_property$
|
|
72
|
-
_define_property$
|
|
70
|
+
_define_property$8(this, "calcomOAuth", void 0);
|
|
71
|
+
_define_property$8(this, "factoryConfig", void 0);
|
|
73
72
|
}
|
|
74
73
|
_create_class$6(CalcomOAuthServiceConfig, null, [
|
|
75
74
|
{
|
|
@@ -156,6 +155,27 @@ function _class_call_check$7(instance, Constructor) {
|
|
|
156
155
|
throw new TypeError("Cannot call a class as a function");
|
|
157
156
|
}
|
|
158
157
|
}
|
|
158
|
+
function _define_property$7(obj, key, value) {
|
|
159
|
+
if (key in obj) {
|
|
160
|
+
Object.defineProperty(obj, key, {
|
|
161
|
+
value: value,
|
|
162
|
+
enumerable: true,
|
|
163
|
+
configurable: true,
|
|
164
|
+
writable: true
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
obj[key] = value;
|
|
168
|
+
}
|
|
169
|
+
return obj;
|
|
170
|
+
}
|
|
171
|
+
function _instanceof(left, right) {
|
|
172
|
+
"@swc/helpers - instanceof";
|
|
173
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
174
|
+
return !!right[Symbol.hasInstance](left);
|
|
175
|
+
} else {
|
|
176
|
+
return left instanceof right;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
159
179
|
function _iterable_to_array$3(iter) {
|
|
160
180
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
161
181
|
}
|
|
@@ -189,12 +209,50 @@ function _non_iterable_rest() {
|
|
|
189
209
|
function _non_iterable_spread$3() {
|
|
190
210
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
191
211
|
}
|
|
212
|
+
function _object_spread$2(target) {
|
|
213
|
+
for(var i = 1; i < arguments.length; i++){
|
|
214
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
215
|
+
var ownKeys = Object.keys(source);
|
|
216
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
217
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
218
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
ownKeys.forEach(function(key) {
|
|
222
|
+
_define_property$7(target, key, source[key]);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return target;
|
|
226
|
+
}
|
|
227
|
+
function ownKeys$2(object, enumerableOnly) {
|
|
228
|
+
var keys = Object.keys(object);
|
|
229
|
+
if (Object.getOwnPropertySymbols) {
|
|
230
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
231
|
+
keys.push.apply(keys, symbols);
|
|
232
|
+
}
|
|
233
|
+
return keys;
|
|
234
|
+
}
|
|
235
|
+
function _object_spread_props$2(target, source) {
|
|
236
|
+
source = source != null ? source : {};
|
|
237
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
238
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
239
|
+
} else {
|
|
240
|
+
ownKeys$2(Object(source)).forEach(function(key) {
|
|
241
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return target;
|
|
245
|
+
}
|
|
192
246
|
function _sliced_to_array(arr, i) {
|
|
193
247
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest();
|
|
194
248
|
}
|
|
195
249
|
function _to_consumable_array$3(arr) {
|
|
196
250
|
return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
|
|
197
251
|
}
|
|
252
|
+
function _type_of(obj) {
|
|
253
|
+
"@swc/helpers - typeof";
|
|
254
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
255
|
+
}
|
|
198
256
|
function _unsupported_iterable_to_array$3(o, minLen) {
|
|
199
257
|
if (!o) return;
|
|
200
258
|
if (typeof o === "string") return _array_like_to_array$3(o, minLen);
|
|
@@ -324,6 +382,56 @@ CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
324
382
|
*/ function calcomRefreshTokenCacheKey(refreshToken) {
|
|
325
383
|
return createHash('sha256').update(refreshToken).digest('hex').substring(0, 16);
|
|
326
384
|
}
|
|
385
|
+
// MARK: Merge
|
|
386
|
+
function buildCalcomReadAdapter(cache) {
|
|
387
|
+
return {
|
|
388
|
+
load: function load() {
|
|
389
|
+
return _async_to_generator$2(function() {
|
|
390
|
+
var value;
|
|
391
|
+
return _ts_generator$2(this, function(_state) {
|
|
392
|
+
switch(_state.label){
|
|
393
|
+
case 0:
|
|
394
|
+
return [
|
|
395
|
+
4,
|
|
396
|
+
cache.loadCachedToken().catch(function() {
|
|
397
|
+
return undefined;
|
|
398
|
+
})
|
|
399
|
+
];
|
|
400
|
+
case 1:
|
|
401
|
+
value = _state.sent();
|
|
402
|
+
return [
|
|
403
|
+
2,
|
|
404
|
+
value != null && !isExpired(value) ? value : undefined
|
|
405
|
+
];
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
})();
|
|
409
|
+
},
|
|
410
|
+
update: function update(token) {
|
|
411
|
+
return cache.updateCachedToken(token);
|
|
412
|
+
},
|
|
413
|
+
clear: function clear() {
|
|
414
|
+
return _async_to_generator$2(function() {
|
|
415
|
+
return _ts_generator$2(this, function(_state) {
|
|
416
|
+
return [
|
|
417
|
+
2
|
|
418
|
+
];
|
|
419
|
+
});
|
|
420
|
+
// CalcomAccessTokenCache does not expose a clear method.
|
|
421
|
+
})();
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function updateCalcomCacheCapturingError(cache, accessToken) {
|
|
426
|
+
return cache.updateCachedToken(accessToken).then(function() {
|
|
427
|
+
return null;
|
|
428
|
+
}).catch(function(e) {
|
|
429
|
+
return [
|
|
430
|
+
cache,
|
|
431
|
+
e
|
|
432
|
+
];
|
|
433
|
+
});
|
|
434
|
+
}
|
|
327
435
|
/**
|
|
328
436
|
* Default error logging function for {@link mergeCalcomOAuthAccessTokenCacheServices}.
|
|
329
437
|
* Logs a warning for each cache that failed to update.
|
|
@@ -342,6 +450,11 @@ CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
342
450
|
* If one source fails retrieval, the next will be tried.
|
|
343
451
|
* When updating a cached token, it will update the token across all services.
|
|
344
452
|
*
|
|
453
|
+
* Read fall-through is delegated to {@link mergeAsyncValueCaches} after wrapping each
|
|
454
|
+
* underlying cache with an {@link isExpired}-aware filter, so an expired cached token
|
|
455
|
+
* never short-circuits the lookup. Updates run across all services in parallel via
|
|
456
|
+
* `Promise.allSettled`, mirroring the previous behavior, with optional error logging.
|
|
457
|
+
*
|
|
345
458
|
* @param inputServicesToMerge Must include at least one service. Empty arrays will throw an error.
|
|
346
459
|
* @param logError - optional error logging configuration; pass a function, true for default logging, or false to disable
|
|
347
460
|
* @returns a merged CalcomOAuthAccessTokenCacheService that delegates across all input services
|
|
@@ -351,60 +464,44 @@ CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
351
464
|
if (allServices.length === 0) {
|
|
352
465
|
throw new Error('mergeCalcomOAuthAccessTokenCacheServices() input cannot be empty.');
|
|
353
466
|
}
|
|
354
|
-
|
|
355
|
-
var
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return x.loadCachedToken().catch(function() {
|
|
359
|
-
return null;
|
|
360
|
-
}).then(function(x) {
|
|
361
|
-
var result = undefined;
|
|
362
|
-
if (x && !isPast(x.expiresAt)) {
|
|
363
|
-
result = x; // only return from cache if it is not expired
|
|
364
|
-
}
|
|
365
|
-
return result;
|
|
366
|
-
});
|
|
367
|
-
};
|
|
368
|
-
}),
|
|
369
|
-
successOnMaybe: false,
|
|
370
|
-
throwErrors: false
|
|
371
|
-
});
|
|
372
|
-
var cacheForService = {
|
|
467
|
+
function mergeCachesForService(accessCachesForServices) {
|
|
468
|
+
var readAdapters = accessCachesForServices.map(buildCalcomReadAdapter);
|
|
469
|
+
var merged = mergeAsyncValueCaches(readAdapters);
|
|
470
|
+
return {
|
|
373
471
|
loadCachedToken: function loadCachedToken() {
|
|
374
|
-
return
|
|
472
|
+
return merged.load();
|
|
375
473
|
},
|
|
376
474
|
updateCachedToken: function updateCachedToken(accessToken) {
|
|
377
475
|
return _async_to_generator$2(function() {
|
|
476
|
+
var settled, failedUpdates;
|
|
378
477
|
return _ts_generator$2(this, function(_state) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
});
|
|
390
|
-
})).then(function(x) {
|
|
391
|
-
// only find the failures if we're logging
|
|
478
|
+
switch(_state.label){
|
|
479
|
+
case 0:
|
|
480
|
+
return [
|
|
481
|
+
4,
|
|
482
|
+
Promise.allSettled(accessCachesForServices.map(function(cache) {
|
|
483
|
+
return updateCalcomCacheCapturingError(cache, accessToken);
|
|
484
|
+
}))
|
|
485
|
+
];
|
|
486
|
+
case 1:
|
|
487
|
+
settled = _state.sent();
|
|
392
488
|
if (logErrorFunction != null) {
|
|
393
|
-
|
|
489
|
+
failedUpdates = filterMaybeArrayValues(settled.map(function(y) {
|
|
394
490
|
return y.value;
|
|
395
491
|
}));
|
|
396
492
|
if (failedUpdates.length) {
|
|
397
493
|
logErrorFunction(failedUpdates);
|
|
398
494
|
}
|
|
399
495
|
}
|
|
400
|
-
|
|
401
|
-
|
|
496
|
+
return [
|
|
497
|
+
2
|
|
498
|
+
];
|
|
499
|
+
}
|
|
402
500
|
});
|
|
403
501
|
})();
|
|
404
502
|
}
|
|
405
503
|
};
|
|
406
|
-
|
|
407
|
-
};
|
|
504
|
+
}
|
|
408
505
|
var allServiceAccessTokenCaches = allServices.map(function(x) {
|
|
409
506
|
return x.loadCalcomAccessTokenCache();
|
|
410
507
|
});
|
|
@@ -415,206 +512,204 @@ CalcomOAuthAccessTokenCacheService = __decorate([
|
|
|
415
512
|
var allCaches = allServicesWithCacheForRefreshToken.map(function(x) {
|
|
416
513
|
return x.cacheForRefreshToken(refreshToken);
|
|
417
514
|
});
|
|
418
|
-
return
|
|
515
|
+
return mergeCachesForService(allCaches);
|
|
419
516
|
} : undefined;
|
|
420
517
|
var service = {
|
|
421
|
-
loadCalcomAccessTokenCache: function
|
|
422
|
-
return
|
|
518
|
+
loadCalcomAccessTokenCache: function loadCalcomAccessTokenCache() {
|
|
519
|
+
return mergeCachesForService(allServiceAccessTokenCaches);
|
|
423
520
|
},
|
|
424
521
|
cacheForRefreshToken: cacheForRefreshToken
|
|
425
522
|
};
|
|
426
523
|
return service;
|
|
427
524
|
}
|
|
428
525
|
// MARK: Memory Access Token Cache
|
|
526
|
+
/**
|
|
527
|
+
* Adapts an {@link AsyncValueCache} to a {@link CalcomAccessTokenCache}, optionally logging cache reads/writes to the console.
|
|
528
|
+
*
|
|
529
|
+
* @param cache - underlying single-value cache for the access token
|
|
530
|
+
* @param logAccessToConsole - when true, logs reads and writes to the console
|
|
531
|
+
* @returns the CalcomAccessTokenCache backed by the given async cache
|
|
532
|
+
*/ function calcomAccessTokenCacheFromAsyncValueCache(cache, logAccessToConsole) {
|
|
533
|
+
return {
|
|
534
|
+
loadCachedToken: function loadCachedToken() {
|
|
535
|
+
return _async_to_generator$2(function() {
|
|
536
|
+
var token;
|
|
537
|
+
return _ts_generator$2(this, function(_state) {
|
|
538
|
+
switch(_state.label){
|
|
539
|
+
case 0:
|
|
540
|
+
return [
|
|
541
|
+
4,
|
|
542
|
+
cache.load()
|
|
543
|
+
];
|
|
544
|
+
case 1:
|
|
545
|
+
token = _state.sent();
|
|
546
|
+
if (logAccessToConsole) {
|
|
547
|
+
console.log('retrieving access token from memory: ', {
|
|
548
|
+
hit: token != null,
|
|
549
|
+
expiresAt: token === null || token === void 0 ? void 0 : token.expiresAt
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return [
|
|
553
|
+
2,
|
|
554
|
+
token
|
|
555
|
+
];
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
})();
|
|
559
|
+
},
|
|
560
|
+
updateCachedToken: function updateCachedToken(accessToken) {
|
|
561
|
+
return _async_to_generator$2(function() {
|
|
562
|
+
return _ts_generator$2(this, function(_state) {
|
|
563
|
+
switch(_state.label){
|
|
564
|
+
case 0:
|
|
565
|
+
return [
|
|
566
|
+
4,
|
|
567
|
+
cache.update(accessToken)
|
|
568
|
+
];
|
|
569
|
+
case 1:
|
|
570
|
+
_state.sent();
|
|
571
|
+
if (logAccessToConsole) {
|
|
572
|
+
console.log('updating access token in memory: ', {
|
|
573
|
+
expiresAt: accessToken === null || accessToken === void 0 ? void 0 : accessToken.expiresAt
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
return [
|
|
577
|
+
2
|
|
578
|
+
];
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
})();
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
}
|
|
429
585
|
/**
|
|
430
586
|
* Creates a CalcomOAuthAccessTokenCacheService that uses in-memory storage.
|
|
431
|
-
*
|
|
587
|
+
*
|
|
588
|
+
* The server-level token is held in a single-slot {@link inMemoryAsyncValueCache};
|
|
589
|
+
* per-user tokens are held in an {@link inMemoryAsyncKeyedValueCache} keyed by the
|
|
590
|
+
* sha256-truncated refresh token hash.
|
|
432
591
|
*
|
|
433
592
|
* @param existingToken - optional pre-existing server-level access token to seed the cache
|
|
434
593
|
* @param logAccessToConsole - when true, logs all cache reads and writes to console
|
|
435
|
-
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory
|
|
594
|
+
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory caches
|
|
436
595
|
*/ function memoryCalcomOAuthAccessTokenCacheService(existingToken, logAccessToConsole) {
|
|
437
|
-
var
|
|
438
|
-
var
|
|
439
|
-
function
|
|
596
|
+
var serverCache = inMemoryAsyncValueCache(existingToken);
|
|
597
|
+
var userCache = inMemoryAsyncKeyedValueCache();
|
|
598
|
+
function userCacheView(key) {
|
|
440
599
|
return {
|
|
441
|
-
|
|
442
|
-
return
|
|
443
|
-
var token;
|
|
444
|
-
return _ts_generator$2(this, function(_state) {
|
|
445
|
-
token = getToken();
|
|
446
|
-
if (logAccessToConsole) {
|
|
447
|
-
console.log('retrieving access token from memory: ', {
|
|
448
|
-
token: token
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
return [
|
|
452
|
-
2,
|
|
453
|
-
token
|
|
454
|
-
];
|
|
455
|
-
});
|
|
456
|
-
})();
|
|
600
|
+
load: function load() {
|
|
601
|
+
return userCache.get(key);
|
|
457
602
|
},
|
|
458
|
-
|
|
459
|
-
return
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
console.log('updating access token in memory: ', {
|
|
464
|
-
accessToken: accessToken
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
return [
|
|
468
|
-
2
|
|
469
|
-
];
|
|
470
|
-
});
|
|
471
|
-
})();
|
|
603
|
+
update: function update(token) {
|
|
604
|
+
return userCache.set(key, token);
|
|
605
|
+
},
|
|
606
|
+
clear: function clear() {
|
|
607
|
+
return userCache.remove(key);
|
|
472
608
|
}
|
|
473
609
|
};
|
|
474
610
|
}
|
|
475
611
|
return {
|
|
476
612
|
loadCalcomAccessTokenCache: function loadCalcomAccessTokenCache() {
|
|
477
|
-
return
|
|
478
|
-
return serverToken;
|
|
479
|
-
}, function(t) {
|
|
480
|
-
serverToken = t;
|
|
481
|
-
});
|
|
613
|
+
return calcomAccessTokenCacheFromAsyncValueCache(serverCache, logAccessToConsole);
|
|
482
614
|
},
|
|
483
615
|
cacheForRefreshToken: function cacheForRefreshToken(refreshToken) {
|
|
484
616
|
var key = calcomRefreshTokenCacheKey(refreshToken);
|
|
485
|
-
return
|
|
486
|
-
return userTokens.get(key);
|
|
487
|
-
}, function(t) {
|
|
488
|
-
return userTokens.set(key, t);
|
|
489
|
-
});
|
|
617
|
+
return calcomAccessTokenCacheFromAsyncValueCache(userCacheView(key), logAccessToConsole);
|
|
490
618
|
}
|
|
491
619
|
};
|
|
492
620
|
}
|
|
493
621
|
// MARK: File System Access Token Cache
|
|
494
622
|
var DEFAULT_FILE_CALCOM_ACCESS_TOKEN_CACHE_DIR = '.tmp/calcom-tokens';
|
|
495
623
|
var CALCOM_SERVER_TOKEN_FILE_KEY = 'server';
|
|
624
|
+
/**
|
|
625
|
+
* Reviver applied to the cached file payload on load so `expiresAt` is always a `Date`
|
|
626
|
+
* regardless of how it was serialized.
|
|
627
|
+
*
|
|
628
|
+
* @param raw - the raw JSON-parsed file payload
|
|
629
|
+
* @returns the revived CalcomAccessToken, or undefined when the payload is empty/invalid
|
|
630
|
+
*/ function reviveCalcomAccessTokenFile(raw) {
|
|
631
|
+
if (raw == null || (typeof raw === "undefined" ? "undefined" : _type_of(raw)) !== 'object') {
|
|
632
|
+
return undefined;
|
|
633
|
+
}
|
|
634
|
+
var wrapper = raw;
|
|
635
|
+
var token = wrapper.token;
|
|
636
|
+
if (token == null) {
|
|
637
|
+
return undefined;
|
|
638
|
+
}
|
|
639
|
+
var rawExpiresAt = token.expiresAt;
|
|
640
|
+
var expiresAt = rawExpiresAt != null && !_instanceof(rawExpiresAt, Date) ? new Date(rawExpiresAt) : rawExpiresAt;
|
|
641
|
+
return _object_spread_props$2(_object_spread$2({}, token), {
|
|
642
|
+
expiresAt: expiresAt
|
|
643
|
+
});
|
|
644
|
+
}
|
|
496
645
|
/**
|
|
497
646
|
* Creates a CalcomOAuthAccessTokenCacheService that reads and writes access tokens
|
|
498
|
-
* to the file system. Each user gets their own file, keyed by an
|
|
647
|
+
* to the file system. Each user gets their own file, keyed by an sha256 hash of their refresh token.
|
|
648
|
+
*
|
|
649
|
+
* Backed by {@link createMemoizedJsonFileAsyncValueCache} for each key, so reads after
|
|
650
|
+
* the first hit memory.
|
|
499
651
|
*
|
|
500
652
|
* File structure:
|
|
501
653
|
* ```
|
|
502
654
|
* <cacheDir>/
|
|
503
655
|
* server.json — server-level token
|
|
504
|
-
* user-<
|
|
656
|
+
* user-<sha256hash>.json — per-user tokens (hash of initial refresh token)
|
|
505
657
|
* ```
|
|
506
658
|
*
|
|
507
659
|
* @param cacheDir Directory to store token files. Defaults to `.tmp/calcom-tokens`.
|
|
508
660
|
* @returns a CalcomOAuthAccessTokenCacheService backed by the file system
|
|
509
661
|
*/ function fileCalcomOAuthAccessTokenCacheService() {
|
|
510
662
|
var cacheDir = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : DEFAULT_FILE_CALCOM_ACCESS_TOKEN_CACHE_DIR;
|
|
511
|
-
var
|
|
512
|
-
function
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
if (!err) {
|
|
523
|
-
try {
|
|
524
|
-
result = JSON.parse(data.toString());
|
|
525
|
-
if (result === null || result === void 0 ? void 0 : result.token) {
|
|
526
|
-
result.token.expiresAt = new Date(result.token.expiresAt);
|
|
527
|
-
}
|
|
528
|
-
} catch (e) {
|
|
529
|
-
console.error("Failed reading token file ".concat(filePath, ": "), e);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
resolve(result);
|
|
533
|
-
});
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
function writeTokenFile(filePath, content) {
|
|
537
|
-
return new Promise(function(resolve, reject) {
|
|
538
|
-
mkdirSync(dirname(filePath), {
|
|
539
|
-
recursive: true
|
|
540
|
-
});
|
|
541
|
-
writeFile(filePath, JSON.stringify(content, null, 2), {}, function(err) {
|
|
542
|
-
if (!err) {
|
|
543
|
-
resolve();
|
|
544
|
-
} else {
|
|
545
|
-
reject(err);
|
|
663
|
+
var cachesByKey = new Map();
|
|
664
|
+
function cacheForKey(fileKey) {
|
|
665
|
+
var cache = cachesByKey.get(fileKey);
|
|
666
|
+
if (cache == null) {
|
|
667
|
+
cache = createMemoizedJsonFileAsyncValueCache({
|
|
668
|
+
filePath: join(cacheDir, "".concat(fileKey, ".json")),
|
|
669
|
+
reviver: reviveCalcomAccessTokenFile,
|
|
670
|
+
replacer: function replacer(token) {
|
|
671
|
+
return {
|
|
672
|
+
token: token
|
|
673
|
+
};
|
|
546
674
|
}
|
|
547
675
|
});
|
|
548
|
-
|
|
676
|
+
cachesByKey.set(fileKey, cache);
|
|
677
|
+
}
|
|
678
|
+
return cache;
|
|
549
679
|
}
|
|
550
680
|
function makeCacheForKey(fileKey) {
|
|
551
|
-
var
|
|
681
|
+
var cache = cacheForKey(fileKey);
|
|
552
682
|
return {
|
|
553
683
|
loadCachedToken: function loadCachedToken() {
|
|
554
|
-
return
|
|
555
|
-
var memoryEntry, fileContent;
|
|
556
|
-
return _ts_generator$2(this, function(_state) {
|
|
557
|
-
switch(_state.label){
|
|
558
|
-
case 0:
|
|
559
|
-
// Check memory first
|
|
560
|
-
memoryEntry = memoryTokens.get(fileKey);
|
|
561
|
-
if (memoryEntry !== undefined) {
|
|
562
|
-
return [
|
|
563
|
-
2,
|
|
564
|
-
memoryEntry === null || memoryEntry === void 0 ? void 0 : memoryEntry.token
|
|
565
|
-
];
|
|
566
|
-
}
|
|
567
|
-
return [
|
|
568
|
-
4,
|
|
569
|
-
readTokenFile(filePath)
|
|
570
|
-
];
|
|
571
|
-
case 1:
|
|
572
|
-
fileContent = _state.sent();
|
|
573
|
-
memoryTokens.set(fileKey, fileContent !== null && fileContent !== void 0 ? fileContent : null);
|
|
574
|
-
return [
|
|
575
|
-
2,
|
|
576
|
-
fileContent === null || fileContent === void 0 ? void 0 : fileContent.token
|
|
577
|
-
];
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
})();
|
|
684
|
+
return cache.load();
|
|
581
685
|
},
|
|
582
686
|
updateCachedToken: function updateCachedToken(accessToken) {
|
|
583
687
|
return _async_to_generator$2(function() {
|
|
584
|
-
var
|
|
688
|
+
var e;
|
|
585
689
|
return _ts_generator$2(this, function(_state) {
|
|
586
690
|
switch(_state.label){
|
|
587
691
|
case 0:
|
|
588
|
-
content = {
|
|
589
|
-
token: accessToken
|
|
590
|
-
};
|
|
591
|
-
memoryTokens.set(fileKey, content);
|
|
592
|
-
_state.label = 1;
|
|
593
|
-
case 1:
|
|
594
692
|
_state.trys.push([
|
|
595
|
-
|
|
596
|
-
|
|
693
|
+
0,
|
|
694
|
+
2,
|
|
597
695
|
,
|
|
598
|
-
|
|
696
|
+
3
|
|
599
697
|
]);
|
|
600
698
|
return [
|
|
601
699
|
4,
|
|
602
|
-
|
|
700
|
+
cache.update(accessToken)
|
|
603
701
|
];
|
|
604
|
-
case
|
|
702
|
+
case 1:
|
|
605
703
|
_state.sent();
|
|
606
704
|
return [
|
|
607
705
|
3,
|
|
608
|
-
|
|
706
|
+
3
|
|
609
707
|
];
|
|
610
|
-
case
|
|
708
|
+
case 2:
|
|
611
709
|
e = _state.sent();
|
|
612
|
-
console.error("Failed updating token file ".concat(
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
4
|
|
616
|
-
];
|
|
617
|
-
case 4:
|
|
710
|
+
console.error("Failed updating token file for ".concat(fileKey, ": "), e);
|
|
711
|
+
throw e;
|
|
712
|
+
case 3:
|
|
618
713
|
return [
|
|
619
714
|
2
|
|
620
715
|
];
|
package/nestjs/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/calcom/nestjs",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.11.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/nestjs": "13.
|
|
6
|
-
"@dereekb/rxjs": "13.
|
|
7
|
-
"@dereekb/util": "13.
|
|
8
|
-
"@dereekb/calcom": "13.
|
|
5
|
+
"@dereekb/nestjs": "13.11.0",
|
|
6
|
+
"@dereekb/rxjs": "13.11.0",
|
|
7
|
+
"@dereekb/util": "13.11.0",
|
|
8
|
+
"@dereekb/calcom": "13.11.0",
|
|
9
9
|
"@nestjs/common": "^11.1.19",
|
|
10
10
|
"@nestjs/config": "^4.0.4",
|
|
11
11
|
"express": "^5.2.1"
|
|
@@ -45,6 +45,11 @@ export declare function logMergeCalcomOAuthAccessTokenCacheServiceErrorFunction(
|
|
|
45
45
|
* If one source fails retrieval, the next will be tried.
|
|
46
46
|
* When updating a cached token, it will update the token across all services.
|
|
47
47
|
*
|
|
48
|
+
* Read fall-through is delegated to {@link mergeAsyncValueCaches} after wrapping each
|
|
49
|
+
* underlying cache with an {@link isExpired}-aware filter, so an expired cached token
|
|
50
|
+
* never short-circuits the lookup. Updates run across all services in parallel via
|
|
51
|
+
* `Promise.allSettled`, mirroring the previous behavior, with optional error logging.
|
|
52
|
+
*
|
|
48
53
|
* @param inputServicesToMerge Must include at least one service. Empty arrays will throw an error.
|
|
49
54
|
* @param logError - optional error logging configuration; pass a function, true for default logging, or false to disable
|
|
50
55
|
* @returns a merged CalcomOAuthAccessTokenCacheService that delegates across all input services
|
|
@@ -52,11 +57,14 @@ export declare function logMergeCalcomOAuthAccessTokenCacheServiceErrorFunction(
|
|
|
52
57
|
export declare function mergeCalcomOAuthAccessTokenCacheServices(inputServicesToMerge: CalcomOAuthAccessTokenCacheService[], logError?: Maybe<boolean | LogMergeCalcomOAuthAccessTokenCacheServiceErrorFunction>): CalcomOAuthAccessTokenCacheService;
|
|
53
58
|
/**
|
|
54
59
|
* Creates a CalcomOAuthAccessTokenCacheService that uses in-memory storage.
|
|
55
|
-
*
|
|
60
|
+
*
|
|
61
|
+
* The server-level token is held in a single-slot {@link inMemoryAsyncValueCache};
|
|
62
|
+
* per-user tokens are held in an {@link inMemoryAsyncKeyedValueCache} keyed by the
|
|
63
|
+
* sha256-truncated refresh token hash.
|
|
56
64
|
*
|
|
57
65
|
* @param existingToken - optional pre-existing server-level access token to seed the cache
|
|
58
66
|
* @param logAccessToConsole - when true, logs all cache reads and writes to console
|
|
59
|
-
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory
|
|
67
|
+
* @returns a CalcomOAuthAccessTokenCacheService backed by in-memory caches
|
|
60
68
|
*/
|
|
61
69
|
export declare function memoryCalcomOAuthAccessTokenCacheService(existingToken?: Maybe<CalcomAccessToken>, logAccessToConsole?: boolean): CalcomOAuthAccessTokenCacheService;
|
|
62
70
|
export declare const DEFAULT_FILE_CALCOM_ACCESS_TOKEN_CACHE_DIR = ".tmp/calcom-tokens";
|
|
@@ -69,13 +77,16 @@ export interface FileSystemCalcomOAuthAccessTokenCacheService extends CalcomOAut
|
|
|
69
77
|
}
|
|
70
78
|
/**
|
|
71
79
|
* Creates a CalcomOAuthAccessTokenCacheService that reads and writes access tokens
|
|
72
|
-
* to the file system. Each user gets their own file, keyed by an
|
|
80
|
+
* to the file system. Each user gets their own file, keyed by an sha256 hash of their refresh token.
|
|
81
|
+
*
|
|
82
|
+
* Backed by {@link createMemoizedJsonFileAsyncValueCache} for each key, so reads after
|
|
83
|
+
* the first hit memory.
|
|
73
84
|
*
|
|
74
85
|
* File structure:
|
|
75
86
|
* ```
|
|
76
87
|
* <cacheDir>/
|
|
77
88
|
* server.json — server-level token
|
|
78
|
-
* user-<
|
|
89
|
+
* user-<sha256hash>.json — per-user tokens (hash of initial refresh token)
|
|
79
90
|
* ```
|
|
80
91
|
*
|
|
81
92
|
* @param cacheDir Directory to store token files. Defaults to `.tmp/calcom-tokens`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/calcom",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.11.0",
|
|
4
4
|
"exports": {
|
|
5
5
|
"./nestjs": {
|
|
6
6
|
"module": "./nestjs/index.esm.js",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@dereekb/nestjs": "13.
|
|
21
|
-
"@dereekb/rxjs": "13.
|
|
22
|
-
"@dereekb/util": "13.
|
|
20
|
+
"@dereekb/nestjs": "13.11.0",
|
|
21
|
+
"@dereekb/rxjs": "13.11.0",
|
|
22
|
+
"@dereekb/util": "13.11.0",
|
|
23
23
|
"@nestjs/common": "^11.1.19",
|
|
24
24
|
"@nestjs/config": "^4.0.4",
|
|
25
25
|
"express": "^5.2.1",
|