@zetra/citrineos-util 1.8.3-fork.44 → 1.8.3-fork.47
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/authorizer/RealTimeAuthorizer.d.ts +2 -2
- package/dist/authorizer/UnknownTokenOcpiAuthorizer.d.ts +18 -0
- package/dist/authorizer/UnknownTokenOcpiAuthorizer.js +107 -0
- package/dist/authorizer/UnknownTokenOcpiAuthorizer.js.map +1 -0
- package/dist/authorizer/index.d.ts +1 -0
- package/dist/authorizer/index.js +1 -0
- package/dist/authorizer/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -8,8 +8,8 @@ export interface RealTimeAuthorizationRequestBody {
|
|
|
8
8
|
idTokenType: IdTokenEnumType;
|
|
9
9
|
locationId?: string;
|
|
10
10
|
stationId: string;
|
|
11
|
-
evseId
|
|
12
|
-
connectorId
|
|
11
|
+
evseId?: number;
|
|
12
|
+
connectorId?: number;
|
|
13
13
|
}
|
|
14
14
|
export interface RealTimeAuthorizationResponse {
|
|
15
15
|
timestamp: string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AuthorizationStatusEnumType, type IdTokenEnumType, type IMessageContext, type SystemConfig } from '@zetra/citrineos-base';
|
|
2
|
+
import type { ILocationRepository, ITenantPartnerRepository } from '@zetra/citrineos-data';
|
|
3
|
+
import type { ILogObj } from 'tslog';
|
|
4
|
+
import { Logger } from 'tslog';
|
|
5
|
+
/**
|
|
6
|
+
* Delegates real-time authorization of unknown tokens to the OCPI module's
|
|
7
|
+
* `/realTimeAuth` endpoint, which performs the OCPI `POST /authorize` against the eMSP.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UnknownTokenOcpiAuthorizer {
|
|
10
|
+
private readonly _locationRepository;
|
|
11
|
+
private readonly _tenantPartnerRepository;
|
|
12
|
+
private readonly _config;
|
|
13
|
+
private readonly _logger;
|
|
14
|
+
private readonly _oidcTokenProvider?;
|
|
15
|
+
constructor(locationRepository: ILocationRepository, tenantPartnerRepository: ITenantPartnerRepository, config: SystemConfig, logger?: Logger<ILogObj>);
|
|
16
|
+
authorize(idToken: string, idTokenType: IdTokenEnumType, context: IMessageContext): Promise<AuthorizationStatusEnumType>;
|
|
17
|
+
private _buildRealTimeAuthUrl;
|
|
18
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { AuthorizationStatusEnum, } from '@zetra/citrineos-base';
|
|
5
|
+
import { Logger } from 'tslog';
|
|
6
|
+
import { OidcTokenProvider } from '../authorization/index.js';
|
|
7
|
+
// The hub TenantPartner that unknown tokens are delegated to for real-time authorization.
|
|
8
|
+
// Warning : As of now, only one hub partner is supported. In case of several partners, need for a rework to send authorization to all partners.
|
|
9
|
+
const HUB_PARTNER_COUNTRY_CODE = 'FR';
|
|
10
|
+
const HUB_PARTNER_PARTY_IDS = ['007', '107'];
|
|
11
|
+
/**
|
|
12
|
+
* Delegates real-time authorization of unknown tokens to the OCPI module's
|
|
13
|
+
* `/realTimeAuth` endpoint, which performs the OCPI `POST /authorize` against the eMSP.
|
|
14
|
+
*/
|
|
15
|
+
export class UnknownTokenOcpiAuthorizer {
|
|
16
|
+
_locationRepository;
|
|
17
|
+
_tenantPartnerRepository;
|
|
18
|
+
_config;
|
|
19
|
+
_logger;
|
|
20
|
+
_oidcTokenProvider;
|
|
21
|
+
constructor(locationRepository, tenantPartnerRepository, config, logger) {
|
|
22
|
+
this._locationRepository = locationRepository;
|
|
23
|
+
this._tenantPartnerRepository = tenantPartnerRepository;
|
|
24
|
+
this._config = config;
|
|
25
|
+
this._logger = logger
|
|
26
|
+
? logger.getSubLogger({ name: this.constructor.name })
|
|
27
|
+
: new Logger({ name: this.constructor.name });
|
|
28
|
+
if (config.oidcClient) {
|
|
29
|
+
this._oidcTokenProvider = new OidcTokenProvider(config.oidcClient, this._logger);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async authorize(idToken, idTokenType, context) {
|
|
33
|
+
const hubPartner = await this._tenantPartnerRepository.getHubPartner(context.tenantId, HUB_PARTNER_COUNTRY_CODE, HUB_PARTNER_PARTY_IDS);
|
|
34
|
+
if (!hubPartner?.id) {
|
|
35
|
+
this._logger.debug(`No hub TenantPartner found for tenant ${context.tenantId} (${HUB_PARTNER_COUNTRY_CODE} ${HUB_PARTNER_PARTY_IDS.join('/')}); cannot delegate real-time authorization`);
|
|
36
|
+
return AuthorizationStatusEnum.Unknown;
|
|
37
|
+
}
|
|
38
|
+
const chargingStation = await this._locationRepository.readChargingStationByStationId(context.tenantId, context.stationId);
|
|
39
|
+
const payload = {
|
|
40
|
+
tenantPartnerId: hubPartner.id,
|
|
41
|
+
idToken,
|
|
42
|
+
idTokenType,
|
|
43
|
+
locationId: chargingStation?.locationId?.toString(),
|
|
44
|
+
stationId: context.stationId,
|
|
45
|
+
};
|
|
46
|
+
const url = this._buildRealTimeAuthUrl();
|
|
47
|
+
this._logger.debug(`Delegating unknown-token real-time authorization for partner ${hubPartner.id} to ${url}`);
|
|
48
|
+
try {
|
|
49
|
+
const headers = {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
};
|
|
52
|
+
// The OCPI `/realTimeAuth` endpoint is an admin endpoint. When citrineos-ocpi is
|
|
53
|
+
// configured with OIDC, it expects a Bearer JWT (client-credentials); otherwise we
|
|
54
|
+
// fall back to the legacy `Token <adminToken>` scheme.
|
|
55
|
+
if (this._oidcTokenProvider) {
|
|
56
|
+
try {
|
|
57
|
+
const token = await this._oidcTokenProvider.getToken();
|
|
58
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this._logger.error('Failed to get OIDC token for real-time authorization:', error);
|
|
62
|
+
return AuthorizationStatusEnum.Unknown;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (this._config.ocpiServer.adminToken) {
|
|
66
|
+
headers['Authorization'] = `Token ${this._config.ocpiServer.adminToken}`;
|
|
67
|
+
}
|
|
68
|
+
const response = await fetch(url, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers,
|
|
71
|
+
body: JSON.stringify(payload),
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const responseBody = await response.text();
|
|
75
|
+
this._logger.error(`Real-time authorization request to ${url} failed: HTTP ${response.status} ${responseBody}`);
|
|
76
|
+
return AuthorizationStatusEnum.Unknown;
|
|
77
|
+
}
|
|
78
|
+
const responseJson = (await response.json());
|
|
79
|
+
this._logger.debug(`Real-time auth response: ${responseJson?.data?.allowed}`);
|
|
80
|
+
switch (responseJson?.data?.allowed) {
|
|
81
|
+
case 'ALLOWED':
|
|
82
|
+
return AuthorizationStatusEnum.Accepted;
|
|
83
|
+
case 'BLOCKED':
|
|
84
|
+
return AuthorizationStatusEnum.Blocked;
|
|
85
|
+
case 'EXPIRED':
|
|
86
|
+
return AuthorizationStatusEnum.Expired;
|
|
87
|
+
case 'NO_CREDIT':
|
|
88
|
+
return AuthorizationStatusEnum.NoCredit;
|
|
89
|
+
case 'NOT_ALLOWED':
|
|
90
|
+
return AuthorizationStatusEnum.NotAtThisLocation;
|
|
91
|
+
default:
|
|
92
|
+
return AuthorizationStatusEnum.Unknown;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
this._logger.error(`Real-time authorization for unknown token failed: ${error}`);
|
|
97
|
+
return AuthorizationStatusEnum.Unknown;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
_buildRealTimeAuthUrl() {
|
|
101
|
+
const { host, port, version } = this._config.ocpiServer;
|
|
102
|
+
// Mirrors the citrineos-ocpi route: global '/ocpi' prefix + Tokens controller
|
|
103
|
+
// base '/:role(cpo|emsp)/:versionId/tokens' + the '/realTimeAuth' admin endpoint.
|
|
104
|
+
return `http://${host}:${port}/ocpi/emsp/${version}/tokens/realTimeAuth`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=UnknownTokenOcpiAuthorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnknownTokenOcpiAuthorizer.js","sourceRoot":"","sources":["../../src/authorizer/UnknownTokenOcpiAuthorizer.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC,OAAO,EACL,uBAAuB,GAKxB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAM9D,0FAA0F;AAC1F,gJAAgJ;AAChJ,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IACpB,mBAAmB,CAAsB;IACzC,wBAAwB,CAA2B;IACnD,OAAO,CAAe;IACtB,OAAO,CAAkB;IACzB,kBAAkB,CAAqB;IAExD,YACE,kBAAuC,EACvC,uBAAiD,EACjD,MAAoB,EACpB,MAAwB;QAExB,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,wBAAwB,GAAG,uBAAuB,CAAC;QACxD,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,OAAe,EACf,WAA4B,EAC5B,OAAwB;QAExB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,aAAa,CAClE,OAAO,CAAC,QAAQ,EAChB,wBAAwB,EACxB,qBAAqB,CACtB,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,yCAAyC,OAAO,CAAC,QAAQ,KAAK,wBAAwB,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,4CAA4C,CACtK,CAAC;YACF,OAAO,uBAAuB,CAAC,OAAO,CAAC;QACzC,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,8BAA8B,CACnF,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,SAAS,CAClB,CAAC;QAEF,MAAM,OAAO,GAAqC;YAChD,eAAe,EAAE,UAAU,CAAC,EAAE;YAC9B,OAAO;YACP,WAAW;YACX,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE;YACnD,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,gEAAgE,UAAU,CAAC,EAAE,OAAO,GAAG,EAAE,CAC1F,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAA8B;gBACzC,cAAc,EAAE,kBAAkB;aACnC,CAAC;YACF,iFAAiF;YACjF,mFAAmF;YACnF,uDAAuD;YACvD,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,uDAAuD,EAAE,KAAK,CAAC,CAAC;oBACnF,OAAO,uBAAuB,CAAC,OAAO,CAAC;gBACzC,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC9C,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YAC3E,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3C,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,sCAAsC,GAAG,iBAAiB,QAAQ,CAAC,MAAM,IAAI,YAAY,EAAE,CAC5F,CAAC;gBACF,OAAO,uBAAuB,CAAC,OAAO,CAAC;YACzC,CAAC;YAED,MAAM,YAAY,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkC,CAAC;YAC9E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAE9E,QAAQ,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBACpC,KAAK,SAAS;oBACZ,OAAO,uBAAuB,CAAC,QAAQ,CAAC;gBAC1C,KAAK,SAAS;oBACZ,OAAO,uBAAuB,CAAC,OAAO,CAAC;gBACzC,KAAK,SAAS;oBACZ,OAAO,uBAAuB,CAAC,OAAO,CAAC;gBACzC,KAAK,WAAW;oBACd,OAAO,uBAAuB,CAAC,QAAQ,CAAC;gBAC1C,KAAK,aAAa;oBAChB,OAAO,uBAAuB,CAAC,iBAAiB,CAAC;gBACnD;oBACE,OAAO,uBAAuB,CAAC,OAAO,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qDAAqD,KAAK,EAAE,CAAC,CAAC;YACjF,OAAO,uBAAuB,CAAC,OAAO,CAAC;QACzC,CAAC;IACH,CAAC;IAEO,qBAAqB;QAC3B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACxD,8EAA8E;QAC9E,kFAAkF;QAClF,OAAO,UAAU,IAAI,IAAI,IAAI,cAAc,OAAO,sBAAsB,CAAC;IAC3E,CAAC;CACF"}
|
package/dist/authorizer/index.js
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authorizer/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zetra/citrineos-util",
|
|
3
|
-
"version": "1.8.3-fork.
|
|
3
|
+
"version": "1.8.3-fork.47",
|
|
4
4
|
"description": "The OCPP util module which supplies helpful utilities like cache and queue connectors, etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"@types/jsrsasign": "10.5.14"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@zetra/citrineos-base": "1.8.3-fork.
|
|
28
|
-
"@zetra/citrineos-data": "1.8.3-fork.
|
|
27
|
+
"@zetra/citrineos-base": "1.8.3-fork.47",
|
|
28
|
+
"@zetra/citrineos-data": "1.8.3-fork.47",
|
|
29
29
|
"@fastify/swagger": "9.4.0",
|
|
30
30
|
"@fastify/swagger-ui": "5.2.0",
|
|
31
31
|
"@google-cloud/storage": "7.18.0",
|