@zetra/citrineos-util 1.8.3-fork.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/authorization/ApiAuthPlugin.d.ts +52 -0
- package/dist/authorization/ApiAuthPlugin.js +122 -0
- package/dist/authorization/ApiAuthPlugin.js.map +1 -0
- package/dist/authorization/OidcTokenProvider.d.ts +15 -0
- package/dist/authorization/OidcTokenProvider.js +47 -0
- package/dist/authorization/OidcTokenProvider.js.map +1 -0
- package/dist/authorization/index.d.ts +4 -0
- package/dist/authorization/index.js +8 -0
- package/dist/authorization/index.js.map +1 -0
- package/dist/authorization/provider/LocalByPassAuthProvider.d.ts +34 -0
- package/dist/authorization/provider/LocalByPassAuthProvider.js +62 -0
- package/dist/authorization/provider/LocalByPassAuthProvider.js.map +1 -0
- package/dist/authorization/provider/OIDCAuthProvider.d.ts +62 -0
- package/dist/authorization/provider/OIDCAuthProvider.js +173 -0
- package/dist/authorization/provider/OIDCAuthProvider.js.map +1 -0
- package/dist/authorization/rbac/RbacRulesLoader.d.ts +32 -0
- package/dist/authorization/rbac/RbacRulesLoader.js +105 -0
- package/dist/authorization/rbac/RbacRulesLoader.js.map +1 -0
- package/dist/authorization/rbac/UrlMatcher.d.ts +14 -0
- package/dist/authorization/rbac/UrlMatcher.js +44 -0
- package/dist/authorization/rbac/UrlMatcher.js.map +1 -0
- package/dist/authorizer/RealTimeAuthorizer.d.ts +28 -0
- package/dist/authorizer/RealTimeAuthorizer.js +152 -0
- package/dist/authorizer/RealTimeAuthorizer.js.map +1 -0
- package/dist/authorizer/index.d.ts +1 -0
- package/dist/authorizer/index.js +5 -0
- package/dist/authorizer/index.js.map +1 -0
- package/dist/cache/memory.d.ts +19 -0
- package/dist/cache/memory.js +147 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/redis.d.ts +16 -0
- package/dist/cache/redis.js +120 -0
- package/dist/cache/redis.js.map +1 -0
- package/dist/certificate/CertificateAuthority.d.ts +38 -0
- package/dist/certificate/CertificateAuthority.js +233 -0
- package/dist/certificate/CertificateAuthority.js.map +1 -0
- package/dist/certificate/CertificateUtil.d.ts +60 -0
- package/dist/certificate/CertificateUtil.js +317 -0
- package/dist/certificate/CertificateUtil.js.map +1 -0
- package/dist/certificate/client/acme.d.ts +37 -0
- package/dist/certificate/client/acme.js +138 -0
- package/dist/certificate/client/acme.js.map +1 -0
- package/dist/certificate/client/hubject.d.ts +41 -0
- package/dist/certificate/client/hubject.js +221 -0
- package/dist/certificate/client/hubject.js.map +1 -0
- package/dist/certificate/client/interface.d.ts +12 -0
- package/dist/certificate/client/interface.js +5 -0
- package/dist/certificate/client/interface.js.map +1 -0
- package/dist/certificate/index.d.ts +2 -0
- package/dist/certificate/index.js +6 -0
- package/dist/certificate/index.js.map +1 -0
- package/dist/files/ftpServer.d.ts +4 -0
- package/dist/files/ftpServer.js +9 -0
- package/dist/files/ftpServer.js.map +1 -0
- package/dist/files/gcpCloudStorage.d.ts +39 -0
- package/dist/files/gcpCloudStorage.js +130 -0
- package/dist/files/gcpCloudStorage.js.map +1 -0
- package/dist/files/localStorage.d.ts +14 -0
- package/dist/files/localStorage.js +57 -0
- package/dist/files/localStorage.js.map +1 -0
- package/dist/files/s3Storage.d.ts +17 -0
- package/dist/files/s3Storage.js +118 -0
- package/dist/files/s3Storage.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/networkconnection/WebsocketNetworkConnection.d.ts +135 -0
- package/dist/networkconnection/WebsocketNetworkConnection.js +474 -0
- package/dist/networkconnection/WebsocketNetworkConnection.js.map +1 -0
- package/dist/networkconnection/authenticator/Authenticator.d.ts +20 -0
- package/dist/networkconnection/authenticator/Authenticator.js +39 -0
- package/dist/networkconnection/authenticator/Authenticator.js.map +1 -0
- package/dist/networkconnection/authenticator/AuthenticatorFilter.d.ts +11 -0
- package/dist/networkconnection/authenticator/AuthenticatorFilter.js +30 -0
- package/dist/networkconnection/authenticator/AuthenticatorFilter.js.map +1 -0
- package/dist/networkconnection/authenticator/BasicAuthenticationFilter.d.ts +17 -0
- package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js +51 -0
- package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js.map +1 -0
- package/dist/networkconnection/authenticator/ConnectedStationFilter.d.ts +14 -0
- package/dist/networkconnection/authenticator/ConnectedStationFilter.js +25 -0
- package/dist/networkconnection/authenticator/ConnectedStationFilter.js.map +1 -0
- package/dist/networkconnection/authenticator/NetworkProfileFilter.d.ts +16 -0
- package/dist/networkconnection/authenticator/NetworkProfileFilter.js +84 -0
- package/dist/networkconnection/authenticator/NetworkProfileFilter.js.map +1 -0
- package/dist/networkconnection/authenticator/UnknownStationFilter.d.ts +16 -0
- package/dist/networkconnection/authenticator/UnknownStationFilter.js +25 -0
- package/dist/networkconnection/authenticator/UnknownStationFilter.js.map +1 -0
- package/dist/networkconnection/authenticator/errors/AuthenticationError.d.ts +6 -0
- package/dist/networkconnection/authenticator/errors/AuthenticationError.js +25 -0
- package/dist/networkconnection/authenticator/errors/AuthenticationError.js.map +1 -0
- package/dist/networkconnection/authenticator/errors/IUpgradeError.d.ts +9 -0
- package/dist/networkconnection/authenticator/errors/IUpgradeError.js +5 -0
- package/dist/networkconnection/authenticator/errors/IUpgradeError.js.map +1 -0
- package/dist/networkconnection/authenticator/errors/UnknownError.d.ts +6 -0
- package/dist/networkconnection/authenticator/errors/UnknownError.js +24 -0
- package/dist/networkconnection/authenticator/errors/UnknownError.js.map +1 -0
- package/dist/networkconnection/index.d.ts +5 -0
- package/dist/networkconnection/index.js +9 -0
- package/dist/networkconnection/index.js.map +1 -0
- package/dist/queue/index.d.ts +4 -0
- package/dist/queue/index.js +8 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/kafka/receiver.d.ts +35 -0
- package/dist/queue/kafka/receiver.js +179 -0
- package/dist/queue/kafka/receiver.js.map +1 -0
- package/dist/queue/kafka/sender.d.ts +53 -0
- package/dist/queue/kafka/sender.js +189 -0
- package/dist/queue/kafka/sender.js.map +1 -0
- package/dist/queue/rabbit-mq/receiver.d.ts +89 -0
- package/dist/queue/rabbit-mq/receiver.js +472 -0
- package/dist/queue/rabbit-mq/receiver.js.map +1 -0
- package/dist/queue/rabbit-mq/sender.d.ts +90 -0
- package/dist/queue/rabbit-mq/sender.js +251 -0
- package/dist/queue/rabbit-mq/sender.js.map +1 -0
- package/dist/security/SignedMeterValuesUtil.d.ts +44 -0
- package/dist/security/SignedMeterValuesUtil.js +135 -0
- package/dist/security/SignedMeterValuesUtil.js.map +1 -0
- package/dist/security/authentication.d.ts +2 -0
- package/dist/security/authentication.js +26 -0
- package/dist/security/authentication.js.map +1 -0
- package/dist/util/RequestOperations.d.ts +14 -0
- package/dist/util/RequestOperations.js +25 -0
- package/dist/util/RequestOperations.js.map +1 -0
- package/dist/util/StringOperations.d.ts +1 -0
- package/dist/util/StringOperations.js +8 -0
- package/dist/util/StringOperations.js.map +1 -0
- package/dist/util/emaidCheckDigitCalculator.d.ts +15 -0
- package/dist/util/emaidCheckDigitCalculator.js +179 -0
- package/dist/util/emaidCheckDigitCalculator.js.map +1 -0
- package/dist/util/idGenerator.d.ts +7 -0
- package/dist/util/idGenerator.js +10 -0
- package/dist/util/idGenerator.js.map +1 -0
- package/dist/util/parser.d.ts +31 -0
- package/dist/util/parser.js +60 -0
- package/dist/util/parser.js.map +1 -0
- package/dist/util/swagger.d.ts +5 -0
- package/dist/util/swagger.js +154 -0
- package/dist/util/swagger.js.map +1 -0
- package/dist/util/validator.d.ts +110 -0
- package/dist/util/validator.js +534 -0
- package/dist/util/validator.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import { Logger } from 'tslog';
|
|
6
|
+
import { RbacRulesSchema } from '@citrineos/base';
|
|
7
|
+
import { UrlMatcher } from './UrlMatcher.js';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
/**
|
|
10
|
+
* Class to load and validate RBAC rules
|
|
11
|
+
*/
|
|
12
|
+
export class RbacRulesLoader {
|
|
13
|
+
_rules = {};
|
|
14
|
+
_logger;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new RBAC rules loader
|
|
17
|
+
*
|
|
18
|
+
* @param rulesFilePath Path to the JSON rules file
|
|
19
|
+
* @param logger Logger instance
|
|
20
|
+
*/
|
|
21
|
+
constructor(rulesFilePath, logger) {
|
|
22
|
+
this._logger = logger.getSubLogger({ name: 'RbacRulesLoader' });
|
|
23
|
+
this.loadRules(rulesFilePath);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load and validate rules from a JSON file
|
|
27
|
+
*
|
|
28
|
+
* @param filePath Path to the JSON rules file
|
|
29
|
+
*/
|
|
30
|
+
loadRules(filePath) {
|
|
31
|
+
const absoluteFilePath = path.join(process.cwd(), filePath);
|
|
32
|
+
try {
|
|
33
|
+
if (!fs.existsSync(absoluteFilePath)) {
|
|
34
|
+
this._logger.warn(`Rules file not found at ${absoluteFilePath}, using empty rules`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const rulesContent = fs.readFileSync(absoluteFilePath, 'utf8');
|
|
38
|
+
const parsedRules = JSON.parse(rulesContent);
|
|
39
|
+
// Validate rules against the schema
|
|
40
|
+
const validationResult = RbacRulesSchema.safeParse(parsedRules);
|
|
41
|
+
if (!validationResult.success) {
|
|
42
|
+
this._logger.error('Invalid RBAC rules format:', validationResult.error);
|
|
43
|
+
throw new Error('Invalid RBAC rules format');
|
|
44
|
+
}
|
|
45
|
+
// Store the validated rules
|
|
46
|
+
this._rules = validationResult.data;
|
|
47
|
+
this._logger.info(`Successfully loaded RBAC rules from ${filePath}`);
|
|
48
|
+
this._logger.debug(`Loaded ${Object.keys(this._rules).length} tenants with rules`);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (error instanceof Error && error.message === 'Invalid RBAC rules format') {
|
|
52
|
+
throw error; // Re-throw validation errors
|
|
53
|
+
}
|
|
54
|
+
this._logger.error('Failed to load RBAC rules:', error);
|
|
55
|
+
throw new Error(`Failed to load RBAC rules: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the required roles for a specific tenant, URL, and HTTP method
|
|
60
|
+
*
|
|
61
|
+
* @param tenantId Tenant identifier
|
|
62
|
+
* @param url URL path
|
|
63
|
+
* @param method HTTP method
|
|
64
|
+
* @returns Array of required roles or null if no matching rule
|
|
65
|
+
*/
|
|
66
|
+
getRequiredRoles(tenantId, url, method) {
|
|
67
|
+
// Normalize method to uppercase
|
|
68
|
+
method = method.toUpperCase();
|
|
69
|
+
const cleanUrl = this.normalizeUrl(url);
|
|
70
|
+
const tenantRules = this._rules[tenantId];
|
|
71
|
+
if (!tenantRules) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
// Try exact URL match first
|
|
75
|
+
const exactUrlRules = tenantRules[cleanUrl];
|
|
76
|
+
if (exactUrlRules) {
|
|
77
|
+
return exactUrlRules[method] || exactUrlRules['*'] || null;
|
|
78
|
+
}
|
|
79
|
+
// Pattern matching
|
|
80
|
+
for (const pattern in tenantRules) {
|
|
81
|
+
if (UrlMatcher.match(cleanUrl, pattern)) {
|
|
82
|
+
const methodRules = tenantRules[pattern];
|
|
83
|
+
const roles = methodRules[method] || methodRules['*'];
|
|
84
|
+
if (roles) {
|
|
85
|
+
return roles;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
normalizeUrl(url) {
|
|
92
|
+
// Remove query parameters and fragments
|
|
93
|
+
let cleanUrl = url.split('?')[0].split('#')[0];
|
|
94
|
+
// Remove trailing slash (optional, depends on your URL patterns)
|
|
95
|
+
if (cleanUrl.length > 1 && cleanUrl.endsWith('/')) {
|
|
96
|
+
cleanUrl = cleanUrl.slice(0, -1);
|
|
97
|
+
}
|
|
98
|
+
// Ensure it starts with /
|
|
99
|
+
if (!cleanUrl.startsWith('/')) {
|
|
100
|
+
cleanUrl = '/' + cleanUrl;
|
|
101
|
+
}
|
|
102
|
+
return cleanUrl;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=RbacRulesLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RbacRulesLoader.js","sourceRoot":"","sources":["../../../src/authorization/rbac/RbacRulesLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for matching URLs against patterns
|
|
3
|
+
*/
|
|
4
|
+
export declare class UrlMatcher {
|
|
5
|
+
/**
|
|
6
|
+
* Check if a URL matches a pattern
|
|
7
|
+
* Supports exact matches, wildcards, and path parameters
|
|
8
|
+
*
|
|
9
|
+
* @param url URL to check
|
|
10
|
+
* @param pattern Pattern to match against
|
|
11
|
+
* @returns True if URL matches pattern
|
|
12
|
+
*/
|
|
13
|
+
static match(url: string, pattern: string): boolean;
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
/**
|
|
5
|
+
* Utility for matching URLs against patterns
|
|
6
|
+
*/
|
|
7
|
+
export class UrlMatcher {
|
|
8
|
+
/**
|
|
9
|
+
* Check if a URL matches a pattern
|
|
10
|
+
* Supports exact matches, wildcards, and path parameters
|
|
11
|
+
*
|
|
12
|
+
* @param url URL to check
|
|
13
|
+
* @param pattern Pattern to match against
|
|
14
|
+
* @returns True if URL matches pattern
|
|
15
|
+
*/
|
|
16
|
+
static match(url, pattern) {
|
|
17
|
+
// Handle exact matches
|
|
18
|
+
if (url === pattern) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
// Handle wildcard patterns
|
|
22
|
+
if (pattern.endsWith('/*')) {
|
|
23
|
+
const basePattern = pattern.slice(0, -1);
|
|
24
|
+
return url === basePattern || url.startsWith(basePattern);
|
|
25
|
+
}
|
|
26
|
+
// Handle path parameters (e.g., /users/:id)
|
|
27
|
+
const patternSegments = pattern.split('/').filter(Boolean);
|
|
28
|
+
const urlSegments = url.split('/').filter(Boolean);
|
|
29
|
+
if (patternSegments.length !== urlSegments.length) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
33
|
+
// Skip path parameters (starting with :)
|
|
34
|
+
if (patternSegments[i].startsWith(':')) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (patternSegments[i] !== urlSegments[i]) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=UrlMatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UrlMatcher.js","sourceRoot":"","sources":["../../../src/authorization/rbac/UrlMatcher.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC;;GAEG;AACH,MAAM,OAAO,UAAU;IACrB;;;;;;;OAOG;IACI,MAAM,CAAC,KAAK,CAAC,GAAW,EAAE,OAAe;QAC9C,uBAAuB;QACvB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2BAA2B;QAC3B,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzC,OAAO,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAC5D,CAAC;QAED,4CAA4C;QAC5C,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,eAAe,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,yCAAyC;YACzC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,IAAI,eAAe,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type AuthorizationStatusEnumType, type ConnectorDto, type EvseDto, type IAuthorizer, type IdTokenEnumType, type IMessageContext, type SystemConfig } from '@citrineos/base';
|
|
2
|
+
import type { Authorization, ILocationRepository } from '@citrineos/data';
|
|
3
|
+
import type { ILogObj } from 'tslog';
|
|
4
|
+
import { Logger } from 'tslog';
|
|
5
|
+
export interface RealTimeAuthorizationRequestBody {
|
|
6
|
+
tenantPartnerId: number;
|
|
7
|
+
idToken: string;
|
|
8
|
+
idTokenType: IdTokenEnumType;
|
|
9
|
+
locationId?: string;
|
|
10
|
+
stationId: string;
|
|
11
|
+
evseId: number;
|
|
12
|
+
connectorId: number;
|
|
13
|
+
}
|
|
14
|
+
export interface RealTimeAuthorizationResponse {
|
|
15
|
+
timestamp: string;
|
|
16
|
+
data: {
|
|
17
|
+
allowed: string;
|
|
18
|
+
reason?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare class RealTimeAuthorizer implements IAuthorizer {
|
|
22
|
+
private _locationRepository;
|
|
23
|
+
private _config;
|
|
24
|
+
private readonly _logger;
|
|
25
|
+
private readonly _oidcTokenProvider?;
|
|
26
|
+
constructor(locationRepository: ILocationRepository, config: SystemConfig, logger?: Logger<ILogObj>);
|
|
27
|
+
authorize(authorization: Authorization, context: IMessageContext, evse?: EvseDto, connector?: ConnectorDto): Promise<AuthorizationStatusEnumType>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { AuthorizationStatusEnum, AuthorizationWhitelistEnum, } from '@citrineos/base';
|
|
5
|
+
import { Logger } from 'tslog';
|
|
6
|
+
import { OidcTokenProvider } from '../authorization/index.js';
|
|
7
|
+
export class RealTimeAuthorizer {
|
|
8
|
+
_locationRepository;
|
|
9
|
+
_config;
|
|
10
|
+
_logger;
|
|
11
|
+
_oidcTokenProvider;
|
|
12
|
+
constructor(locationRepository, config, logger) {
|
|
13
|
+
this._locationRepository = locationRepository;
|
|
14
|
+
this._config = config;
|
|
15
|
+
this._logger = logger
|
|
16
|
+
? logger.getSubLogger({ name: this.constructor.name })
|
|
17
|
+
: new Logger({ name: this.constructor.name });
|
|
18
|
+
if (config.oidcClient) {
|
|
19
|
+
this._oidcTokenProvider = new OidcTokenProvider(config.oidcClient, this._logger);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async authorize(authorization, context, evse, connector) {
|
|
23
|
+
if (!authorization.realTimeAuthUrl) {
|
|
24
|
+
this._logger.debug(`No Realtime Auth URL from authorization ${authorization.id}`);
|
|
25
|
+
return authorization.status;
|
|
26
|
+
}
|
|
27
|
+
else if (!authorization.realTimeAuth ||
|
|
28
|
+
authorization.realTimeAuth === AuthorizationWhitelistEnum.Allowed) {
|
|
29
|
+
this._logger.debug(`Realtime Auth whitelisted for authorization ${authorization.id}`);
|
|
30
|
+
return authorization.status;
|
|
31
|
+
}
|
|
32
|
+
else if (authorization.status !== AuthorizationStatusEnum.Accepted) {
|
|
33
|
+
this._logger.debug(`Skipping Realtime Auth for authorization ${authorization.id} with status ${authorization.status}`);
|
|
34
|
+
return authorization.status;
|
|
35
|
+
}
|
|
36
|
+
let evseId = undefined;
|
|
37
|
+
let connectorId = undefined;
|
|
38
|
+
let result = AuthorizationStatusEnum.Invalid;
|
|
39
|
+
try {
|
|
40
|
+
const chargingStation = await this._locationRepository.readChargingStationByStationId(context.tenantId, context.stationId);
|
|
41
|
+
// Determine evseId and connectorId
|
|
42
|
+
// Priority: provided evse and connector > provided evse with single connector > station with single evse and single connector
|
|
43
|
+
if (evse && connector) {
|
|
44
|
+
evseId = evse.id;
|
|
45
|
+
connectorId = connector.id;
|
|
46
|
+
}
|
|
47
|
+
else if (evse && !connector && evse.connectors?.length === 1) {
|
|
48
|
+
evseId = evse.id;
|
|
49
|
+
connectorId = evse.connectors[0].id;
|
|
50
|
+
}
|
|
51
|
+
else if (chargingStation &&
|
|
52
|
+
chargingStation.evses &&
|
|
53
|
+
chargingStation.evses.length === 1 &&
|
|
54
|
+
chargingStation.evses[0].connectors?.length === 1) {
|
|
55
|
+
evseId = chargingStation.evses[0].id;
|
|
56
|
+
connectorId = chargingStation.evses[0].connectors[0].id;
|
|
57
|
+
}
|
|
58
|
+
if (evseId === undefined || connectorId === undefined) {
|
|
59
|
+
this._logger.error(`Cannot determine evseId and connectorId for Realtime Auth of authorization ${authorization.id}`);
|
|
60
|
+
return authorization.status;
|
|
61
|
+
}
|
|
62
|
+
else if (authorization.realTimeAuthLastAttempt) {
|
|
63
|
+
const realTimeAuthLastAttempt = authorization.realTimeAuthLastAttempt;
|
|
64
|
+
// Check if last attempt was at the same station and connector within the timeout period
|
|
65
|
+
if (context.stationId === realTimeAuthLastAttempt.stationId &&
|
|
66
|
+
connectorId === realTimeAuthLastAttempt.connectorId) {
|
|
67
|
+
const lastAttempt = new Date(realTimeAuthLastAttempt.timestamp);
|
|
68
|
+
const timeout = authorization.realTimeAuthTimeout ?? this._config.realTimeAuthDefaultTimeoutSeconds;
|
|
69
|
+
const now = new Date();
|
|
70
|
+
const diffInSeconds = (now.getTime() - lastAttempt.getTime()) / 1000;
|
|
71
|
+
if (diffInSeconds < timeout) {
|
|
72
|
+
this._logger.debug(`Skipping Realtime Auth for authorization ${authorization.id} due to timeout (${diffInSeconds}s < ${timeout}s)`);
|
|
73
|
+
return realTimeAuthLastAttempt.result;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const payload = {
|
|
78
|
+
tenantPartnerId: authorization.tenantPartnerId, // Required if authorization has RealTimeAuth
|
|
79
|
+
idToken: authorization.idToken,
|
|
80
|
+
idTokenType: authorization.idTokenType,
|
|
81
|
+
locationId: chargingStation.locationId.toString(),
|
|
82
|
+
stationId: context.stationId,
|
|
83
|
+
evseId: evseId,
|
|
84
|
+
connectorId: connectorId,
|
|
85
|
+
};
|
|
86
|
+
this._logger.debug(`Sending Realtime Auth request for authorization ${authorization.id} to url: ${authorization.realTimeAuthUrl}`);
|
|
87
|
+
const headers = {
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
};
|
|
90
|
+
if (this._oidcTokenProvider) {
|
|
91
|
+
try {
|
|
92
|
+
const token = await this._oidcTokenProvider.getToken();
|
|
93
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
this._logger.error('Failed to get OIDC token:', error);
|
|
97
|
+
return AuthorizationStatusEnum.Invalid;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const response = await fetch(authorization.realTimeAuthUrl, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers,
|
|
103
|
+
body: JSON.stringify(payload),
|
|
104
|
+
});
|
|
105
|
+
const responseJson = await response.json();
|
|
106
|
+
const realTimeAuth = responseJson;
|
|
107
|
+
this._logger.debug(`Real time auth response: ${realTimeAuth.data.allowed}`);
|
|
108
|
+
if (realTimeAuth) {
|
|
109
|
+
switch (realTimeAuth.data.allowed) {
|
|
110
|
+
case 'ALLOWED':
|
|
111
|
+
result = AuthorizationStatusEnum.Accepted;
|
|
112
|
+
break;
|
|
113
|
+
case 'BLOCKED':
|
|
114
|
+
result = AuthorizationStatusEnum.Blocked;
|
|
115
|
+
break;
|
|
116
|
+
case 'EXPIRED':
|
|
117
|
+
result = AuthorizationStatusEnum.Expired;
|
|
118
|
+
break;
|
|
119
|
+
case 'NO_CREDIT':
|
|
120
|
+
result = AuthorizationStatusEnum.NoCredit;
|
|
121
|
+
break;
|
|
122
|
+
case 'NOT_ALLOWED':
|
|
123
|
+
result = AuthorizationStatusEnum.NotAtThisLocation;
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
result = AuthorizationStatusEnum.Unknown;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
result = AuthorizationStatusEnum.Unknown;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
this._logger.error(`Real-Time Auth failed: ${error}`);
|
|
135
|
+
if (authorization.realTimeAuth === 'AllowedOffline') {
|
|
136
|
+
result = AuthorizationStatusEnum.Accepted;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
authorization.realTimeAuthLastAttempt = {
|
|
140
|
+
timestamp: new Date().toISOString(),
|
|
141
|
+
result,
|
|
142
|
+
stationId: context.stationId,
|
|
143
|
+
evseId: evseId,
|
|
144
|
+
connectorId: connectorId,
|
|
145
|
+
};
|
|
146
|
+
authorization.save().catch((error) => {
|
|
147
|
+
this._logger.error(`Failed to save realTimeAuthLastAttempt for authorization ${authorization.id}: ${error}`);
|
|
148
|
+
});
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=RealTimeAuthorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealTimeAuthorizer.js","sourceRoot":"","sources":["../../src/authorizer/RealTimeAuthorizer.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC,OAAO,EACL,uBAAuB,EACvB,0BAA0B,GAQ3B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAoB9D,MAAM,OAAO,kBAAkB;IACrB,mBAAmB,CAAsB;IACzC,OAAO,CAAe;IACb,OAAO,CAAkB;IACzB,kBAAkB,CAAqB;IAExD,YACE,kBAAuC,EACvC,MAAoB,EACpB,MAAwB;QAExB,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,MAAM;YACnB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YACtD,CAAC,CAAC,IAAI,MAAM,CAAU,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,IAAI,CAAC,kBAAkB,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CACb,aAA4B,EAC5B,OAAwB,EACxB,IAAc,EACd,SAAwB;QAExB,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,2CAA2C,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;YAClF,OAAO,aAAa,CAAC,MAAM,CAAC;QAC9B,CAAC;aAAM,IACL,CAAC,aAAa,CAAC,YAAY;YAC3B,aAAa,CAAC,YAAY,KAAK,0BAA0B,CAAC,OAAO,EACjE,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,+CAA+C,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;YACtF,OAAO,aAAa,CAAC,MAAM,CAAC;QAC9B,CAAC;aAAM,IAAI,aAAa,CAAC,MAAM,KAAK,uBAAuB,CAAC,QAAQ,EAAE,CAAC;YACrE,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,4CAA4C,aAAa,CAAC,EAAE,gBAAgB,aAAa,CAAC,MAAM,EAAE,CACnG,CAAC;YACF,OAAO,aAAa,CAAC,MAAM,CAAC;QAC9B,CAAC;QAED,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,WAAW,GAAG,SAAS,CAAC;QAC5B,IAAI,MAAM,GAAgC,uBAAuB,CAAC,OAAO,CAAC;QAC1E,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,8BAA8B,CACnF,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,SAAS,CAClB,CAAC;YAEF,mCAAmC;YACnC,8HAA8H;YAC9H,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;gBACtB,MAAM,GAAG,IAAI,CAAC,EAAG,CAAC;gBAClB,WAAW,GAAG,SAAS,CAAC,EAAG,CAAC;YAC9B,CAAC;iBAAM,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/D,MAAM,GAAG,IAAI,CAAC,EAAG,CAAC;gBAClB,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAG,CAAC;YACvC,CAAC;iBAAM,IACL,eAAe;gBACf,eAAe,CAAC,KAAK;gBACrB,eAAe,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;gBAClC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,CAAC,EACjD,CAAC;gBACD,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAG,CAAC;gBACtC,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC,EAAG,CAAC;YAC5D,CAAC;YAED,IAAI,MAAM,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBACtD,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,8EAA8E,aAAa,CAAC,EAAE,EAAE,CACjG,CAAC;gBACF,OAAO,aAAa,CAAC,MAAM,CAAC;YAC9B,CAAC;iBAAM,IAAI,aAAa,CAAC,uBAAuB,EAAE,CAAC;gBACjD,MAAM,uBAAuB,GAAG,aAAa,CAAC,uBAAuB,CAAC;gBACtE,wFAAwF;gBACxF,IACE,OAAO,CAAC,SAAS,KAAK,uBAAuB,CAAC,SAAS;oBACvD,WAAY,KAAK,uBAAuB,CAAC,WAAW,EACpD,CAAC;oBACD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;oBAChE,MAAM,OAAO,GACX,aAAa,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC;oBACtF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;oBACrE,IAAI,aAAa,GAAG,OAAO,EAAE,CAAC;wBAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,4CAA4C,aAAa,CAAC,EAAE,oBAAoB,aAAa,OAAO,OAAO,IAAI,CAChH,CAAC;wBACF,OAAO,uBAAuB,CAAC,MAAM,CAAC;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,OAAO,GAAqC;gBAChD,eAAe,EAAE,aAAa,CAAC,eAAgB,EAAE,6CAA6C;gBAC9F,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,WAAW,EAAE,aAAa,CAAC,WAAY;gBACvC,UAAU,EAAE,eAAgB,CAAC,UAAW,CAAC,QAAQ,EAAE;gBACnD,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,WAAW;aACzB,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,mDAAmD,aAAa,CAAC,EAAE,YAAY,aAAa,CAAC,eAAe,EAAE,CAC/G,CAAC;YAEF,MAAM,OAAO,GAA8B;gBACzC,cAAc,EAAE,kBAAkB;aACnC,CAAC;YAEF,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC;oBACvD,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;gBAC/C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;oBACvD,OAAO,uBAAuB,CAAC,OAAO,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,eAAe,EAAE;gBAC1D,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAE3C,MAAM,YAAY,GAChB,YAA6C,CAAC;YAChD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5E,IAAI,YAAY,EAAE,CAAC;gBACjB,QAAQ,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClC,KAAK,SAAS;wBACZ,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC;wBAC1C,MAAM;oBACR,KAAK,SAAS;wBACZ,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC;wBACzC,MAAM;oBACR,KAAK,SAAS;wBACZ,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC;wBACzC,MAAM;oBACR,KAAK,WAAW;wBACd,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC;wBAC1C,MAAM;oBACR,KAAK,aAAa;wBAChB,MAAM,GAAG,uBAAuB,CAAC,iBAAiB,CAAC;wBACnD,MAAM;oBACR;wBACE,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC;gBAC7C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;YACtD,IAAI,aAAa,CAAC,YAAY,KAAK,gBAAgB,EAAE,CAAC;gBACpD,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,aAAa,CAAC,uBAAuB,GAAG;YACtC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM;YACN,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,MAAM;YACd,WAAW,EAAE,WAAY;SAC1B,CAAC;QACF,aAAa,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,4DAA4D,aAAa,CAAC,EAAE,KAAK,KAAK,EAAE,CACzF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './RealTimeAuthorizer.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authorizer/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ICache } from '@citrineos/base';
|
|
2
|
+
import type { ClassConstructor } from 'class-transformer';
|
|
3
|
+
/**
|
|
4
|
+
* Implementation of cache interface with memory storage
|
|
5
|
+
*/
|
|
6
|
+
export declare class MemoryCache implements ICache {
|
|
7
|
+
private _cache;
|
|
8
|
+
private _keySubscriptionMap;
|
|
9
|
+
private _keySubscriptionPromiseMap;
|
|
10
|
+
private _timeoutMap;
|
|
11
|
+
constructor();
|
|
12
|
+
exists(key: string, namespace?: string): Promise<boolean>;
|
|
13
|
+
remove(key: string, namespace?: string): Promise<boolean>;
|
|
14
|
+
onChange<T>(key: string, waitSeconds: number, namespace?: string, classConstructor?: () => ClassConstructor<T>): Promise<T | null>;
|
|
15
|
+
get<T>(key: string, namespace?: string, classConstructor?: () => ClassConstructor<T>): Promise<T | null>;
|
|
16
|
+
set(key: string, value: string, namespace?: string, expireSeconds?: number): Promise<boolean>;
|
|
17
|
+
setIfNotExist(key: string, value: string, namespace?: string, expireSeconds?: number): Promise<boolean>;
|
|
18
|
+
private resolveOnChange;
|
|
19
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { plainToInstance } from 'class-transformer';
|
|
5
|
+
/**
|
|
6
|
+
* Implementation of cache interface with memory storage
|
|
7
|
+
*/
|
|
8
|
+
export class MemoryCache {
|
|
9
|
+
_cache;
|
|
10
|
+
_keySubscriptionMap;
|
|
11
|
+
_keySubscriptionPromiseMap;
|
|
12
|
+
_timeoutMap;
|
|
13
|
+
constructor() {
|
|
14
|
+
const keySubscriptionMap = new Map();
|
|
15
|
+
const subscriptionHandler = {
|
|
16
|
+
// Returns value on keySubscriptions when Map.set(key, value) is called
|
|
17
|
+
set(target, property, value) {
|
|
18
|
+
const setOutcome = Reflect.set(target, property, value);
|
|
19
|
+
if (typeof property === 'string' && keySubscriptionMap.has(property) && setOutcome) {
|
|
20
|
+
(keySubscriptionMap?.get(property))(value);
|
|
21
|
+
}
|
|
22
|
+
return setOutcome;
|
|
23
|
+
},
|
|
24
|
+
// Returns null on keySubscriptions when Map.delete(key) is called
|
|
25
|
+
deleteProperty(target, property) {
|
|
26
|
+
const deleteOutcome = Reflect.deleteProperty(target, property);
|
|
27
|
+
if (typeof property === 'string' && keySubscriptionMap.has(property) && deleteOutcome) {
|
|
28
|
+
(keySubscriptionMap?.get(property))(null);
|
|
29
|
+
}
|
|
30
|
+
return deleteOutcome;
|
|
31
|
+
},
|
|
32
|
+
// Here to support Map.get and Map.has, does not alter behavior
|
|
33
|
+
get(target, property) {
|
|
34
|
+
const value = Reflect.get(target, property);
|
|
35
|
+
if (typeof value === 'function') {
|
|
36
|
+
// Return a bound version of the method to the original target
|
|
37
|
+
return value.bind(target);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
this._cache = new Proxy(new Map(), subscriptionHandler);
|
|
43
|
+
this._keySubscriptionMap = keySubscriptionMap;
|
|
44
|
+
this._keySubscriptionPromiseMap = new Map();
|
|
45
|
+
this._timeoutMap = new Map();
|
|
46
|
+
}
|
|
47
|
+
exists(key, namespace) {
|
|
48
|
+
namespace = namespace || 'default';
|
|
49
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
50
|
+
return Promise.resolve(this._cache.has(namespaceKey));
|
|
51
|
+
}
|
|
52
|
+
async remove(key, namespace) {
|
|
53
|
+
namespace = namespace || 'default';
|
|
54
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
55
|
+
return this._cache.delete(namespaceKey);
|
|
56
|
+
}
|
|
57
|
+
onChange(key, waitSeconds, namespace, classConstructor) {
|
|
58
|
+
namespace = namespace || 'default';
|
|
59
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
60
|
+
// Either get existing promise awaiting change on this key or create a new one and store it.
|
|
61
|
+
// This way, any number of threads can wait for the same key at the same time.
|
|
62
|
+
// Type must include 'undefined' due to Map.get(key)'s return type, however in no case can it actually be undefined.
|
|
63
|
+
const onChangeValuePromise = this._keySubscriptionPromiseMap.has(namespaceKey)
|
|
64
|
+
? this._keySubscriptionPromiseMap.get(namespaceKey)
|
|
65
|
+
: this._keySubscriptionPromiseMap
|
|
66
|
+
.set(namespaceKey, new Promise((resolve) => {
|
|
67
|
+
this._keySubscriptionMap.set(namespaceKey, (value) => {
|
|
68
|
+
resolve(value);
|
|
69
|
+
this._keySubscriptionMap.delete(namespaceKey);
|
|
70
|
+
this._keySubscriptionPromiseMap.delete(namespaceKey);
|
|
71
|
+
});
|
|
72
|
+
}))
|
|
73
|
+
.get(namespaceKey);
|
|
74
|
+
return Promise.race([
|
|
75
|
+
onChangeValuePromise?.then((value) => {
|
|
76
|
+
if (typeof value === 'string') {
|
|
77
|
+
if (classConstructor) {
|
|
78
|
+
return plainToInstance(classConstructor(), JSON.parse(value));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
88
|
+
new Promise((resolve) => {
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
resolve(this.get(key, namespace, classConstructor));
|
|
91
|
+
}, waitSeconds * 1000);
|
|
92
|
+
}),
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
async get(key, namespace, classConstructor) {
|
|
96
|
+
namespace = namespace || 'default';
|
|
97
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
98
|
+
const result = this._cache.get(namespaceKey);
|
|
99
|
+
if (result) {
|
|
100
|
+
if (classConstructor) {
|
|
101
|
+
return plainToInstance(classConstructor(), JSON.parse(result));
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
async set(key, value, namespace, expireSeconds) {
|
|
108
|
+
namespace = namespace || 'default';
|
|
109
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
110
|
+
this._cache.set(namespaceKey, value);
|
|
111
|
+
if (this._timeoutMap.has(namespaceKey)) {
|
|
112
|
+
clearTimeout(this._timeoutMap.get(namespaceKey));
|
|
113
|
+
}
|
|
114
|
+
if (expireSeconds) {
|
|
115
|
+
this._timeoutMap.set(namespaceKey, setTimeout(() => {
|
|
116
|
+
this._cache.delete(namespaceKey);
|
|
117
|
+
}, expireSeconds * 1000));
|
|
118
|
+
}
|
|
119
|
+
this.resolveOnChange(namespaceKey, value);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
async setIfNotExist(key, value, namespace, expireSeconds) {
|
|
123
|
+
namespace = namespace || 'default';
|
|
124
|
+
const namespaceKey = `${namespace}:${key}`;
|
|
125
|
+
if (this._cache.has(namespaceKey)) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
this._cache.set(namespaceKey, value);
|
|
129
|
+
if (this._timeoutMap.has(namespaceKey)) {
|
|
130
|
+
clearTimeout(this._timeoutMap.get(namespaceKey));
|
|
131
|
+
}
|
|
132
|
+
if (expireSeconds) {
|
|
133
|
+
this._timeoutMap.set(namespaceKey, setTimeout(() => {
|
|
134
|
+
this._cache.delete(namespaceKey);
|
|
135
|
+
}, expireSeconds * 1000));
|
|
136
|
+
}
|
|
137
|
+
this.resolveOnChange(namespaceKey, value);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
resolveOnChange(namespaceKey, value) {
|
|
141
|
+
const resolveOnChangeCallback = this._keySubscriptionMap.get(namespaceKey);
|
|
142
|
+
if (resolveOnChangeCallback) {
|
|
143
|
+
resolveOnChangeCallback(value);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/cache/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ICache } from '@citrineos/base';
|
|
2
|
+
import type { ClassConstructor } from 'class-transformer';
|
|
3
|
+
import type { RedisClientOptions } from 'redis';
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of cache interface with redis storage
|
|
6
|
+
*/
|
|
7
|
+
export declare class RedisCache implements ICache {
|
|
8
|
+
private _client;
|
|
9
|
+
constructor(clientOptions?: RedisClientOptions);
|
|
10
|
+
exists(key: string, namespace?: string): Promise<boolean>;
|
|
11
|
+
remove(key: string, namespace?: string | undefined): Promise<boolean>;
|
|
12
|
+
onChange<T>(key: string, waitSeconds: number, namespace?: string | undefined, classConstructor?: (() => ClassConstructor<T>) | undefined): Promise<T | null>;
|
|
13
|
+
get<T>(key: string, namespace?: string, classConstructor?: () => ClassConstructor<T>): Promise<T | null>;
|
|
14
|
+
set(key: string, value: string, namespace?: string, expireSeconds?: number): Promise<boolean>;
|
|
15
|
+
setIfNotExist(key: string, value: string, namespace?: string, expireSeconds?: number): Promise<boolean>;
|
|
16
|
+
}
|