@open-charging-cloud/chargy-core 0.8.0 → 0.9.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/README.md +67 -10
- package/dist/ACrypt.d.ts +2 -1
- package/dist/ACrypt.d.ts.map +1 -1
- package/dist/Alfen.d.ts.map +1 -1
- package/dist/BSMCrypt01.d.ts.map +1 -1
- package/dist/EMHCrypt01.d.ts.map +1 -1
- package/dist/GDFCrypt01.d.ts.map +1 -1
- package/dist/Mennekes.d.ts.map +1 -1
- package/dist/OCMF.d.ts +17 -2
- package/dist/OCMF.d.ts.map +1 -1
- package/dist/OCMF_BET_TariffTextExtension.d.ts +33 -0
- package/dist/OCMF_BET_TariffTextExtension.d.ts.map +1 -0
- package/dist/PTBContainer.d.ts +49 -0
- package/dist/PTBContainer.d.ts.map +1 -0
- package/dist/browser/index.js +614 -123
- package/dist/browser/index.js.map +1 -1
- package/dist/chargy.d.ts +6 -1
- package/dist/chargy.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/interfaces/chargyInterfaces.d.ts +20 -15
- package/dist/interfaces/chargyInterfaces.d.ts.map +1 -1
- package/dist/node/index.js +614 -123
- package/dist/node/index.js.map +1 -1
- package/i18n.json +35 -0
- package/package.json +1 -1
- package/dist/verificationResults.d.ts +0 -2
- package/dist/verificationResults.d.ts.map +0 -1
package/dist/browser/index.js
CHANGED
|
@@ -9841,11 +9841,16 @@ function CreateWarning(message, level = "low" /* low */) {
|
|
|
9841
9841
|
message
|
|
9842
9842
|
};
|
|
9843
9843
|
}
|
|
9844
|
-
function CreateError(message, level = "high" /* high
|
|
9845
|
-
|
|
9844
|
+
function CreateError(message, level = "high" /* high */, code, details) {
|
|
9845
|
+
const error = {
|
|
9846
9846
|
level,
|
|
9847
9847
|
message
|
|
9848
9848
|
};
|
|
9849
|
+
if (code !== void 0)
|
|
9850
|
+
error.code = code;
|
|
9851
|
+
if (details !== void 0)
|
|
9852
|
+
error.details = details;
|
|
9853
|
+
return error;
|
|
9849
9854
|
}
|
|
9850
9855
|
function isISessionCryptoResult1(obj) {
|
|
9851
9856
|
return isObject(obj) && obj["status"] !== void 0;
|
|
@@ -10831,6 +10836,20 @@ var ACrypt = class {
|
|
|
10831
10836
|
newText.classList.remove("overEntry");
|
|
10832
10837
|
};
|
|
10833
10838
|
}
|
|
10839
|
+
// Records why a verification step failed as structured data: a stable reason
|
|
10840
|
+
// key (localized via i18n.json and machine-switchable by the GUI) plus an
|
|
10841
|
+
// optional, language-neutral technical detail. Presentation is left to the GUI.
|
|
10842
|
+
AddVerificationError(cryptoResult, reasonKey, detail) {
|
|
10843
|
+
const details = detail instanceof Error ? detail.message : typeof detail === "string" ? detail : void 0;
|
|
10844
|
+
(cryptoResult.errors ??= []).push(
|
|
10845
|
+
CreateError(
|
|
10846
|
+
this.chargy.GetMultilanguageText(reasonKey),
|
|
10847
|
+
"high" /* high */,
|
|
10848
|
+
reasonKey,
|
|
10849
|
+
details
|
|
10850
|
+
)
|
|
10851
|
+
);
|
|
10852
|
+
}
|
|
10834
10853
|
};
|
|
10835
10854
|
var Alfen = class {
|
|
10836
10855
|
chargy;
|
|
@@ -11057,8 +11076,7 @@ var Alfen = class {
|
|
|
11057
11076
|
"connectors": [{
|
|
11058
11077
|
"type": asString(connector?.["type"]) ?? "",
|
|
11059
11078
|
"cable": {
|
|
11060
|
-
"length": asNumber(connector?.["cableLength"]) ?? 0
|
|
11061
|
-
"looses": asNumber(connector?.["cableLooses"]) ?? 0
|
|
11079
|
+
"length": asNumber(connector?.["cableLength"]) ?? 0
|
|
11062
11080
|
}
|
|
11063
11081
|
}],
|
|
11064
11082
|
"energyMeters": [
|
|
@@ -11246,9 +11264,15 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
11246
11264
|
cryptoResult.publicKey = meter.publicKeys[0]?.value;
|
|
11247
11265
|
cryptoResult.publicKeyFormat = meter.publicKeys[0]?.format;
|
|
11248
11266
|
cryptoResult.publicKeySignatures = meter.publicKeys[0]?.signatures;
|
|
11267
|
+
let publicKey;
|
|
11268
|
+
try {
|
|
11269
|
+
publicKey = buf2hex(this.chargy.base32Decode(cryptoResult.publicKey ?? "", "RFC4648"));
|
|
11270
|
+
} catch (exception) {
|
|
11271
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
11272
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
11273
|
+
}
|
|
11274
|
+
let result = false;
|
|
11249
11275
|
try {
|
|
11250
|
-
const publicKey = buf2hex(this.chargy.base32Decode(cryptoResult.publicKey ?? "", "RFC4648"));
|
|
11251
|
-
let result = false;
|
|
11252
11276
|
switch (meter.publicKeys[0]?.algorithm ?? "") {
|
|
11253
11277
|
case "secp192r1":
|
|
11254
11278
|
cryptoResult.hashValue = await sha256(cryptoBuffer);
|
|
@@ -11293,25 +11317,29 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
11293
11317
|
);
|
|
11294
11318
|
break;
|
|
11295
11319
|
}
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
}
|
|
11299
|
-
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11300
|
-
} catch {
|
|
11320
|
+
} catch (exception) {
|
|
11321
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
11301
11322
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11302
11323
|
}
|
|
11303
|
-
|
|
11324
|
+
if (result)
|
|
11325
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
11326
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
11327
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11328
|
+
} catch (exception) {
|
|
11329
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
11304
11330
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
11305
11331
|
}
|
|
11306
11332
|
} else
|
|
11307
11333
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
11308
11334
|
} else
|
|
11309
11335
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
11310
|
-
} catch {
|
|
11336
|
+
} catch (exception) {
|
|
11337
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
11311
11338
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11312
11339
|
}
|
|
11313
11340
|
}
|
|
11314
|
-
|
|
11341
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
11342
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11315
11343
|
}
|
|
11316
11344
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
11317
11345
|
const result = measurementValue.result;
|
|
@@ -12150,33 +12178,46 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
12150
12178
|
const publicKeyDER = ASN1_PublicKey.decode(Buffer.from(meter.publicKeys[0]?.value ?? "", "hex"), "der");
|
|
12151
12179
|
publicKey = buf2hex(publicKeyDER.publicKey.data).toLowerCase();
|
|
12152
12180
|
}
|
|
12181
|
+
let keyPair;
|
|
12153
12182
|
try {
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
)
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12183
|
+
keyPair = this.curve.keyFromPublic(publicKey, "hex");
|
|
12184
|
+
} catch (exception) {
|
|
12185
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12186
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12187
|
+
}
|
|
12188
|
+
const keyValidation = keyPair.validate();
|
|
12189
|
+
if (!keyValidation.result) {
|
|
12190
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
12191
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12192
|
+
}
|
|
12193
|
+
let signatureValid;
|
|
12194
|
+
try {
|
|
12195
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
12196
|
+
} catch (exception) {
|
|
12197
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
12166
12198
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12167
12199
|
}
|
|
12168
|
-
|
|
12200
|
+
if (measurementValue.errors && measurementValue.errors.length > 0)
|
|
12201
|
+
return setResult("ValidationError" /* ValidationError */);
|
|
12202
|
+
if (signatureValid)
|
|
12203
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
12204
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
12205
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12206
|
+
} catch (exception) {
|
|
12207
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12169
12208
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12170
12209
|
}
|
|
12171
12210
|
} else
|
|
12172
12211
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
12173
12212
|
} else
|
|
12174
12213
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
12175
|
-
} catch {
|
|
12214
|
+
} catch (exception) {
|
|
12215
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
12176
12216
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12177
12217
|
}
|
|
12178
12218
|
}
|
|
12179
|
-
|
|
12219
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
12220
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12180
12221
|
}
|
|
12181
12222
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
12182
12223
|
if (measurementValue.measurement === void 0)
|
|
@@ -12355,35 +12396,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
12355
12396
|
if ((value & 1 << 29) != 0) events.push("OEM 15");
|
|
12356
12397
|
return events;
|
|
12357
12398
|
}
|
|
12358
|
-
|
|
12359
|
-
// {
|
|
12360
|
-
// const statusArray:string[] = [];
|
|
12361
|
-
// try
|
|
12362
|
-
// {
|
|
12363
|
-
// const status = parseInt(statusValue);
|
|
12364
|
-
// if ((status & 1) == 1)
|
|
12365
|
-
// statusArray.push("Fehler erkannt");
|
|
12366
|
-
// if ((status & 2) == 2)
|
|
12367
|
-
// statusArray.push("Synchrone Messwertübermittlung");
|
|
12368
|
-
// // Bit 3 is reserved!
|
|
12369
|
-
// if ((status & 8) == 8)
|
|
12370
|
-
// statusArray.push("System-Uhr ist synchron");
|
|
12371
|
-
// else
|
|
12372
|
-
// statusArray.push("System-Uhr ist nicht synchron");
|
|
12373
|
-
// if ((status & 16) == 16)
|
|
12374
|
-
// statusArray.push("Rücklaufsperre aktiv");
|
|
12375
|
-
// if ((status & 32) == 32)
|
|
12376
|
-
// statusArray.push("Energierichtung -A");
|
|
12377
|
-
// if ((status & 64) == 64)
|
|
12378
|
-
// statusArray.push("Magnetfeld erkannt");
|
|
12379
|
-
// }
|
|
12380
|
-
// catch
|
|
12381
|
-
// {
|
|
12382
|
-
// statusArray.push("Invalid status!");
|
|
12383
|
-
// }
|
|
12384
|
-
// return statusArray;
|
|
12385
|
-
// }
|
|
12386
|
-
// //#endregion
|
|
12399
|
+
//#endregion
|
|
12387
12400
|
};
|
|
12388
12401
|
|
|
12389
12402
|
// src/interfaces/IPublicKeyInfo.ts
|
|
@@ -13842,29 +13855,44 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
13842
13855
|
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
13843
13856
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
13844
13857
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
13858
|
+
let keyPair;
|
|
13845
13859
|
try {
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
)
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
|
|
13853
|
-
|
|
13860
|
+
keyPair = this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex");
|
|
13861
|
+
} catch (exception) {
|
|
13862
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
13863
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
13864
|
+
}
|
|
13865
|
+
const keyValidation = keyPair.validate();
|
|
13866
|
+
if (!keyValidation.result) {
|
|
13867
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
13868
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
13869
|
+
}
|
|
13870
|
+
let signatureValid;
|
|
13871
|
+
try {
|
|
13872
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
13873
|
+
} catch (exception) {
|
|
13874
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
13854
13875
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
13855
13876
|
}
|
|
13856
|
-
|
|
13877
|
+
if (signatureValid)
|
|
13878
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
13879
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
13880
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
13881
|
+
} catch (exception) {
|
|
13882
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
13857
13883
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
13858
13884
|
}
|
|
13859
13885
|
} else
|
|
13860
13886
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
13861
13887
|
} else
|
|
13862
13888
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
13863
|
-
} catch {
|
|
13889
|
+
} catch (exception) {
|
|
13890
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
13864
13891
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
13865
13892
|
}
|
|
13866
13893
|
}
|
|
13867
|
-
|
|
13894
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
13895
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
13868
13896
|
}
|
|
13869
13897
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
13870
13898
|
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
@@ -13972,7 +14000,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
13972
14000
|
DecodeStatus(statusValue) {
|
|
13973
14001
|
const statusArray = [];
|
|
13974
14002
|
try {
|
|
13975
|
-
const status = parseInt(statusValue);
|
|
14003
|
+
const status = parseInt(statusValue, 16);
|
|
13976
14004
|
if ((status & 1) == 1)
|
|
13977
14005
|
statusArray.push("Fehler erkannt");
|
|
13978
14006
|
if ((status & 2) == 2)
|
|
@@ -14074,29 +14102,44 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
14074
14102
|
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
14075
14103
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
14076
14104
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
14105
|
+
let keyPair;
|
|
14077
14106
|
try {
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
)
|
|
14082
|
-
|
|
14083
|
-
|
|
14084
|
-
|
|
14085
|
-
|
|
14107
|
+
keyPair = this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex");
|
|
14108
|
+
} catch (exception) {
|
|
14109
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
14110
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14111
|
+
}
|
|
14112
|
+
const keyValidation = keyPair.validate();
|
|
14113
|
+
if (!keyValidation.result) {
|
|
14114
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
14115
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14116
|
+
}
|
|
14117
|
+
let signatureValid;
|
|
14118
|
+
try {
|
|
14119
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
14120
|
+
} catch (exception) {
|
|
14121
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
14086
14122
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14087
14123
|
}
|
|
14088
|
-
|
|
14124
|
+
if (signatureValid)
|
|
14125
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
14126
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
14127
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14128
|
+
} catch (exception) {
|
|
14129
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
14089
14130
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14090
14131
|
}
|
|
14091
14132
|
} else
|
|
14092
14133
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
14093
14134
|
} else
|
|
14094
14135
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
14095
|
-
} catch {
|
|
14136
|
+
} catch (exception) {
|
|
14137
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
14096
14138
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14097
14139
|
}
|
|
14098
14140
|
}
|
|
14099
|
-
|
|
14141
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
14142
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14100
14143
|
}
|
|
14101
14144
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
14102
14145
|
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
@@ -14435,19 +14478,38 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
14435
14478
|
);
|
|
14436
14479
|
cryptoResult.hashValue = (await sha256(new DataView(signedDataBuffer))).substring(0, 48);
|
|
14437
14480
|
const publicKey = cleanHex(meter.publicKeys.at(0)?.value ?? measurement.publicKey);
|
|
14438
|
-
if (publicKey.length !== 96)
|
|
14481
|
+
if (publicKey.length !== 96) {
|
|
14482
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed");
|
|
14439
14483
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14440
|
-
|
|
14441
|
-
|
|
14442
|
-
|
|
14484
|
+
}
|
|
14485
|
+
let keyPair;
|
|
14486
|
+
try {
|
|
14487
|
+
keyPair = this.curve192r1.keyFromPublic("04" + publicKey, "hex");
|
|
14488
|
+
} catch (exception) {
|
|
14489
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
14490
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14491
|
+
}
|
|
14492
|
+
const keyValidation = keyPair.validate();
|
|
14493
|
+
if (!keyValidation.result) {
|
|
14494
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
14495
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
14496
|
+
}
|
|
14497
|
+
let signatureValid;
|
|
14498
|
+
try {
|
|
14499
|
+
signatureValid = keyPair.verify(cryptoResult.hashValue.toUpperCase(), {
|
|
14443
14500
|
r: signatureExpected.r,
|
|
14444
14501
|
s: signatureExpected.s
|
|
14445
|
-
}
|
|
14446
|
-
)
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14502
|
+
});
|
|
14503
|
+
} catch (exception) {
|
|
14504
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
14505
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14506
|
+
}
|
|
14507
|
+
if (signatureValid)
|
|
14508
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
14509
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
14510
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14511
|
+
} catch (exception) {
|
|
14512
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
14451
14513
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
14452
14514
|
}
|
|
14453
14515
|
}
|
|
@@ -14653,6 +14715,132 @@ function numberToBytesBE(value, length) {
|
|
|
14653
14715
|
}
|
|
14654
14716
|
return bytes;
|
|
14655
14717
|
}
|
|
14718
|
+
var OCMFBonnTariffParseError = class extends Error {
|
|
14719
|
+
tariffText;
|
|
14720
|
+
constructor(tariffText, message) {
|
|
14721
|
+
super(message);
|
|
14722
|
+
this.name = "OCMFBonnTariffParseError";
|
|
14723
|
+
this.tariffText = tariffText;
|
|
14724
|
+
}
|
|
14725
|
+
};
|
|
14726
|
+
function parseCents(value, tariffText, fieldName) {
|
|
14727
|
+
if (!/^(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(value))
|
|
14728
|
+
throw new OCMFBonnTariffParseError(tariffText, `${fieldName} must be a non-negative decimal number`);
|
|
14729
|
+
const parsedValue = Number(value);
|
|
14730
|
+
if (!Number.isFinite(parsedValue))
|
|
14731
|
+
throw new OCMFBonnTariffParseError(tariffText, `${fieldName} is outside the supported numeric range`);
|
|
14732
|
+
return parsedValue;
|
|
14733
|
+
}
|
|
14734
|
+
function parseOCMFBonnTariffText(tariffText) {
|
|
14735
|
+
const fields = tariffText.split(";");
|
|
14736
|
+
const code = fields[0];
|
|
14737
|
+
if (fields[1] !== "EUR")
|
|
14738
|
+
throw new OCMFBonnTariffParseError(tariffText, "currency must be EUR");
|
|
14739
|
+
switch (code) {
|
|
14740
|
+
case "001":
|
|
14741
|
+
if (fields.length !== 6)
|
|
14742
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 001 must contain six fields");
|
|
14743
|
+
return {
|
|
14744
|
+
raw: tariffText,
|
|
14745
|
+
code,
|
|
14746
|
+
currency: "EUR",
|
|
14747
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
14748
|
+
energyFeeCentsPerKWh: parseCents(fields[3] ?? "", tariffText, "X"),
|
|
14749
|
+
blockingFeeCentsPerMinute: parseCents(fields[4] ?? "", tariffText, "Y"),
|
|
14750
|
+
blockingFeeStartMinute: parseCents(fields[5] ?? "", tariffText, "Z")
|
|
14751
|
+
};
|
|
14752
|
+
case "002":
|
|
14753
|
+
if (fields.length !== 5)
|
|
14754
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 002 must contain five fields");
|
|
14755
|
+
return {
|
|
14756
|
+
raw: tariffText,
|
|
14757
|
+
code,
|
|
14758
|
+
currency: "EUR",
|
|
14759
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
14760
|
+
energyFeeCentsPerKWh: parseCents(fields[3] ?? "", tariffText, "X"),
|
|
14761
|
+
blockingFeeCentsPerMinute: parseCents(fields[4] ?? "", tariffText, "Y"),
|
|
14762
|
+
blockingFeeStartsAfterCharging: true
|
|
14763
|
+
};
|
|
14764
|
+
case "003":
|
|
14765
|
+
if (fields.length !== 4)
|
|
14766
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 003 must contain four fields");
|
|
14767
|
+
return {
|
|
14768
|
+
raw: tariffText,
|
|
14769
|
+
code,
|
|
14770
|
+
currency: "EUR",
|
|
14771
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
14772
|
+
timeFeeCentsPerMinute: parseCents(fields[3] ?? "", tariffText, "X")
|
|
14773
|
+
};
|
|
14774
|
+
default:
|
|
14775
|
+
throw new OCMFBonnTariffParseError(tariffText, "unknown Bonn tariff profile");
|
|
14776
|
+
}
|
|
14777
|
+
}
|
|
14778
|
+
function tryParseOCMFBonnTariffText(tariffText) {
|
|
14779
|
+
try {
|
|
14780
|
+
return parseOCMFBonnTariffText(tariffText);
|
|
14781
|
+
} catch (error) {
|
|
14782
|
+
if (error instanceof OCMFBonnTariffParseError)
|
|
14783
|
+
return void 0;
|
|
14784
|
+
throw error;
|
|
14785
|
+
}
|
|
14786
|
+
}
|
|
14787
|
+
function priceComponent(type, price, stepSize) {
|
|
14788
|
+
return {
|
|
14789
|
+
type,
|
|
14790
|
+
price,
|
|
14791
|
+
step_size: stepSize
|
|
14792
|
+
};
|
|
14793
|
+
}
|
|
14794
|
+
function eurosFromCents(cents) {
|
|
14795
|
+
return new Decimal(cents).dividedBy(100);
|
|
14796
|
+
}
|
|
14797
|
+
function eurosPerHourFromCentsPerMinute(cents) {
|
|
14798
|
+
return eurosFromCents(cents).times(60);
|
|
14799
|
+
}
|
|
14800
|
+
function ocmfBonnTariffToChargingTariff(tariff) {
|
|
14801
|
+
const baseComponents = new Array(
|
|
14802
|
+
priceComponent("FLAT", eurosFromCents(tariff.startFeeCents), 1)
|
|
14803
|
+
);
|
|
14804
|
+
const elements = new Array();
|
|
14805
|
+
switch (tariff.code) {
|
|
14806
|
+
case "001":
|
|
14807
|
+
baseComponents.push(priceComponent("ENERGY", eurosFromCents(tariff.energyFeeCentsPerKWh), 1));
|
|
14808
|
+
elements.push(
|
|
14809
|
+
{ price_components: baseComponents },
|
|
14810
|
+
{
|
|
14811
|
+
price_components: [
|
|
14812
|
+
priceComponent("PARKING_TIME", eurosPerHourFromCentsPerMinute(tariff.blockingFeeCentsPerMinute), 60)
|
|
14813
|
+
],
|
|
14814
|
+
restrictions: {
|
|
14815
|
+
min_duration: tariff.blockingFeeStartMinute * 60
|
|
14816
|
+
}
|
|
14817
|
+
}
|
|
14818
|
+
);
|
|
14819
|
+
break;
|
|
14820
|
+
case "002":
|
|
14821
|
+
baseComponents.push(priceComponent("ENERGY", eurosFromCents(tariff.energyFeeCentsPerKWh), 1));
|
|
14822
|
+
elements.push(
|
|
14823
|
+
{ price_components: baseComponents },
|
|
14824
|
+
{
|
|
14825
|
+
price_components: [
|
|
14826
|
+
priceComponent("PARKING_TIME", eurosPerHourFromCentsPerMinute(tariff.blockingFeeCentsPerMinute), 60)
|
|
14827
|
+
]
|
|
14828
|
+
}
|
|
14829
|
+
);
|
|
14830
|
+
break;
|
|
14831
|
+
case "003":
|
|
14832
|
+
baseComponents.push(priceComponent("TIME", eurosPerHourFromCentsPerMinute(tariff.timeFeeCentsPerMinute), 60));
|
|
14833
|
+
elements.push({ price_components: baseComponents });
|
|
14834
|
+
break;
|
|
14835
|
+
}
|
|
14836
|
+
return {
|
|
14837
|
+
"@id": tariff.raw,
|
|
14838
|
+
currency: tariff.currency,
|
|
14839
|
+
elements
|
|
14840
|
+
};
|
|
14841
|
+
}
|
|
14842
|
+
|
|
14843
|
+
// src/OCMF.ts
|
|
14656
14844
|
var OCMFv1_x = class extends ACrypt {
|
|
14657
14845
|
curve = new this.chargy.elliptic.ec("p256");
|
|
14658
14846
|
constructor(chargy) {
|
|
@@ -14742,6 +14930,8 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
14742
14930
|
return "Reading Current Type";
|
|
14743
14931
|
case "CL":
|
|
14744
14932
|
return "Cumulated Loss";
|
|
14933
|
+
case "EI":
|
|
14934
|
+
return "Error Index";
|
|
14745
14935
|
case "EF":
|
|
14746
14936
|
return "Error Flags";
|
|
14747
14937
|
case "ST":
|
|
@@ -14949,10 +15139,39 @@ var OCMF = class {
|
|
|
14949
15139
|
const identificationType = firstOCMDJSONDocument.payload.IT;
|
|
14950
15140
|
const identificationData = firstOCMDJSONDocument.payload.ID;
|
|
14951
15141
|
const tariffText = firstOCMDJSONDocument.payload.TT;
|
|
14952
|
-
const
|
|
15142
|
+
const tariffTextInterpretation = typeof tariffText === "string" ? tryParseOCMFBonnTariffText(tariffText) : void 0;
|
|
15143
|
+
const chargingTariff = typeof tariffText === "string" && tariffText.length > 0 ? tariffTextInterpretation !== void 0 ? ocmfBonnTariffToChargingTariff(tariffTextInterpretation) : { "@id": tariffText } : void 0;
|
|
15144
|
+
const controllerFirmwareVersion = firstOCMDJSONDocument.payload.CF;
|
|
14953
15145
|
const lossCompensation = firstOCMDJSONDocument.payload.LC;
|
|
15146
|
+
const signedCable = lossCompensation !== void 0 && typeof lossCompensation.LR === "number" && Number.isFinite(lossCompensation.LR) && typeof lossCompensation.LU === "string" && lossCompensation.LU.length > 0 ? {
|
|
15147
|
+
...typeof lossCompensation.LN === "string" ? { lossCompensation: lossCompensation.LN } : {},
|
|
15148
|
+
...typeof lossCompensation.LI === "number" ? { lossCompensationId: lossCompensation.LI.toString() } : {},
|
|
15149
|
+
resistance: lossCompensation.LR,
|
|
15150
|
+
resistanceUnit: lossCompensation.LU
|
|
15151
|
+
} : void 0;
|
|
14954
15152
|
const chargePointIdType = firstOCMDJSONDocument.payload.CT;
|
|
14955
15153
|
const chargePointId = firstOCMDJSONDocument.payload.CI;
|
|
15154
|
+
let signedChargingStationId;
|
|
15155
|
+
let signedEVSEId;
|
|
15156
|
+
let signedConnectorId;
|
|
15157
|
+
if (typeof chargePointId === "string" && chargePointId.trim().length > 0) {
|
|
15158
|
+
const normalizedChargePointId = chargePointId.trim();
|
|
15159
|
+
switch (chargePointIdType?.toUpperCase()) {
|
|
15160
|
+
case void 0:
|
|
15161
|
+
break;
|
|
15162
|
+
case "EVSEID":
|
|
15163
|
+
signedEVSEId = normalizedChargePointId;
|
|
15164
|
+
break;
|
|
15165
|
+
case "CBIDC": {
|
|
15166
|
+
const cbidcMatch = /^(\S+)\s+(\S+)$/.exec(normalizedChargePointId);
|
|
15167
|
+
if (cbidcMatch?.[1] !== void 0 && cbidcMatch[2] !== void 0) {
|
|
15168
|
+
signedChargingStationId = cbidcMatch[1];
|
|
15169
|
+
signedConnectorId = cbidcMatch[2];
|
|
15170
|
+
}
|
|
15171
|
+
break;
|
|
15172
|
+
}
|
|
15173
|
+
}
|
|
15174
|
+
}
|
|
14956
15175
|
if (isOptionalString(formatVersion) && isOptionalString(gatewayInformation) && isOptionalString(gatewaySerial) && isOptionalString(gatewayVersion) && isMandatoryString(paging) && isOptionalString(meterVendor) && isOptionalString(meterModel) && // OCMF 1.0 table 3 lists MS as 1..1, but the later "Relation of Serial Numbers,
|
|
14957
15176
|
// Charge Point and Public Key" section makes the serial-number fields conditionally
|
|
14958
15177
|
// mandatory. KEBA KCP30 records identify the signing gateway via GS and omit MS.
|
|
@@ -14965,7 +15184,7 @@ var OCMF = class {
|
|
|
14965
15184
|
// IT is 1..1 in the user-assignment table for transaction records. Some OCMF 1.0
|
|
14966
15185
|
// implementations omit it when no user is assigned (IS=false, ID empty). We tolerate
|
|
14967
15186
|
// this vendor compatibility case instead of rejecting otherwise valid signatures.
|
|
14968
|
-
isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(
|
|
15187
|
+
isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(controllerFirmwareVersion) && isOptionalJSONObject(lossCompensation) && isOptionalString(chargePointIdType) && isOptionalString(chargePointId)) {
|
|
14969
15188
|
const paginationPrefix = paging.length > 0 ? paging.charAt(0).toLowerCase() : null;
|
|
14970
15189
|
const transactionType = paginationPrefix === "t" ? "transaction" /* transaction */ : paginationPrefix === "f" ? "fiscal" /* fiscal */ : "undefined" /* undefined */;
|
|
14971
15190
|
const pagination = paging.length > 1 ? parseNumber(paging.substring(1)) : null;
|
|
@@ -14997,11 +15216,22 @@ var OCMF = class {
|
|
|
14997
15216
|
"@id": identificationData ?? "?",
|
|
14998
15217
|
"type": identificationType ?? "?"
|
|
14999
15218
|
},
|
|
15219
|
+
"chargingTariffs": chargingTariff !== void 0 ? [chargingTariff] : void 0,
|
|
15000
15220
|
"ocmf": {
|
|
15001
15221
|
"formatVersion": formatVersion,
|
|
15002
15222
|
"gatewayInformation": gatewayInformation,
|
|
15003
15223
|
"gatewaySerial": gatewaySerial,
|
|
15004
|
-
"gatewayVersion": gatewayVersion
|
|
15224
|
+
"gatewayVersion": gatewayVersion,
|
|
15225
|
+
"meterVendor": meterVendor,
|
|
15226
|
+
"meterModel": meterModel,
|
|
15227
|
+
"meterSerial": meterSerial,
|
|
15228
|
+
"meterFirmware": meterFirmware,
|
|
15229
|
+
"tariffText": tariffText,
|
|
15230
|
+
"tariffTextInterpretation": tariffTextInterpretation,
|
|
15231
|
+
"controllerFirmwareVersion": controllerFirmwareVersion,
|
|
15232
|
+
"lossCompensation": lossCompensation,
|
|
15233
|
+
"chargePointIdentificationType": chargePointIdType,
|
|
15234
|
+
"chargePointIdentification": chargePointId
|
|
15005
15235
|
},
|
|
15006
15236
|
// "chargingStationOperators": [{
|
|
15007
15237
|
// "chargingPools": [{
|
|
@@ -15068,6 +15298,11 @@ var OCMF = class {
|
|
|
15068
15298
|
"@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
|
|
15069
15299
|
"begin": "?",
|
|
15070
15300
|
"end": "?",
|
|
15301
|
+
"chargingStationId": signedChargingStationId,
|
|
15302
|
+
"EVSEId": signedEVSEId,
|
|
15303
|
+
"ConnectorId": signedConnectorId,
|
|
15304
|
+
"tariffId": chargingTariff?.["@id"],
|
|
15305
|
+
"chargingTariffs": chargingTariff !== void 0 ? [chargingTariff] : void 0,
|
|
15071
15306
|
"authorizationStart": {
|
|
15072
15307
|
"@id": identificationData ?? "?",
|
|
15073
15308
|
"type": identificationType ?? "?",
|
|
@@ -15080,19 +15315,50 @@ var OCMF = class {
|
|
|
15080
15315
|
}],
|
|
15081
15316
|
"certainty": 1
|
|
15082
15317
|
};
|
|
15083
|
-
|
|
15318
|
+
const resolvedChargingStationId = signedChargingStationId ?? containerChargingStation?.["@id"];
|
|
15319
|
+
if (resolvedChargingStationId !== void 0) {
|
|
15320
|
+
const matchingContainerStation = containerChargingStation?.["@id"] === resolvedChargingStationId ? containerChargingStation : void 0;
|
|
15321
|
+
const resolvedChargingStation = {
|
|
15322
|
+
...matchingContainerStation ?? { "@id": resolvedChargingStationId },
|
|
15323
|
+
...controllerFirmwareVersion !== void 0 ? {
|
|
15324
|
+
firmware: {
|
|
15325
|
+
...matchingContainerStation?.firmware,
|
|
15326
|
+
version: controllerFirmwareVersion
|
|
15327
|
+
}
|
|
15328
|
+
} : {}
|
|
15329
|
+
};
|
|
15330
|
+
CTR.chargingStations = [
|
|
15331
|
+
resolvedChargingStation,
|
|
15332
|
+
...ContainerInfos?.chargingStations?.filter((station) => station["@id"] !== resolvedChargingStationId) ?? []
|
|
15333
|
+
];
|
|
15334
|
+
if (CTR.chargingSessions?.[0] !== void 0) {
|
|
15335
|
+
CTR.chargingSessions[0].chargingStationId ??= resolvedChargingStationId;
|
|
15336
|
+
CTR.chargingSessions[0].chargingStation = resolvedChargingStation;
|
|
15337
|
+
}
|
|
15338
|
+
} else if (ContainerInfos?.chargingStations !== void 0)
|
|
15084
15339
|
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
15085
|
-
if (containerChargingStation !== void 0 && CTR.chargingSessions?.[0] !== void 0) {
|
|
15086
|
-
CTR.chargingSessions[0].chargingStationId = containerChargingStation["@id"];
|
|
15087
|
-
CTR.chargingSessions[0].chargingStation = containerChargingStation;
|
|
15088
|
-
}
|
|
15089
15340
|
if (containerEVSE !== void 0 && CTR.chargingSessions?.[0] !== void 0) {
|
|
15090
|
-
CTR.chargingSessions[0]
|
|
15091
|
-
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
|
|
15341
|
+
const chargingSession = CTR.chargingSessions[0];
|
|
15342
|
+
chargingSession.EVSEId ??= containerEVSE["@id"];
|
|
15343
|
+
if (chargingSession.EVSEId === containerEVSE["@id"])
|
|
15344
|
+
chargingSession.EVSE = containerEVSE;
|
|
15345
|
+
}
|
|
15346
|
+
const resolvedConnectorId = signedConnectorId ?? containerConnector?.["@id"];
|
|
15347
|
+
if ((resolvedConnectorId !== void 0 || signedCable !== void 0) && CTR.chargingSessions?.[0] !== void 0) {
|
|
15348
|
+
const matchingContainerConnector = containerConnector?.["@id"] === resolvedConnectorId ? containerConnector : void 0;
|
|
15349
|
+
const resolvedConnector = {
|
|
15350
|
+
...matchingContainerConnector,
|
|
15351
|
+
...resolvedConnectorId !== void 0 ? { "@id": resolvedConnectorId } : {},
|
|
15352
|
+
...signedCable !== void 0 ? {
|
|
15353
|
+
cable: {
|
|
15354
|
+
...matchingContainerConnector?.cable,
|
|
15355
|
+
...signedCable
|
|
15356
|
+
}
|
|
15357
|
+
} : {}
|
|
15358
|
+
};
|
|
15359
|
+
const chargingSession = CTR.chargingSessions[0];
|
|
15360
|
+
chargingSession.ConnectorId ??= resolvedConnectorId;
|
|
15361
|
+
chargingSession.Connector = resolvedConnector;
|
|
15096
15362
|
}
|
|
15097
15363
|
const measurementsByKey = /* @__PURE__ */ new Map();
|
|
15098
15364
|
for (const ocmfJSONDocument of OCMFJSONDocuments) {
|
|
@@ -15106,12 +15372,13 @@ var OCMF = class {
|
|
|
15106
15372
|
const readingUnit = effectiveReading.RU;
|
|
15107
15373
|
const readingCurrentType = effectiveReading.RT;
|
|
15108
15374
|
const cumulatedLoss = effectiveReading.CL;
|
|
15375
|
+
const errorIndex = effectiveReading.EI;
|
|
15109
15376
|
const errorFlags = effectiveReading.EF;
|
|
15110
15377
|
const status = effectiveReading.ST;
|
|
15111
15378
|
inheritedReading = effectiveReading;
|
|
15112
15379
|
if (isMandatoryString(time) && isOptionalString(transaction) && isMandatoryDecimal(readingValue) && // Note: Some vendors use a JSON string here!
|
|
15113
15380
|
isOptionalString(readingIdentification) && isMandatoryString(readingUnit) && isOptionalString(readingCurrentType) && // chargyLib.isOptionalDecimal (cumulatedLoss) &&
|
|
15114
|
-
isOptionalString(errorFlags) && isMandatoryString(status)) {
|
|
15381
|
+
isOptionalNumber(errorIndex) && isOptionalString(errorFlags) && isMandatoryString(status)) {
|
|
15115
15382
|
const timeSplit = time.split(" ");
|
|
15116
15383
|
if (timeSplit.length != 2) return {
|
|
15117
15384
|
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
@@ -15210,6 +15477,7 @@ var OCMF = class {
|
|
|
15210
15477
|
// "T" ToDo: Serialize this to a string!
|
|
15211
15478
|
"pagination": pagination,
|
|
15212
15479
|
// "9289"
|
|
15480
|
+
"errorIndex": errorIndex,
|
|
15213
15481
|
"errorFlags": errorFlags,
|
|
15214
15482
|
// ""
|
|
15215
15483
|
"cumulatedLoss": cumulatedLoss != null && cumulatedLoss !== 0 ? new Decimal(cumulatedLoss) : void 0,
|
|
@@ -15219,17 +15487,17 @@ var OCMF = class {
|
|
|
15219
15487
|
// "value": ocmfJSONDocument.signature["SD"]
|
|
15220
15488
|
// }],
|
|
15221
15489
|
"result": {
|
|
15222
|
-
"status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated
|
|
15490
|
+
"status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated */,
|
|
15491
|
+
// Surface the per-document verification diagnostics on the measurement value.
|
|
15492
|
+
...ocmfJSONDocument.validationErrors && ocmfJSONDocument.validationErrors.length > 0 ? { errors: ocmfJSONDocument.validationErrors } : {}
|
|
15223
15493
|
},
|
|
15224
15494
|
"ocmfDocument": ocmfJSONDocument
|
|
15225
15495
|
});
|
|
15226
15496
|
}
|
|
15227
15497
|
}
|
|
15228
15498
|
}
|
|
15229
|
-
if (ContainerInfos?.chargingStations !== void 0)
|
|
15230
|
-
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
15231
15499
|
if (ContainerInfos?.warnings !== void 0)
|
|
15232
|
-
CTR.warnings =
|
|
15500
|
+
CTR.warnings = (CTR.warnings ?? []).concat(ContainerInfos.warnings);
|
|
15233
15501
|
CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
|
|
15234
15502
|
if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
|
|
15235
15503
|
CTR.begin = CTR.chargingSessions[0].begin;
|
|
@@ -15366,6 +15634,20 @@ var OCMF = class {
|
|
|
15366
15634
|
// return mergedCTR;
|
|
15367
15635
|
// }
|
|
15368
15636
|
// //#endregion
|
|
15637
|
+
// Records why a verification step failed as structured data: a stable reason
|
|
15638
|
+
// key (localized via i18n.json and machine-switchable by the GUI) plus an
|
|
15639
|
+
// optional, language-neutral technical detail. Presentation is left to the GUI.
|
|
15640
|
+
AddValidationError(OCMFJSONDocument, reasonKey, detail) {
|
|
15641
|
+
const details = detail instanceof Error ? detail.message : typeof detail === "string" ? detail : void 0;
|
|
15642
|
+
(OCMFJSONDocument.validationErrors ??= []).push(
|
|
15643
|
+
CreateError(
|
|
15644
|
+
this.chargy.GetMultilanguageText(reasonKey),
|
|
15645
|
+
"high" /* high */,
|
|
15646
|
+
reasonKey,
|
|
15647
|
+
details
|
|
15648
|
+
)
|
|
15649
|
+
);
|
|
15650
|
+
}
|
|
15369
15651
|
//#region (private) validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding?)
|
|
15370
15652
|
async validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding) {
|
|
15371
15653
|
try {
|
|
@@ -15405,7 +15687,8 @@ var OCMF = class {
|
|
|
15405
15687
|
curve = new this.chargy.elliptic.ec("p256");
|
|
15406
15688
|
break;
|
|
15407
15689
|
}
|
|
15408
|
-
} catch {
|
|
15690
|
+
} catch (exception) {
|
|
15691
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_UnknownSignatureFormat", exception);
|
|
15409
15692
|
OCMFJSONDocument.validationStatus = "UnknownSignatureFormat" /* UnknownSignatureFormat */;
|
|
15410
15693
|
return OCMFJSONDocument.validationStatus;
|
|
15411
15694
|
}
|
|
@@ -15482,20 +15765,26 @@ var OCMF = class {
|
|
|
15482
15765
|
y: OCMFJSONDocument.publicKey.y
|
|
15483
15766
|
}, "hex");
|
|
15484
15767
|
}
|
|
15485
|
-
} catch {
|
|
15768
|
+
} catch (exception) {
|
|
15769
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_PublicKeyDecodingFailed", exception);
|
|
15486
15770
|
OCMFJSONDocument.validationStatus = "InvalidPublicKey" /* InvalidPublicKey */;
|
|
15487
15771
|
return OCMFJSONDocument.validationStatus;
|
|
15488
15772
|
}
|
|
15489
15773
|
try {
|
|
15490
15774
|
if (publicKey === null)
|
|
15491
15775
|
throw new Error("Missing public key!");
|
|
15492
|
-
|
|
15776
|
+
const signatureValid = publicKey.verify(OCMFJSONDocument.hashValue, OCMFJSONDocument.signatureRS);
|
|
15777
|
+
if (!signatureValid)
|
|
15778
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_SignatureMismatch");
|
|
15779
|
+
OCMFJSONDocument.validationStatus = signatureValid ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
|
|
15493
15780
|
return await Promise.resolve(OCMFJSONDocument.validationStatus);
|
|
15494
|
-
} catch {
|
|
15781
|
+
} catch (exception) {
|
|
15782
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_SignatureMalformed", exception);
|
|
15495
15783
|
OCMFJSONDocument.validationStatus = "InvalidSignature" /* InvalidSignature */;
|
|
15496
15784
|
return OCMFJSONDocument.validationStatus;
|
|
15497
15785
|
}
|
|
15498
|
-
} catch {
|
|
15786
|
+
} catch (exception) {
|
|
15787
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_UnexpectedError", exception);
|
|
15499
15788
|
OCMFJSONDocument.validationStatus = "InvalidSignature" /* InvalidSignature */;
|
|
15500
15789
|
return OCMFJSONDocument.validationStatus;
|
|
15501
15790
|
}
|
|
@@ -15724,6 +16013,11 @@ var OCMF = class {
|
|
|
15724
16013
|
}
|
|
15725
16014
|
if (ocmfJSONDocumentGroup[0]) {
|
|
15726
16015
|
switch (ocmfJSONDocumentGroup[0].payload.FV) {
|
|
16016
|
+
// FV has cardinality 0..1 in OCMF. All supported 1.x
|
|
16017
|
+
// versions use the same parser, so an omitted version
|
|
16018
|
+
// is parsed as generic OCMF without changing the
|
|
16019
|
+
// signed payload or inventing a concrete version.
|
|
16020
|
+
case void 0:
|
|
15727
16021
|
case "0.1":
|
|
15728
16022
|
// OCMF 0.1 SAFE reference data uses a few legacy field names/forms (VI/VV,
|
|
15729
16023
|
// string based IS values), but the compact signed document structure is close
|
|
@@ -16745,6 +17039,184 @@ function readDERInteger(bytes, getOffset, setOffset) {
|
|
|
16745
17039
|
return hex;
|
|
16746
17040
|
}
|
|
16747
17041
|
|
|
17042
|
+
// src/PTBContainer.ts
|
|
17043
|
+
var base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
17044
|
+
var formatVersionRegExp = /^1(?:\.[0-9]+)?$/;
|
|
17045
|
+
var PTB = class {
|
|
17046
|
+
chargy;
|
|
17047
|
+
constructor(chargy) {
|
|
17048
|
+
this.chargy = chargy;
|
|
17049
|
+
}
|
|
17050
|
+
async TryToParsePTBContainer(container) {
|
|
17051
|
+
const validation = this.validateContainer(container);
|
|
17052
|
+
if (!validation.valid)
|
|
17053
|
+
return this.validationError(validation.issues);
|
|
17054
|
+
const ptbContainer = validation.container;
|
|
17055
|
+
const containerInfos = {
|
|
17056
|
+
chargingStations: [{
|
|
17057
|
+
"@id": ptbContainer.chargeboxIdentifier,
|
|
17058
|
+
address: this.normalizeAddress(ptbContainer.address),
|
|
17059
|
+
geoLocation: {
|
|
17060
|
+
lat: ptbContainer.geoLocation.lat,
|
|
17061
|
+
lng: ptbContainer.geoLocation.lng
|
|
17062
|
+
},
|
|
17063
|
+
EVSEs: [{
|
|
17064
|
+
"@id": ptbContainer.chargeboxIdentifier
|
|
17065
|
+
}]
|
|
17066
|
+
}]
|
|
17067
|
+
};
|
|
17068
|
+
return new OCMF(this.chargy).TryToParseOCMFDocuments(
|
|
17069
|
+
[ptbContainer.ocmfBegin, ptbContainer.ocmfEnd],
|
|
17070
|
+
ptbContainer.publicKey,
|
|
17071
|
+
"base64",
|
|
17072
|
+
containerInfos
|
|
17073
|
+
);
|
|
17074
|
+
}
|
|
17075
|
+
validateContainer(container) {
|
|
17076
|
+
const issues = [];
|
|
17077
|
+
if (!isMandatoryJSONObject(container))
|
|
17078
|
+
return {
|
|
17079
|
+
valid: false,
|
|
17080
|
+
issues: [{
|
|
17081
|
+
path: "$",
|
|
17082
|
+
message: "must be an object"
|
|
17083
|
+
}]
|
|
17084
|
+
};
|
|
17085
|
+
this.requireConstantString(container, "format", "ptb", issues);
|
|
17086
|
+
this.requireString(container, "publicKey", issues);
|
|
17087
|
+
this.requireString(container, "chargeboxIdentifier", issues);
|
|
17088
|
+
this.requireString(container, "ocmfBegin", issues);
|
|
17089
|
+
this.requireString(container, "ocmfEnd", issues);
|
|
17090
|
+
const formatVersion = container["formatVersion"];
|
|
17091
|
+
if (formatVersion !== void 0 && (typeof formatVersion !== "string" || !formatVersionRegExp.test(formatVersion))) {
|
|
17092
|
+
issues.push({
|
|
17093
|
+
path: "$.formatVersion",
|
|
17094
|
+
message: "must match ^1(?:\\.[0-9]+)?$"
|
|
17095
|
+
});
|
|
17096
|
+
}
|
|
17097
|
+
const publicKey = container["publicKey"];
|
|
17098
|
+
if (typeof publicKey === "string" && publicKey.length > 0 && !base64RegExp.test(publicKey))
|
|
17099
|
+
issues.push({
|
|
17100
|
+
path: "$.publicKey",
|
|
17101
|
+
message: "must be a base64 encoded string"
|
|
17102
|
+
});
|
|
17103
|
+
for (const propertyName of ["ocmfBegin", "ocmfEnd"]) {
|
|
17104
|
+
const ocmfDocument = container[propertyName];
|
|
17105
|
+
if (typeof ocmfDocument === "string" && (ocmfDocument.length < 10 || !ocmfDocument.startsWith("OCMF|"))) {
|
|
17106
|
+
issues.push({
|
|
17107
|
+
path: "$." + propertyName,
|
|
17108
|
+
message: "must be an unmodified OCMF record beginning with OCMF|"
|
|
17109
|
+
});
|
|
17110
|
+
}
|
|
17111
|
+
}
|
|
17112
|
+
const address = container["address"];
|
|
17113
|
+
if (!isMandatoryJSONObject(address))
|
|
17114
|
+
issues.push({
|
|
17115
|
+
path: "$.address",
|
|
17116
|
+
message: "must be an object"
|
|
17117
|
+
});
|
|
17118
|
+
else
|
|
17119
|
+
this.validateAddress(address, issues);
|
|
17120
|
+
const geoLocation = container["geoLocation"];
|
|
17121
|
+
if (!isMandatoryJSONObject(geoLocation))
|
|
17122
|
+
issues.push({
|
|
17123
|
+
path: "$.geoLocation",
|
|
17124
|
+
message: "must be an object"
|
|
17125
|
+
});
|
|
17126
|
+
else
|
|
17127
|
+
this.validateGeoLocation(geoLocation, issues);
|
|
17128
|
+
if (issues.length > 0)
|
|
17129
|
+
return {
|
|
17130
|
+
valid: false,
|
|
17131
|
+
issues
|
|
17132
|
+
};
|
|
17133
|
+
return {
|
|
17134
|
+
valid: true,
|
|
17135
|
+
container
|
|
17136
|
+
};
|
|
17137
|
+
}
|
|
17138
|
+
validateAddress(address, issues) {
|
|
17139
|
+
this.requireString(address, "street", issues, "$.address");
|
|
17140
|
+
for (const propertyName of ["houseNumber", "zipCode", "postalCode", "town", "city", "country"]) {
|
|
17141
|
+
const propertyValue = address[propertyName];
|
|
17142
|
+
if (propertyValue !== void 0 && typeof propertyValue !== "string")
|
|
17143
|
+
issues.push({
|
|
17144
|
+
path: "$.address." + propertyName,
|
|
17145
|
+
message: "must be a string"
|
|
17146
|
+
});
|
|
17147
|
+
else if ((propertyName === "town" || propertyName === "city") && propertyValue === "")
|
|
17148
|
+
issues.push({
|
|
17149
|
+
path: "$.address." + propertyName,
|
|
17150
|
+
message: "must be a non-empty string"
|
|
17151
|
+
});
|
|
17152
|
+
}
|
|
17153
|
+
const town = address["town"];
|
|
17154
|
+
const city = address["city"];
|
|
17155
|
+
if ((typeof town !== "string" || town.length === 0) && (typeof city !== "string" || city.length === 0)) {
|
|
17156
|
+
issues.push({
|
|
17157
|
+
path: "$.address",
|
|
17158
|
+
message: "must contain a non-empty town or city"
|
|
17159
|
+
});
|
|
17160
|
+
}
|
|
17161
|
+
}
|
|
17162
|
+
validateGeoLocation(geoLocation, issues) {
|
|
17163
|
+
const latitude = geoLocation["lat"];
|
|
17164
|
+
const longitude = geoLocation["lng"];
|
|
17165
|
+
if (typeof latitude !== "number" || !Number.isFinite(latitude) || latitude < -90 || latitude > 90)
|
|
17166
|
+
issues.push({
|
|
17167
|
+
path: "$.geoLocation.lat",
|
|
17168
|
+
message: "must be a number between -90 and 90"
|
|
17169
|
+
});
|
|
17170
|
+
if (typeof longitude !== "number" || !Number.isFinite(longitude) || longitude < -180 || longitude > 180)
|
|
17171
|
+
issues.push({
|
|
17172
|
+
path: "$.geoLocation.lng",
|
|
17173
|
+
message: "must be a number between -180 and 180"
|
|
17174
|
+
});
|
|
17175
|
+
for (const propertyName of Object.keys(geoLocation))
|
|
17176
|
+
if (propertyName !== "lat" && propertyName !== "lng")
|
|
17177
|
+
issues.push({
|
|
17178
|
+
path: "$.geoLocation." + propertyName,
|
|
17179
|
+
message: "is not allowed"
|
|
17180
|
+
});
|
|
17181
|
+
}
|
|
17182
|
+
requireString(json, propertyName, issues, parentPath = "$") {
|
|
17183
|
+
const value = json[propertyName];
|
|
17184
|
+
if (typeof value !== "string" || value.length === 0)
|
|
17185
|
+
issues.push({
|
|
17186
|
+
path: parentPath + "." + propertyName,
|
|
17187
|
+
message: "must be a non-empty string"
|
|
17188
|
+
});
|
|
17189
|
+
}
|
|
17190
|
+
requireConstantString(json, propertyName, expectedValue, issues) {
|
|
17191
|
+
if (json[propertyName] !== expectedValue)
|
|
17192
|
+
issues.push({
|
|
17193
|
+
path: "$." + propertyName,
|
|
17194
|
+
message: "must equal " + expectedValue
|
|
17195
|
+
});
|
|
17196
|
+
}
|
|
17197
|
+
normalizeAddress(address) {
|
|
17198
|
+
return {
|
|
17199
|
+
city: address.city ?? address.town,
|
|
17200
|
+
street: address.street,
|
|
17201
|
+
houseNumber: address.houseNumber,
|
|
17202
|
+
postalCode: address.postalCode ?? address.zipCode,
|
|
17203
|
+
country: address.country
|
|
17204
|
+
};
|
|
17205
|
+
}
|
|
17206
|
+
validationError(issues) {
|
|
17207
|
+
return {
|
|
17208
|
+
format: "ptb",
|
|
17209
|
+
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
17210
|
+
message: this.chargy.GetMultilanguageText("Invalid PTB OCMF container!"),
|
|
17211
|
+
certainty: 1,
|
|
17212
|
+
issues,
|
|
17213
|
+
errors: issues.map((issue) => CreateError(
|
|
17214
|
+
this.chargy.GetMultilanguageText(issue.path + " " + issue.message)
|
|
17215
|
+
))
|
|
17216
|
+
};
|
|
17217
|
+
}
|
|
17218
|
+
};
|
|
17219
|
+
|
|
16748
17220
|
// src/SAFE_XML.ts
|
|
16749
17221
|
var SAFEXML = class _SAFEXML {
|
|
16750
17222
|
chargy;
|
|
@@ -19261,6 +19733,26 @@ var Chargy = class {
|
|
|
19261
19733
|
return textContent.replace(/\s+/g, "");
|
|
19262
19734
|
return void 0;
|
|
19263
19735
|
}
|
|
19736
|
+
TryToCreatePublicKeyLookup(processedFiles) {
|
|
19737
|
+
if (processedFiles.length === 0)
|
|
19738
|
+
return void 0;
|
|
19739
|
+
const publicKeys = new Array();
|
|
19740
|
+
for (const processedFile of processedFiles) {
|
|
19741
|
+
if (IsAChargeTransparencyRecord(processedFile.result) || IsAChargeTransparencyLiveLink(processedFile.result)) {
|
|
19742
|
+
return void 0;
|
|
19743
|
+
}
|
|
19744
|
+
if (IsAPublicKey(processedFile.result))
|
|
19745
|
+
publicKeys.push(processedFile.result);
|
|
19746
|
+
else if (IsAPublicKeyLookup(processedFile.result))
|
|
19747
|
+
publicKeys.push(...processedFile.result.publicKeys);
|
|
19748
|
+
else
|
|
19749
|
+
return void 0;
|
|
19750
|
+
}
|
|
19751
|
+
if (processedFiles.length === 1 && IsAPublicKeyLookup(processedFiles[0]?.result)) {
|
|
19752
|
+
return processedFiles[0].result;
|
|
19753
|
+
}
|
|
19754
|
+
return { publicKeys };
|
|
19755
|
+
}
|
|
19264
19756
|
//#endregion
|
|
19265
19757
|
//#region QR code image files...
|
|
19266
19758
|
normalizeMIMEType(mimeType) {
|
|
@@ -19977,7 +20469,9 @@ var Chargy = class {
|
|
|
19977
20469
|
if (IsAChargeTransparencyLiveLink(JSONContent)) {
|
|
19978
20470
|
JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
|
|
19979
20471
|
processedFile.result = JSONContent;
|
|
19980
|
-
} else if (
|
|
20472
|
+
} else if (JSONContent["format"] === "ptb")
|
|
20473
|
+
processedFile.result = await new PTB(this).TryToParsePTBContainer(JSONContent);
|
|
20474
|
+
else if (isMandatoryString(JSONContext)) {
|
|
19981
20475
|
if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
|
|
19982
20476
|
processedFile.result = JSONContent;
|
|
19983
20477
|
else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
|
|
@@ -20017,18 +20511,15 @@ var Chargy = class {
|
|
|
20017
20511
|
}
|
|
20018
20512
|
processedFiles.push(processedFile);
|
|
20019
20513
|
}
|
|
20514
|
+
const publicKeyLookup = this.TryToCreatePublicKeyLookup(processedFiles);
|
|
20515
|
+
if (publicKeyLookup != null)
|
|
20516
|
+
return publicKeyLookup;
|
|
20020
20517
|
if (processedFiles.length == 1) {
|
|
20021
20518
|
const processedFile = getFirstArrayElement(processedFiles, "Missing processed file");
|
|
20022
20519
|
if (IsAChargeTransparencyRecord(processedFile.result))
|
|
20023
20520
|
return this.processChargeTransparencyRecord(processedFile.result);
|
|
20024
20521
|
if (IsAChargeTransparencyLiveLink(processedFile.result))
|
|
20025
20522
|
return processedFile.result;
|
|
20026
|
-
if (IsAPublicKeyLookup(processedFile.result))
|
|
20027
|
-
return {
|
|
20028
|
-
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
20029
|
-
message: this.GetMultilanguageText("UnknownOrInvalidChargeTransparencyRecord"),
|
|
20030
|
-
certainty: 0
|
|
20031
|
-
};
|
|
20032
20523
|
return processedFile.result;
|
|
20033
20524
|
} else if (processedFiles.length > 1) {
|
|
20034
20525
|
const mergedCTR = {
|
|
@@ -20450,6 +20941,6 @@ buffer/index.js:
|
|
|
20450
20941
|
*)
|
|
20451
20942
|
*/
|
|
20452
20943
|
|
|
20453
|
-
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, unquotePCDFText, validatePCDFFields, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
20944
|
+
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFBonnTariffParseError, OCMFTransactionTypes, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, PTB, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, ocmfBonnTariffToChargingTariff, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parseOCMFBonnTariffText, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, tryParseOCMFBonnTariffText, unquotePCDFText, validatePCDFFields, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
20454
20945
|
//# sourceMappingURL=index.js.map
|
|
20455
20946
|
//# sourceMappingURL=index.js.map
|