@universis/janitor 2.2.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11,10 +11,17 @@ var rateLimitRedis = require('rate-limit-redis');
11
11
  var ioredis = require('ioredis');
12
12
  require('@themost/promise-sequence');
13
13
  var url = require('url');
14
+ var janitor = require('@universis/janitor');
15
+ require('@themost/express');
14
16
  var superagent = require('superagent');
15
17
  var jwt = require('jsonwebtoken');
16
18
  var BearerStrategy = require('passport-http-bearer');
17
19
  var passport = require('passport');
20
+ var cloneDeep = require('lodash/cloneDeep');
21
+ var MD5 = require('crypto-js/md5');
22
+ var data = require('@themost/data');
23
+ var ipRangeCheck = require('ip-range-check');
24
+ var operators = require('rxjs/operators');
18
25
 
19
26
  class RateLimitService extends common.ApplicationService {
20
27
  /**
@@ -804,22 +811,125 @@ class ExtendScopeAccessConfiguration extends common.ApplicationService {
804
811
  }
805
812
  }
806
813
 
807
- function validateScope() {
808
- return (req, res, next) => {
814
+ class InvalidClientScopeError extends common.HttpForbiddenError {
815
+ constructor() {
816
+ super('Access denied due to invalid client scopes.');
817
+ }
818
+ }
819
+
820
+ class VerifyUserClientScope extends common.ApplicationService {
821
+
822
+ constructor(app) {
823
+ super(app);
824
+ // Sets the pre-defined OpenID Connect client scopes that are whitelisted and should be omitted during validation
825
+ this.options = {
826
+ whitelist: [
827
+ 'profile',
828
+ 'email',
829
+ 'openid']
830
+
831
+ };
832
+ }
833
+
834
+ /**
835
+ * Verify user scope access against its assigned groups,
836
+ * following the client scopes that are available for the user groups.
837
+ * @param {ExpressDataContext} context
838
+ * @param {boolean=} throwError
839
+ * @returns {Promise<boolean>}
840
+ */
841
+ async verify(context, throwError) {
842
+ // noinspection JSUnresolvedReference
843
+ const user = await context.getUser();
844
+ if (user == null) {
845
+ return false;
846
+ }
847
+ const groups = user.groups.map((group) => group.id);
848
+ /**
849
+ * @type {import('@themost/data').DataModel}
850
+ */
851
+ const ClientScopes = context.model('Group').convert({}).property('scopes').getBaseModel();
852
+ // set conditional caching
853
+ ClientScopes.caching = 'conditional';
854
+ /**
855
+ * get client scopes assigned to user groups
856
+ * @type {Array<{ scope: string }>}
857
+ */
858
+ const items = await ClientScopes.where('group').equal(groups).select('scope').cache(true).take(-1).silent().getItems();
809
859
  /**
810
- * @type {ScopeAccessConfiguration}
860
+ * @type {string[]}
811
861
  */
812
- let scopeAccessConfiguration = req.context.getApplication().getConfiguration().getStrategy(ScopeAccessConfiguration);
813
- if (typeof scopeAccessConfiguration === 'undefined') {
814
- return next(new Error('Invalid application configuration. Scope access configuration strategy is missing or is in accessible.'));
862
+ const assignedScopes = items.map((item) => item.scope);
863
+ const contextScopes = new janitor.ScopeString(context.user.authenticationScope).split().filter((scope) => {
864
+ return this.options.whitelist.includes(scope) === false;
865
+ });
866
+
867
+ const unassigned = contextScopes.filter((scope) => {
868
+ return !assignedScopes.includes(scope);
869
+ });
870
+ if (unassigned.length) {
871
+ if (!!throwError) {
872
+ common.TraceUtils.error(`Access denied for user "${context.user.name}" due to invalid client scope(s) "${unassigned.join(',')}"`);
873
+ throw new InvalidClientScopeError();
874
+ }
875
+ return false;
815
876
  }
816
- scopeAccessConfiguration.verify(req).then((value) => {
817
- if (value) {
877
+ return true;
878
+ }
879
+ }
880
+
881
+ class DisableUserClientScopeVerification extends VerifyUserClientScope {
882
+ constructor(app) {
883
+ super(app);
884
+ }
885
+ async verify(context, throwError) {
886
+ return true;
887
+ }
888
+ }
889
+
890
+ function validateClientScope() {
891
+ return function (req, res, next) {
892
+ try {
893
+ /**
894
+ * @type {VerifyUserClientScope}
895
+ */
896
+ const service = req.context.getApplication().getService(VerifyUserClientScope);
897
+ if (service == null) {
898
+ return next();
899
+ }
900
+ void service.verify(req).then(() => {
818
901
  return next();
902
+ }).catch((reason) => {
903
+ return next(reason);
904
+ });
905
+ } catch (err) {
906
+ return next(err);
907
+ }
908
+ };
909
+ }
910
+
911
+ function validateScope() {
912
+ return (req, res, next) => {
913
+ const validateClientScopeHandler = validateClientScope();
914
+ return validateClientScopeHandler(req, res, (err) => {
915
+ if (err) {
916
+ return next(err);
917
+ }
918
+ /**
919
+ * @type {ScopeAccessConfiguration}
920
+ */
921
+ let scopeAccessConfiguration = req.context.getApplication().getConfiguration().getStrategy(ScopeAccessConfiguration);
922
+ if (typeof scopeAccessConfiguration === 'undefined') {
923
+ return next(new Error('Invalid application configuration. Scope access configuration strategy is missing or is in accessible.'));
819
924
  }
820
- return next(new common.HttpForbiddenError('Access denied due to authorization scopes.'));
821
- }).catch((reason) => {
822
- return next(reason);
925
+ scopeAccessConfiguration.verify(req).then((value) => {
926
+ if (value) {
927
+ return next();
928
+ }
929
+ return next(new common.HttpForbiddenError('Access denied due to authorization scopes.'));
930
+ }).catch((reason) => {
931
+ return next(reason);
932
+ });
823
933
  });
824
934
  };
825
935
  }
@@ -1337,9 +1447,496 @@ class PassportService extends common.ApplicationService {
1337
1447
 
1338
1448
  }
1339
1449
 
1450
+ /**
1451
+ *
1452
+ * @param {{profiles:Map<string, import('./outputCacheRouter').OutputCachingProfile>,elements: import('./outputCacheRouter').OutputCachingElement[]}} options
1453
+ * @returns {import('express').Router}
1454
+ */
1455
+ function outputCache({ profiles, elements }) {
1456
+ const router = new express.Router();
1457
+ // prepare regular expressions
1458
+ const outputCacheElements = Array.isArray(elements) ? elements : [];
1459
+ outputCacheElements.forEach((element) => {
1460
+ if (!(element.expr instanceof RegExp)) {
1461
+ element.expr = new RegExp('^' + element.resource, 'g');
1462
+ }
1463
+ });
1464
+ router.use((req, res, next) => {
1465
+ // only GET requests are cacheable
1466
+ if (req.method !== 'GET') {
1467
+ return next();
1468
+ }
1469
+ // if cache-control header is set to no-cache then skip caching
1470
+ const cacheControl = req.headers['cache-control'];
1471
+ if (cacheControl && cacheControl.includes('no-cache')) {
1472
+ return next();
1473
+ }
1474
+ for (let element of outputCacheElements) {
1475
+ if (element.expr.test(req.path)) {
1476
+ let profile;
1477
+ if (typeof element.profile === 'string') {
1478
+ profile = profiles.get(element.profile);
1479
+ } else if (typeof element.profile === 'object') {
1480
+ profile = element.profile;
1481
+ }
1482
+ if (profile) {
1483
+ // clone profile to avoid mutation
1484
+ Object.assign(req, {
1485
+ outputCaching: cloneDeep(profile)
1486
+ });
1487
+ }
1488
+ return next();
1489
+ }
1490
+ }
1491
+ return next();
1492
+ });
1493
+ router.use((req, res, next) => {
1494
+ try {
1495
+ const shouldCached = req.outputCaching && (req.outputCaching.location === 'any' || req.outputCaching.location === 'client');
1496
+ if (!shouldCached) {
1497
+ return next();
1498
+ }
1499
+ // determine cache location
1500
+ let cacheLocation = req.outputCaching.location === 'any' ? 'public' : 'private';
1501
+ if (req.headers.authorization && req.headers.authorization.length > 0) {
1502
+ // if authorization header is present, we should not cache the response publicly
1503
+ cacheLocation = 'private';
1504
+ }
1505
+ if (req.outputCaching.duration) {
1506
+ res.setHeader('Cache-Control', `${cacheLocation}, max-age=${req.outputCaching.duration}`);
1507
+ } else {
1508
+ res.setHeader('Cache-Control', cacheLocation);
1509
+ }
1510
+ const { varyByContentEncoding, varyByHeader, varyByParam, location, duration } = req.outputCaching;
1511
+ if (varyByContentEncoding) {
1512
+ res.setHeader('Vary', 'Accept-Encoding');
1513
+ }
1514
+ const varyByReqHeader = varyByHeader || [];
1515
+ if (varyByReqHeader.length) {
1516
+ res.setHeader('Vary', varyByReqHeader.join(', '));
1517
+ }
1518
+ let varyByQueryParam = varyByParam || [];
1519
+ if (varyByQueryParam.length === 1 && varyByQueryParam[0] === '*') {
1520
+ varyByQueryParam = Object.keys(req.query).sort((a, b) => {
1521
+ if (a < b) {
1522
+ return -1;
1523
+ }
1524
+ if (a > b) {
1525
+ return 1;
1526
+ }
1527
+ return 0;
1528
+ });
1529
+ }
1530
+
1531
+ const headers = varyByReqHeader.reduce((acc, val) => {
1532
+ acc[val] = req.get(val);
1533
+ return acc;
1534
+ }, {});
1535
+
1536
+ const params = varyByQueryParam.reduce((acc, val) => {
1537
+ if (req.query[val]) {
1538
+ acc[val] = req.query[val];
1539
+ }
1540
+ return acc;
1541
+ }, {});
1542
+
1543
+ // vary by query parameters is not supported by HTTP caching, but we can use it to create a cache key
1544
+ const entry = {
1545
+ path: req.path,
1546
+ location: location,
1547
+ contentEncoding: varyByContentEncoding,
1548
+ headers,
1549
+ params,
1550
+ customParams: null,
1551
+ duration: duration
1552
+ };
1553
+
1554
+ (async () => {
1555
+ const { varyByExpr } = req.outputCaching;
1556
+ if (varyByExpr && typeof varyByExpr === 'object') {
1557
+ // noinspection JSCheckFunctionSignatures
1558
+ const formatter = new data.ValueFormatter(req.context, null, req);
1559
+ entry.customParams = await formatter.format(varyByExpr);
1560
+ }
1561
+ return `W/"${MD5(JSON.stringify({
1562
+ path: entry.path,
1563
+ location: entry.location,
1564
+ contentEncoding: entry.contentEncoding,
1565
+ headers: entry.headers,
1566
+ params: entry.params,
1567
+ customParams: entry.customParams,
1568
+ duration: entry.duration
1569
+ })).toString()}"`;
1570
+ })().then((entityTag) => {
1571
+ if (req.headers['if-none-match'] === entityTag) {
1572
+ return res.status(304).end();
1573
+ }
1574
+ res.setHeader('ETag', entityTag);
1575
+ res.setHeader('Date', new Date().toUTCString());
1576
+ return next();
1577
+ }).catch((err) => {
1578
+ return next(err);
1579
+ });
1580
+ } catch (err) {
1581
+ return next(err);
1582
+ }
1583
+ });
1584
+ return router;
1585
+ }
1586
+
1587
+ class OutputCachingService extends common.ApplicationService {
1588
+ constructor(app) {
1589
+ super(app);
1590
+ let options = app.getConfiguration().getSourceAt('settings/universis/outputCaching') || {
1591
+ profiles: [],
1592
+ elements: []
1593
+ };
1594
+ if (typeof options.extends === 'string') {
1595
+ const configurationDir = this.getApplication().getConfiguration().getConfigurationPath();
1596
+ const parentOptions = require(path.resolve(configurationDir, options.extends));
1597
+ options = Object.assign({}, parentOptions, options);
1598
+ }
1599
+ /**
1600
+ * @type {Map<string, OutputCachingProfile>}
1601
+ */
1602
+ this.profiles = new Map(options.profiles || []);
1603
+ /**
1604
+ * @type {OutputCachingElement[]}
1605
+ */
1606
+ this.elements = options.elements || [];
1607
+ if (app && app.container) {
1608
+ app.container.subscribe((container) => {
1609
+ if (container == null) {
1610
+ return;
1611
+ }
1612
+ container.use(outputCache({
1613
+ profiles: this.profiles,
1614
+ elements: this.elements
1615
+ }));
1616
+ const stack = container._router && container._router.stack;
1617
+ if (Array.isArray(stack)) {
1618
+ let index = stack.findIndex((item) => item.name === 'dataContextMiddleware');
1619
+ if (index > -1) {
1620
+ stack.splice(index, 0, stack.pop());
1621
+ }
1622
+ }
1623
+ });
1624
+ }
1625
+ }
1626
+ }
1627
+
1628
+ class UserWithNetworkAddress extends data.UserService {
1629
+ constructor(app) {
1630
+ super(app);
1631
+ }
1632
+
1633
+ /**
1634
+ * @protected
1635
+ * @param {import('@themost/data').DataContext} context
1636
+ * @param {string} name
1637
+ * @return {import('@themost/data').DataQueryable}
1638
+ */
1639
+ queryUser(context, name) {
1640
+ return context.model('User').asQueryable().expand('groups', 'networkAddress').
1641
+ where('name').equal(name);
1642
+ }
1643
+
1644
+ /**
1645
+ * @protected
1646
+ * @param {import('@themost/data').DataContext} context
1647
+ * @param {string} name
1648
+ * @return {import('@themost/data').DataQueryable}
1649
+ */
1650
+ queryGroup(context, name) {
1651
+ return context.model('Group').asQueryable().expand('groups', 'networkAddress').
1652
+ where('name').equal(name);
1653
+ }
1654
+
1655
+ /**
1656
+ * Gets user by name
1657
+ * @param context
1658
+ * @param name
1659
+ * @returns {Promise<any>}
1660
+ */
1661
+ getUser(context, name) {
1662
+ // noinspection JSCheckFunctionSignatures
1663
+ /**
1664
+ * @type {import('./data-cache').DataCacheStrategy}
1665
+ */
1666
+ // noinspection JSCheckFunctionSignatures
1667
+ const cache = context.getConfiguration().getStrategy(function DataCacheStrategy() {});
1668
+ if (cache) {
1669
+ return cache.getOrDefault(`/User/${name}`, () => {
1670
+ return this.queryUser(context, name).silent().getItem().then((user) => {
1671
+ return user;
1672
+ });
1673
+ });
1674
+ }
1675
+ return this.queryUser(context, name).silent().getItem().then((user) => {
1676
+ return user;
1677
+ });
1678
+ }
1679
+
1680
+ /**
1681
+ * Gets group by name
1682
+ * @param context
1683
+ * @param name
1684
+ * @returns {Promise<any>}
1685
+ */
1686
+ getGroup(context, name) {
1687
+ // noinspection JSCheckFunctionSignatures
1688
+ /**
1689
+ * @type {import('./data-cache').DataCacheStrategy}
1690
+ */
1691
+ // noinspection JSCheckFunctionSignatures
1692
+ const cache = context.getConfiguration().getStrategy(function DataCacheStrategy() {});
1693
+ if (cache) {
1694
+ return cache.getOrDefault(`/Group/${name}`, () => {
1695
+ return this.queryGroup(context, name).silent().getItem().then((group) => {
1696
+ return group;
1697
+ });
1698
+ });
1699
+ }
1700
+ return this.queryGroup(context, name).silent().getItem().then((group) => {
1701
+ return group;
1702
+ });
1703
+ }
1704
+
1705
+ /**
1706
+ * Gets anonymous user
1707
+ * @param context
1708
+ * @returns {Promise<any>}
1709
+ */
1710
+ getAnonymousUser(context) {
1711
+ return this.getUser(context, 'anonymous');
1712
+ }
1713
+
1714
+ }
1715
+
1716
+ const AccountNetworkAddress = {
1717
+ "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json",
1718
+ "@id": "https://universis.io/schemas/AccountNetworkAddress",
1719
+ "name": "AccountNetworkAddress",
1720
+ "hidden": true,
1721
+ "source": "AccountNetworkAddress",
1722
+ "view": "AccountNetworkAddress",
1723
+ "version": "1.0.0",
1724
+ "fields": [
1725
+ {
1726
+ "name": "id",
1727
+ "type": "Counter",
1728
+ "nullable": false,
1729
+ "primary": true,
1730
+ "many": false
1731
+ },
1732
+ {
1733
+ "name": "account",
1734
+ "type": "Account",
1735
+ "nullable": false,
1736
+ "many": false,
1737
+ "indexed": true
1738
+ },
1739
+ {
1740
+ "name": "value",
1741
+ "type": "Text",
1742
+ "nullable": false,
1743
+ "many": false,
1744
+ "indexed": false
1745
+ }],
1746
+
1747
+ "constraints": [
1748
+ {
1749
+ "type": "unique",
1750
+ "fields": [
1751
+ "account",
1752
+ "value"]
1753
+
1754
+ }],
1755
+
1756
+ "privileges": [
1757
+ {
1758
+ "mask": 15,
1759
+ "type": "global"
1760
+ },
1761
+ {
1762
+ "mask": 15,
1763
+ "type": "global",
1764
+ "account": "Administrators"
1765
+ }]
1766
+
1767
+ };
1768
+
1769
+ class HttpNetworkAccessForbiddenError extends common.HttpForbiddenError {
1770
+ constructor() {
1771
+ super('Access is denied due to network address conflict.');
1772
+ this.statusCode = 403.6;
1773
+ }
1774
+
1775
+ }
1776
+
1777
+ class NetworkRestrictAccess extends common.ApplicationService {
1778
+ constructor(app) {
1779
+ super(app);
1780
+ Object.defineProperty(this, 'proxyAddressForwarding', {
1781
+ configurable: true,
1782
+ enumerable: false,
1783
+ value: !!app.getConfiguration().getSourceAt('settings/universis/api/proxyAddressForwarding'),
1784
+ writable: false
1785
+ });
1786
+ this.apply();
1787
+ }
1788
+
1789
+ apply() {
1790
+ // get schema loader
1791
+ const schemaLoader = this.getApplication().
1792
+ getConfiguration().
1793
+ getStrategy(data.SchemaLoaderStrategy);
1794
+ const accountNetworkAddressModel = schemaLoader.getModelDefinition('AccountNetworkAddress');
1795
+ if (accountNetworkAddressModel == null) {
1796
+ schemaLoader.setModelDefinition(AccountNetworkAddress);
1797
+ }
1798
+ // get model definition
1799
+ const model = schemaLoader.getModelDefinition('Account');
1800
+ if (model == null) {
1801
+ common.TraceUtils.warn('NetworkRestrictAccess: Account model definition not found.');
1802
+ return;
1803
+ }
1804
+ const found = model.fields.find((field) => {
1805
+ return field.name === 'networkAddress';
1806
+ });
1807
+ if (!found) {
1808
+ model.fields.push({
1809
+ "name": "networkAddress",
1810
+ "type": "Text",
1811
+ "many": true,
1812
+ "mapping": {
1813
+ "parentModel": "Account",
1814
+ "parentField": "id",
1815
+ "associationType": "junction",
1816
+ "associationAdapter": "AccountNetworkAddress",
1817
+ "cascade": "delete",
1818
+ "associationObjectField": "account",
1819
+ "associationValueField": "value"
1820
+ }
1821
+ });
1822
+ }
1823
+ model.eventListeners = model.eventListeners || [];
1824
+ let index = model.eventListeners.findIndex((listener) => {
1825
+ return listener.type === '@themost/data/previous-state-listener';
1826
+ });
1827
+ if (index < 0) {
1828
+ model.eventListeners.push({
1829
+ type: '@themost/data/previous-state-listener'
1830
+ });
1831
+ index = model.eventListeners.length - 1;
1832
+ }
1833
+ let otherIndex = model.eventListeners.findIndex((listener) => {
1834
+ return listener.type === path.resolve(__dirname, './OnAccountUpdate');
1835
+ });
1836
+ if (otherIndex < 0) {
1837
+ model.eventListeners.splice(index, 0, {
1838
+ type: path.resolve(__dirname, './OnAccountUpdate')
1839
+ });
1840
+ }
1841
+ schemaLoader.setModelDefinition(model);
1842
+ }
1843
+
1844
+ /**
1845
+ * Gets remote address from request
1846
+ * @param {import('express').Request} req
1847
+ * @returns
1848
+ */
1849
+ getRemoteAddress(req) {
1850
+ let remoteAddress;
1851
+ if (this.proxyAddressForwarding) {
1852
+ // get proxy headers or remote address
1853
+ // noinspection JSDeprecatedSymbols
1854
+ remoteAddress = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || (req.connection ? req.connection.remoteAddress : req.socket.remoteAddress);
1855
+ } else {
1856
+ // noinspection JSDeprecatedSymbols
1857
+ remoteAddress = req.connection ? req.connection.remoteAddress : req.socket.remoteAddress;
1858
+ }
1859
+ return remoteAddress;
1860
+ }
1861
+ }
1862
+
1863
+
1864
+
1865
+ /**
1866
+ * Validate network address for the current request against the assigned network addresses for the user account.
1867
+ * @returns {import('express').Handler}
1868
+ */
1869
+ function validateNetworkAddress() {
1870
+ /**
1871
+ * @param {import('express').Request} req
1872
+ * @param {import('express').Response} res
1873
+ * @param {import('express').NextFunction} next
1874
+ */
1875
+ return function (req, res, next) {
1876
+ try {
1877
+ const service = req.context.getApplication().getService(NetworkRestrictAccess);
1878
+ if (service == null) {
1879
+ return next();
1880
+ }
1881
+ req.context.user$.pipe(
1882
+ operators.take(1)
1883
+ ).subscribe({
1884
+ next: (user) => {
1885
+ if (user == null) {
1886
+ return next();
1887
+ }
1888
+ if (Array.isArray(user.networkAddress)) {
1889
+ if (user.networkAddress.length > 0) {
1890
+ // get remote address
1891
+ const remoteAddress = service.getRemoteAddress(req);
1892
+ const result = ipRangeCheck(remoteAddress, user.networkAddress);
1893
+ if (result !== true) {
1894
+ return next(new HttpNetworkAccessForbiddenError());
1895
+ }
1896
+ }
1897
+ }
1898
+ return next();
1899
+ },
1900
+ error: (err) => {
1901
+ return next(err);
1902
+ }
1903
+ });
1904
+ } catch (err) {
1905
+ return next(err);
1906
+ }
1907
+
1908
+ };
1909
+ }
1910
+
1911
+ class EnableNetworkRestrictAccess extends NetworkRestrictAccess {
1912
+ constructor(app) {
1913
+ super(app);
1914
+ if (app && app.serviceRouter) {
1915
+ app.serviceRouter.subscribe((serviceRouter) => {
1916
+ if (serviceRouter == null) {
1917
+ return;
1918
+ }
1919
+ const addRouter = express.Router();
1920
+ addRouter.use(validateNetworkAddress());
1921
+ // insert router at the beginning of serviceRouter.stack
1922
+ serviceRouter.stack.unshift.apply(serviceRouter.stack, addRouter.stack);
1923
+ });
1924
+ }
1925
+ }
1926
+ }
1927
+
1928
+ class DisableNetworkRestrictAccess extends NetworkRestrictAccess {
1929
+ constructor(app) {
1930
+ super(app);
1931
+ }
1932
+ }
1933
+
1340
1934
  exports.AppRateLimitService = AppRateLimitService;
1341
1935
  exports.AppSpeedLimitService = AppSpeedLimitService;
1342
1936
  exports.DefaultScopeAccessConfiguration = DefaultScopeAccessConfiguration;
1937
+ exports.DisableNetworkRestrictAccess = DisableNetworkRestrictAccess;
1938
+ exports.DisableUserClientScopeVerification = DisableUserClientScopeVerification;
1939
+ exports.EnableNetworkRestrictAccess = EnableNetworkRestrictAccess;
1343
1940
  exports.EnableScopeAccessConfiguration = EnableScopeAccessConfiguration;
1344
1941
  exports.ExtendScopeAccessConfiguration = ExtendScopeAccessConfiguration;
1345
1942
  exports.HttpAccountDisabled = HttpAccountDisabled;
@@ -1347,8 +1944,12 @@ exports.HttpBearerStrategy = HttpBearerStrategy;
1347
1944
  exports.HttpBearerTokenExpired = HttpBearerTokenExpired;
1348
1945
  exports.HttpBearerTokenNotFound = HttpBearerTokenNotFound;
1349
1946
  exports.HttpBearerTokenRequired = HttpBearerTokenRequired;
1947
+ exports.HttpNetworkAccessForbiddenError = HttpNetworkAccessForbiddenError;
1350
1948
  exports.HttpRemoteAddrForbiddenError = HttpRemoteAddrForbiddenError;
1949
+ exports.InvalidClientScopeError = InvalidClientScopeError;
1950
+ exports.NetworkRestrictAccess = NetworkRestrictAccess;
1351
1951
  exports.OAuth2ClientService = OAuth2ClientService;
1952
+ exports.OutputCachingService = OutputCachingService;
1352
1953
  exports.PassportService = PassportService;
1353
1954
  exports.RateLimitService = RateLimitService;
1354
1955
  exports.RedisClientStore = RedisClientStore;
@@ -1356,5 +1957,10 @@ exports.RemoteAddressValidator = RemoteAddressValidator;
1356
1957
  exports.ScopeAccessConfiguration = ScopeAccessConfiguration;
1357
1958
  exports.ScopeString = ScopeString;
1358
1959
  exports.SpeedLimitService = SpeedLimitService;
1960
+ exports.UserWithNetworkAddress = UserWithNetworkAddress;
1961
+ exports.VerifyUserClientScope = VerifyUserClientScope;
1962
+ exports.outputCache = outputCache;
1963
+ exports.validateClientScope = validateClientScope;
1964
+ exports.validateNetworkAddress = validateNetworkAddress;
1359
1965
  exports.validateScope = validateScope;
1360
1966
  //# sourceMappingURL=index.js.map