@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/node/index.js
CHANGED
|
@@ -8078,11 +8078,16 @@ function CreateWarning(message, level = "low" /* low */) {
|
|
|
8078
8078
|
message
|
|
8079
8079
|
};
|
|
8080
8080
|
}
|
|
8081
|
-
function CreateError(message, level = "high" /* high
|
|
8082
|
-
|
|
8081
|
+
function CreateError(message, level = "high" /* high */, code, details) {
|
|
8082
|
+
const error = {
|
|
8083
8083
|
level,
|
|
8084
8084
|
message
|
|
8085
8085
|
};
|
|
8086
|
+
if (code !== void 0)
|
|
8087
|
+
error.code = code;
|
|
8088
|
+
if (details !== void 0)
|
|
8089
|
+
error.details = details;
|
|
8090
|
+
return error;
|
|
8086
8091
|
}
|
|
8087
8092
|
function isISessionCryptoResult1(obj) {
|
|
8088
8093
|
return isObject(obj) && obj["status"] !== void 0;
|
|
@@ -9068,6 +9073,20 @@ var ACrypt = class {
|
|
|
9068
9073
|
newText.classList.remove("overEntry");
|
|
9069
9074
|
};
|
|
9070
9075
|
}
|
|
9076
|
+
// Records why a verification step failed as structured data: a stable reason
|
|
9077
|
+
// key (localized via i18n.json and machine-switchable by the GUI) plus an
|
|
9078
|
+
// optional, language-neutral technical detail. Presentation is left to the GUI.
|
|
9079
|
+
AddVerificationError(cryptoResult, reasonKey, detail) {
|
|
9080
|
+
const details = detail instanceof Error ? detail.message : typeof detail === "string" ? detail : void 0;
|
|
9081
|
+
(cryptoResult.errors ??= []).push(
|
|
9082
|
+
CreateError(
|
|
9083
|
+
this.chargy.GetMultilanguageText(reasonKey),
|
|
9084
|
+
"high" /* high */,
|
|
9085
|
+
reasonKey,
|
|
9086
|
+
details
|
|
9087
|
+
)
|
|
9088
|
+
);
|
|
9089
|
+
}
|
|
9071
9090
|
};
|
|
9072
9091
|
var Alfen = class {
|
|
9073
9092
|
chargy;
|
|
@@ -9294,8 +9313,7 @@ var Alfen = class {
|
|
|
9294
9313
|
"connectors": [{
|
|
9295
9314
|
"type": asString(connector?.["type"]) ?? "",
|
|
9296
9315
|
"cable": {
|
|
9297
|
-
"length": asNumber(connector?.["cableLength"]) ?? 0
|
|
9298
|
-
"looses": asNumber(connector?.["cableLooses"]) ?? 0
|
|
9316
|
+
"length": asNumber(connector?.["cableLength"]) ?? 0
|
|
9299
9317
|
}
|
|
9300
9318
|
}],
|
|
9301
9319
|
"energyMeters": [
|
|
@@ -9483,9 +9501,15 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9483
9501
|
cryptoResult.publicKey = meter.publicKeys[0]?.value;
|
|
9484
9502
|
cryptoResult.publicKeyFormat = meter.publicKeys[0]?.format;
|
|
9485
9503
|
cryptoResult.publicKeySignatures = meter.publicKeys[0]?.signatures;
|
|
9504
|
+
let publicKey;
|
|
9505
|
+
try {
|
|
9506
|
+
publicKey = buf2hex(this.chargy.base32Decode(cryptoResult.publicKey ?? "", "RFC4648"));
|
|
9507
|
+
} catch (exception) {
|
|
9508
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
9509
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
9510
|
+
}
|
|
9511
|
+
let result = false;
|
|
9486
9512
|
try {
|
|
9487
|
-
const publicKey = buf2hex(this.chargy.base32Decode(cryptoResult.publicKey ?? "", "RFC4648"));
|
|
9488
|
-
let result = false;
|
|
9489
9513
|
switch (meter.publicKeys[0]?.algorithm ?? "") {
|
|
9490
9514
|
case "secp192r1":
|
|
9491
9515
|
cryptoResult.hashValue = await sha256(cryptoBuffer);
|
|
@@ -9530,25 +9554,29 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9530
9554
|
);
|
|
9531
9555
|
break;
|
|
9532
9556
|
}
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
}
|
|
9536
|
-
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
9537
|
-
} catch {
|
|
9557
|
+
} catch (exception) {
|
|
9558
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
9538
9559
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
9539
9560
|
}
|
|
9540
|
-
|
|
9561
|
+
if (result)
|
|
9562
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
9563
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
9564
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
9565
|
+
} catch (exception) {
|
|
9566
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
9541
9567
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
9542
9568
|
}
|
|
9543
9569
|
} else
|
|
9544
9570
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
9545
9571
|
} else
|
|
9546
9572
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
9547
|
-
} catch {
|
|
9573
|
+
} catch (exception) {
|
|
9574
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
9548
9575
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
9549
9576
|
}
|
|
9550
9577
|
}
|
|
9551
|
-
|
|
9578
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
9579
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
9552
9580
|
}
|
|
9553
9581
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
9554
9582
|
const result = measurementValue.result;
|
|
@@ -10387,33 +10415,46 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10387
10415
|
const publicKeyDER = ASN1_PublicKey.decode(Buffer.from(meter.publicKeys[0]?.value ?? "", "hex"), "der");
|
|
10388
10416
|
publicKey = buf2hex(publicKeyDER.publicKey.data).toLowerCase();
|
|
10389
10417
|
}
|
|
10418
|
+
let keyPair;
|
|
10390
10419
|
try {
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
)
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10420
|
+
keyPair = this.curve.keyFromPublic(publicKey, "hex");
|
|
10421
|
+
} catch (exception) {
|
|
10422
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
10423
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
10424
|
+
}
|
|
10425
|
+
const keyValidation = keyPair.validate();
|
|
10426
|
+
if (!keyValidation.result) {
|
|
10427
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
10428
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
10429
|
+
}
|
|
10430
|
+
let signatureValid;
|
|
10431
|
+
try {
|
|
10432
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
10433
|
+
} catch (exception) {
|
|
10434
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
10403
10435
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
10404
10436
|
}
|
|
10405
|
-
|
|
10437
|
+
if (measurementValue.errors && measurementValue.errors.length > 0)
|
|
10438
|
+
return setResult("ValidationError" /* ValidationError */);
|
|
10439
|
+
if (signatureValid)
|
|
10440
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
10441
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
10442
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
10443
|
+
} catch (exception) {
|
|
10444
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
10406
10445
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
10407
10446
|
}
|
|
10408
10447
|
} else
|
|
10409
10448
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
10410
10449
|
} else
|
|
10411
10450
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
10412
|
-
} catch {
|
|
10451
|
+
} catch (exception) {
|
|
10452
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
10413
10453
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
10414
10454
|
}
|
|
10415
10455
|
}
|
|
10416
|
-
|
|
10456
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
10457
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
10417
10458
|
}
|
|
10418
10459
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
10419
10460
|
if (measurementValue.measurement === void 0)
|
|
@@ -10592,35 +10633,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10592
10633
|
if ((value & 1 << 29) != 0) events.push("OEM 15");
|
|
10593
10634
|
return events;
|
|
10594
10635
|
}
|
|
10595
|
-
|
|
10596
|
-
// {
|
|
10597
|
-
// const statusArray:string[] = [];
|
|
10598
|
-
// try
|
|
10599
|
-
// {
|
|
10600
|
-
// const status = parseInt(statusValue);
|
|
10601
|
-
// if ((status & 1) == 1)
|
|
10602
|
-
// statusArray.push("Fehler erkannt");
|
|
10603
|
-
// if ((status & 2) == 2)
|
|
10604
|
-
// statusArray.push("Synchrone Messwertübermittlung");
|
|
10605
|
-
// // Bit 3 is reserved!
|
|
10606
|
-
// if ((status & 8) == 8)
|
|
10607
|
-
// statusArray.push("System-Uhr ist synchron");
|
|
10608
|
-
// else
|
|
10609
|
-
// statusArray.push("System-Uhr ist nicht synchron");
|
|
10610
|
-
// if ((status & 16) == 16)
|
|
10611
|
-
// statusArray.push("Rücklaufsperre aktiv");
|
|
10612
|
-
// if ((status & 32) == 32)
|
|
10613
|
-
// statusArray.push("Energierichtung -A");
|
|
10614
|
-
// if ((status & 64) == 64)
|
|
10615
|
-
// statusArray.push("Magnetfeld erkannt");
|
|
10616
|
-
// }
|
|
10617
|
-
// catch
|
|
10618
|
-
// {
|
|
10619
|
-
// statusArray.push("Invalid status!");
|
|
10620
|
-
// }
|
|
10621
|
-
// return statusArray;
|
|
10622
|
-
// }
|
|
10623
|
-
// //#endregion
|
|
10636
|
+
//#endregion
|
|
10624
10637
|
};
|
|
10625
10638
|
|
|
10626
10639
|
// src/interfaces/IPublicKeyInfo.ts
|
|
@@ -12079,29 +12092,44 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
12079
12092
|
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
12080
12093
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
12081
12094
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
12095
|
+
let keyPair;
|
|
12082
12096
|
try {
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
)
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12097
|
+
keyPair = this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex");
|
|
12098
|
+
} catch (exception) {
|
|
12099
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12100
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12101
|
+
}
|
|
12102
|
+
const keyValidation = keyPair.validate();
|
|
12103
|
+
if (!keyValidation.result) {
|
|
12104
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
12105
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12106
|
+
}
|
|
12107
|
+
let signatureValid;
|
|
12108
|
+
try {
|
|
12109
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
12110
|
+
} catch (exception) {
|
|
12111
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
12091
12112
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12092
12113
|
}
|
|
12093
|
-
|
|
12114
|
+
if (signatureValid)
|
|
12115
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
12116
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
12117
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12118
|
+
} catch (exception) {
|
|
12119
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12094
12120
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12095
12121
|
}
|
|
12096
12122
|
} else
|
|
12097
12123
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
12098
12124
|
} else
|
|
12099
12125
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
12100
|
-
} catch {
|
|
12126
|
+
} catch (exception) {
|
|
12127
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
12101
12128
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12102
12129
|
}
|
|
12103
12130
|
}
|
|
12104
|
-
|
|
12131
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
12132
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12105
12133
|
}
|
|
12106
12134
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
12107
12135
|
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
@@ -12209,7 +12237,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
12209
12237
|
DecodeStatus(statusValue) {
|
|
12210
12238
|
const statusArray = [];
|
|
12211
12239
|
try {
|
|
12212
|
-
const status = parseInt(statusValue);
|
|
12240
|
+
const status = parseInt(statusValue, 16);
|
|
12213
12241
|
if ((status & 1) == 1)
|
|
12214
12242
|
statusArray.push("Fehler erkannt");
|
|
12215
12243
|
if ((status & 2) == 2)
|
|
@@ -12311,29 +12339,44 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
12311
12339
|
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
12312
12340
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
12313
12341
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
12342
|
+
let keyPair;
|
|
12314
12343
|
try {
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
)
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12344
|
+
keyPair = this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex");
|
|
12345
|
+
} catch (exception) {
|
|
12346
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12347
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12348
|
+
}
|
|
12349
|
+
const keyValidation = keyPair.validate();
|
|
12350
|
+
if (!keyValidation.result) {
|
|
12351
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
12352
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12353
|
+
}
|
|
12354
|
+
let signatureValid;
|
|
12355
|
+
try {
|
|
12356
|
+
signatureValid = keyPair.verify(cryptoResult.sha256value, cryptoResult.signature);
|
|
12357
|
+
} catch (exception) {
|
|
12358
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
12323
12359
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12324
12360
|
}
|
|
12325
|
-
|
|
12361
|
+
if (signatureValid)
|
|
12362
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
12363
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
12364
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12365
|
+
} catch (exception) {
|
|
12366
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12326
12367
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12327
12368
|
}
|
|
12328
12369
|
} else
|
|
12329
12370
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
12330
12371
|
} else
|
|
12331
12372
|
return setResult("EnergyMeterNotFound" /* EnergyMeterNotFound */);
|
|
12332
|
-
} catch {
|
|
12373
|
+
} catch (exception) {
|
|
12374
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
12333
12375
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12334
12376
|
}
|
|
12335
12377
|
}
|
|
12336
|
-
|
|
12378
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMissing");
|
|
12379
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12337
12380
|
}
|
|
12338
12381
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
12339
12382
|
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
@@ -12672,19 +12715,38 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
12672
12715
|
);
|
|
12673
12716
|
cryptoResult.hashValue = (await sha256(new DataView(signedDataBuffer))).substring(0, 48);
|
|
12674
12717
|
const publicKey = cleanHex(meter.publicKeys.at(0)?.value ?? measurement.publicKey);
|
|
12675
|
-
if (publicKey.length !== 96)
|
|
12718
|
+
if (publicKey.length !== 96) {
|
|
12719
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed");
|
|
12676
12720
|
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12721
|
+
}
|
|
12722
|
+
let keyPair;
|
|
12723
|
+
try {
|
|
12724
|
+
keyPair = this.curve192r1.keyFromPublic("04" + publicKey, "hex");
|
|
12725
|
+
} catch (exception) {
|
|
12726
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyDecodingFailed", exception);
|
|
12727
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12728
|
+
}
|
|
12729
|
+
const keyValidation = keyPair.validate();
|
|
12730
|
+
if (!keyValidation.result) {
|
|
12731
|
+
this.AddVerificationError(cryptoResult, "Verification_PublicKeyNotOnCurve", keyValidation.reason ?? void 0);
|
|
12732
|
+
return setResult("InvalidPublicKey" /* InvalidPublicKey */);
|
|
12733
|
+
}
|
|
12734
|
+
let signatureValid;
|
|
12735
|
+
try {
|
|
12736
|
+
signatureValid = keyPair.verify(cryptoResult.hashValue.toUpperCase(), {
|
|
12680
12737
|
r: signatureExpected.r,
|
|
12681
12738
|
s: signatureExpected.s
|
|
12682
|
-
}
|
|
12683
|
-
)
|
|
12684
|
-
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
|
|
12739
|
+
});
|
|
12740
|
+
} catch (exception) {
|
|
12741
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMalformed", exception);
|
|
12742
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12743
|
+
}
|
|
12744
|
+
if (signatureValid)
|
|
12745
|
+
return setResult("ValidSignature" /* ValidSignature */);
|
|
12746
|
+
this.AddVerificationError(cryptoResult, "Verification_SignatureMismatch");
|
|
12747
|
+
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12748
|
+
} catch (exception) {
|
|
12749
|
+
this.AddVerificationError(cryptoResult, "Verification_UnexpectedError", exception);
|
|
12688
12750
|
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
12689
12751
|
}
|
|
12690
12752
|
}
|
|
@@ -12890,6 +12952,132 @@ function numberToBytesBE(value, length) {
|
|
|
12890
12952
|
}
|
|
12891
12953
|
return bytes;
|
|
12892
12954
|
}
|
|
12955
|
+
var OCMFBonnTariffParseError = class extends Error {
|
|
12956
|
+
tariffText;
|
|
12957
|
+
constructor(tariffText, message) {
|
|
12958
|
+
super(message);
|
|
12959
|
+
this.name = "OCMFBonnTariffParseError";
|
|
12960
|
+
this.tariffText = tariffText;
|
|
12961
|
+
}
|
|
12962
|
+
};
|
|
12963
|
+
function parseCents(value, tariffText, fieldName) {
|
|
12964
|
+
if (!/^(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(value))
|
|
12965
|
+
throw new OCMFBonnTariffParseError(tariffText, `${fieldName} must be a non-negative decimal number`);
|
|
12966
|
+
const parsedValue = Number(value);
|
|
12967
|
+
if (!Number.isFinite(parsedValue))
|
|
12968
|
+
throw new OCMFBonnTariffParseError(tariffText, `${fieldName} is outside the supported numeric range`);
|
|
12969
|
+
return parsedValue;
|
|
12970
|
+
}
|
|
12971
|
+
function parseOCMFBonnTariffText(tariffText) {
|
|
12972
|
+
const fields = tariffText.split(";");
|
|
12973
|
+
const code = fields[0];
|
|
12974
|
+
if (fields[1] !== "EUR")
|
|
12975
|
+
throw new OCMFBonnTariffParseError(tariffText, "currency must be EUR");
|
|
12976
|
+
switch (code) {
|
|
12977
|
+
case "001":
|
|
12978
|
+
if (fields.length !== 6)
|
|
12979
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 001 must contain six fields");
|
|
12980
|
+
return {
|
|
12981
|
+
raw: tariffText,
|
|
12982
|
+
code,
|
|
12983
|
+
currency: "EUR",
|
|
12984
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
12985
|
+
energyFeeCentsPerKWh: parseCents(fields[3] ?? "", tariffText, "X"),
|
|
12986
|
+
blockingFeeCentsPerMinute: parseCents(fields[4] ?? "", tariffText, "Y"),
|
|
12987
|
+
blockingFeeStartMinute: parseCents(fields[5] ?? "", tariffText, "Z")
|
|
12988
|
+
};
|
|
12989
|
+
case "002":
|
|
12990
|
+
if (fields.length !== 5)
|
|
12991
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 002 must contain five fields");
|
|
12992
|
+
return {
|
|
12993
|
+
raw: tariffText,
|
|
12994
|
+
code,
|
|
12995
|
+
currency: "EUR",
|
|
12996
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
12997
|
+
energyFeeCentsPerKWh: parseCents(fields[3] ?? "", tariffText, "X"),
|
|
12998
|
+
blockingFeeCentsPerMinute: parseCents(fields[4] ?? "", tariffText, "Y"),
|
|
12999
|
+
blockingFeeStartsAfterCharging: true
|
|
13000
|
+
};
|
|
13001
|
+
case "003":
|
|
13002
|
+
if (fields.length !== 4)
|
|
13003
|
+
throw new OCMFBonnTariffParseError(tariffText, "profile 003 must contain four fields");
|
|
13004
|
+
return {
|
|
13005
|
+
raw: tariffText,
|
|
13006
|
+
code,
|
|
13007
|
+
currency: "EUR",
|
|
13008
|
+
startFeeCents: parseCents(fields[2] ?? "", tariffText, "W"),
|
|
13009
|
+
timeFeeCentsPerMinute: parseCents(fields[3] ?? "", tariffText, "X")
|
|
13010
|
+
};
|
|
13011
|
+
default:
|
|
13012
|
+
throw new OCMFBonnTariffParseError(tariffText, "unknown Bonn tariff profile");
|
|
13013
|
+
}
|
|
13014
|
+
}
|
|
13015
|
+
function tryParseOCMFBonnTariffText(tariffText) {
|
|
13016
|
+
try {
|
|
13017
|
+
return parseOCMFBonnTariffText(tariffText);
|
|
13018
|
+
} catch (error) {
|
|
13019
|
+
if (error instanceof OCMFBonnTariffParseError)
|
|
13020
|
+
return void 0;
|
|
13021
|
+
throw error;
|
|
13022
|
+
}
|
|
13023
|
+
}
|
|
13024
|
+
function priceComponent(type, price, stepSize) {
|
|
13025
|
+
return {
|
|
13026
|
+
type,
|
|
13027
|
+
price,
|
|
13028
|
+
step_size: stepSize
|
|
13029
|
+
};
|
|
13030
|
+
}
|
|
13031
|
+
function eurosFromCents(cents) {
|
|
13032
|
+
return new Decimal(cents).dividedBy(100);
|
|
13033
|
+
}
|
|
13034
|
+
function eurosPerHourFromCentsPerMinute(cents) {
|
|
13035
|
+
return eurosFromCents(cents).times(60);
|
|
13036
|
+
}
|
|
13037
|
+
function ocmfBonnTariffToChargingTariff(tariff) {
|
|
13038
|
+
const baseComponents = new Array(
|
|
13039
|
+
priceComponent("FLAT", eurosFromCents(tariff.startFeeCents), 1)
|
|
13040
|
+
);
|
|
13041
|
+
const elements = new Array();
|
|
13042
|
+
switch (tariff.code) {
|
|
13043
|
+
case "001":
|
|
13044
|
+
baseComponents.push(priceComponent("ENERGY", eurosFromCents(tariff.energyFeeCentsPerKWh), 1));
|
|
13045
|
+
elements.push(
|
|
13046
|
+
{ price_components: baseComponents },
|
|
13047
|
+
{
|
|
13048
|
+
price_components: [
|
|
13049
|
+
priceComponent("PARKING_TIME", eurosPerHourFromCentsPerMinute(tariff.blockingFeeCentsPerMinute), 60)
|
|
13050
|
+
],
|
|
13051
|
+
restrictions: {
|
|
13052
|
+
min_duration: tariff.blockingFeeStartMinute * 60
|
|
13053
|
+
}
|
|
13054
|
+
}
|
|
13055
|
+
);
|
|
13056
|
+
break;
|
|
13057
|
+
case "002":
|
|
13058
|
+
baseComponents.push(priceComponent("ENERGY", eurosFromCents(tariff.energyFeeCentsPerKWh), 1));
|
|
13059
|
+
elements.push(
|
|
13060
|
+
{ price_components: baseComponents },
|
|
13061
|
+
{
|
|
13062
|
+
price_components: [
|
|
13063
|
+
priceComponent("PARKING_TIME", eurosPerHourFromCentsPerMinute(tariff.blockingFeeCentsPerMinute), 60)
|
|
13064
|
+
]
|
|
13065
|
+
}
|
|
13066
|
+
);
|
|
13067
|
+
break;
|
|
13068
|
+
case "003":
|
|
13069
|
+
baseComponents.push(priceComponent("TIME", eurosPerHourFromCentsPerMinute(tariff.timeFeeCentsPerMinute), 60));
|
|
13070
|
+
elements.push({ price_components: baseComponents });
|
|
13071
|
+
break;
|
|
13072
|
+
}
|
|
13073
|
+
return {
|
|
13074
|
+
"@id": tariff.raw,
|
|
13075
|
+
currency: tariff.currency,
|
|
13076
|
+
elements
|
|
13077
|
+
};
|
|
13078
|
+
}
|
|
13079
|
+
|
|
13080
|
+
// src/OCMF.ts
|
|
12893
13081
|
var OCMFv1_x = class extends ACrypt {
|
|
12894
13082
|
curve = new this.chargy.elliptic.ec("p256");
|
|
12895
13083
|
constructor(chargy) {
|
|
@@ -12979,6 +13167,8 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
12979
13167
|
return "Reading Current Type";
|
|
12980
13168
|
case "CL":
|
|
12981
13169
|
return "Cumulated Loss";
|
|
13170
|
+
case "EI":
|
|
13171
|
+
return "Error Index";
|
|
12982
13172
|
case "EF":
|
|
12983
13173
|
return "Error Flags";
|
|
12984
13174
|
case "ST":
|
|
@@ -13186,10 +13376,39 @@ var OCMF = class {
|
|
|
13186
13376
|
const identificationType = firstOCMDJSONDocument.payload.IT;
|
|
13187
13377
|
const identificationData = firstOCMDJSONDocument.payload.ID;
|
|
13188
13378
|
const tariffText = firstOCMDJSONDocument.payload.TT;
|
|
13189
|
-
const
|
|
13379
|
+
const tariffTextInterpretation = typeof tariffText === "string" ? tryParseOCMFBonnTariffText(tariffText) : void 0;
|
|
13380
|
+
const chargingTariff = typeof tariffText === "string" && tariffText.length > 0 ? tariffTextInterpretation !== void 0 ? ocmfBonnTariffToChargingTariff(tariffTextInterpretation) : { "@id": tariffText } : void 0;
|
|
13381
|
+
const controllerFirmwareVersion = firstOCMDJSONDocument.payload.CF;
|
|
13190
13382
|
const lossCompensation = firstOCMDJSONDocument.payload.LC;
|
|
13383
|
+
const signedCable = lossCompensation !== void 0 && typeof lossCompensation.LR === "number" && Number.isFinite(lossCompensation.LR) && typeof lossCompensation.LU === "string" && lossCompensation.LU.length > 0 ? {
|
|
13384
|
+
...typeof lossCompensation.LN === "string" ? { lossCompensation: lossCompensation.LN } : {},
|
|
13385
|
+
...typeof lossCompensation.LI === "number" ? { lossCompensationId: lossCompensation.LI.toString() } : {},
|
|
13386
|
+
resistance: lossCompensation.LR,
|
|
13387
|
+
resistanceUnit: lossCompensation.LU
|
|
13388
|
+
} : void 0;
|
|
13191
13389
|
const chargePointIdType = firstOCMDJSONDocument.payload.CT;
|
|
13192
13390
|
const chargePointId = firstOCMDJSONDocument.payload.CI;
|
|
13391
|
+
let signedChargingStationId;
|
|
13392
|
+
let signedEVSEId;
|
|
13393
|
+
let signedConnectorId;
|
|
13394
|
+
if (typeof chargePointId === "string" && chargePointId.trim().length > 0) {
|
|
13395
|
+
const normalizedChargePointId = chargePointId.trim();
|
|
13396
|
+
switch (chargePointIdType?.toUpperCase()) {
|
|
13397
|
+
case void 0:
|
|
13398
|
+
break;
|
|
13399
|
+
case "EVSEID":
|
|
13400
|
+
signedEVSEId = normalizedChargePointId;
|
|
13401
|
+
break;
|
|
13402
|
+
case "CBIDC": {
|
|
13403
|
+
const cbidcMatch = /^(\S+)\s+(\S+)$/.exec(normalizedChargePointId);
|
|
13404
|
+
if (cbidcMatch?.[1] !== void 0 && cbidcMatch[2] !== void 0) {
|
|
13405
|
+
signedChargingStationId = cbidcMatch[1];
|
|
13406
|
+
signedConnectorId = cbidcMatch[2];
|
|
13407
|
+
}
|
|
13408
|
+
break;
|
|
13409
|
+
}
|
|
13410
|
+
}
|
|
13411
|
+
}
|
|
13193
13412
|
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,
|
|
13194
13413
|
// Charge Point and Public Key" section makes the serial-number fields conditionally
|
|
13195
13414
|
// mandatory. KEBA KCP30 records identify the signing gateway via GS and omit MS.
|
|
@@ -13202,7 +13421,7 @@ var OCMF = class {
|
|
|
13202
13421
|
// IT is 1..1 in the user-assignment table for transaction records. Some OCMF 1.0
|
|
13203
13422
|
// implementations omit it when no user is assigned (IS=false, ID empty). We tolerate
|
|
13204
13423
|
// this vendor compatibility case instead of rejecting otherwise valid signatures.
|
|
13205
|
-
isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(
|
|
13424
|
+
isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(controllerFirmwareVersion) && isOptionalJSONObject(lossCompensation) && isOptionalString(chargePointIdType) && isOptionalString(chargePointId)) {
|
|
13206
13425
|
const paginationPrefix = paging.length > 0 ? paging.charAt(0).toLowerCase() : null;
|
|
13207
13426
|
const transactionType = paginationPrefix === "t" ? "transaction" /* transaction */ : paginationPrefix === "f" ? "fiscal" /* fiscal */ : "undefined" /* undefined */;
|
|
13208
13427
|
const pagination = paging.length > 1 ? parseNumber(paging.substring(1)) : null;
|
|
@@ -13234,11 +13453,22 @@ var OCMF = class {
|
|
|
13234
13453
|
"@id": identificationData ?? "?",
|
|
13235
13454
|
"type": identificationType ?? "?"
|
|
13236
13455
|
},
|
|
13456
|
+
"chargingTariffs": chargingTariff !== void 0 ? [chargingTariff] : void 0,
|
|
13237
13457
|
"ocmf": {
|
|
13238
13458
|
"formatVersion": formatVersion,
|
|
13239
13459
|
"gatewayInformation": gatewayInformation,
|
|
13240
13460
|
"gatewaySerial": gatewaySerial,
|
|
13241
|
-
"gatewayVersion": gatewayVersion
|
|
13461
|
+
"gatewayVersion": gatewayVersion,
|
|
13462
|
+
"meterVendor": meterVendor,
|
|
13463
|
+
"meterModel": meterModel,
|
|
13464
|
+
"meterSerial": meterSerial,
|
|
13465
|
+
"meterFirmware": meterFirmware,
|
|
13466
|
+
"tariffText": tariffText,
|
|
13467
|
+
"tariffTextInterpretation": tariffTextInterpretation,
|
|
13468
|
+
"controllerFirmwareVersion": controllerFirmwareVersion,
|
|
13469
|
+
"lossCompensation": lossCompensation,
|
|
13470
|
+
"chargePointIdentificationType": chargePointIdType,
|
|
13471
|
+
"chargePointIdentification": chargePointId
|
|
13242
13472
|
},
|
|
13243
13473
|
// "chargingStationOperators": [{
|
|
13244
13474
|
// "chargingPools": [{
|
|
@@ -13305,6 +13535,11 @@ var OCMF = class {
|
|
|
13305
13535
|
"@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
|
|
13306
13536
|
"begin": "?",
|
|
13307
13537
|
"end": "?",
|
|
13538
|
+
"chargingStationId": signedChargingStationId,
|
|
13539
|
+
"EVSEId": signedEVSEId,
|
|
13540
|
+
"ConnectorId": signedConnectorId,
|
|
13541
|
+
"tariffId": chargingTariff?.["@id"],
|
|
13542
|
+
"chargingTariffs": chargingTariff !== void 0 ? [chargingTariff] : void 0,
|
|
13308
13543
|
"authorizationStart": {
|
|
13309
13544
|
"@id": identificationData ?? "?",
|
|
13310
13545
|
"type": identificationType ?? "?",
|
|
@@ -13317,19 +13552,50 @@ var OCMF = class {
|
|
|
13317
13552
|
}],
|
|
13318
13553
|
"certainty": 1
|
|
13319
13554
|
};
|
|
13320
|
-
|
|
13555
|
+
const resolvedChargingStationId = signedChargingStationId ?? containerChargingStation?.["@id"];
|
|
13556
|
+
if (resolvedChargingStationId !== void 0) {
|
|
13557
|
+
const matchingContainerStation = containerChargingStation?.["@id"] === resolvedChargingStationId ? containerChargingStation : void 0;
|
|
13558
|
+
const resolvedChargingStation = {
|
|
13559
|
+
...matchingContainerStation ?? { "@id": resolvedChargingStationId },
|
|
13560
|
+
...controllerFirmwareVersion !== void 0 ? {
|
|
13561
|
+
firmware: {
|
|
13562
|
+
...matchingContainerStation?.firmware,
|
|
13563
|
+
version: controllerFirmwareVersion
|
|
13564
|
+
}
|
|
13565
|
+
} : {}
|
|
13566
|
+
};
|
|
13567
|
+
CTR.chargingStations = [
|
|
13568
|
+
resolvedChargingStation,
|
|
13569
|
+
...ContainerInfos?.chargingStations?.filter((station) => station["@id"] !== resolvedChargingStationId) ?? []
|
|
13570
|
+
];
|
|
13571
|
+
if (CTR.chargingSessions?.[0] !== void 0) {
|
|
13572
|
+
CTR.chargingSessions[0].chargingStationId ??= resolvedChargingStationId;
|
|
13573
|
+
CTR.chargingSessions[0].chargingStation = resolvedChargingStation;
|
|
13574
|
+
}
|
|
13575
|
+
} else if (ContainerInfos?.chargingStations !== void 0)
|
|
13321
13576
|
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
13322
|
-
if (containerChargingStation !== void 0 && CTR.chargingSessions?.[0] !== void 0) {
|
|
13323
|
-
CTR.chargingSessions[0].chargingStationId = containerChargingStation["@id"];
|
|
13324
|
-
CTR.chargingSessions[0].chargingStation = containerChargingStation;
|
|
13325
|
-
}
|
|
13326
13577
|
if (containerEVSE !== void 0 && CTR.chargingSessions?.[0] !== void 0) {
|
|
13327
|
-
CTR.chargingSessions[0]
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13578
|
+
const chargingSession = CTR.chargingSessions[0];
|
|
13579
|
+
chargingSession.EVSEId ??= containerEVSE["@id"];
|
|
13580
|
+
if (chargingSession.EVSEId === containerEVSE["@id"])
|
|
13581
|
+
chargingSession.EVSE = containerEVSE;
|
|
13582
|
+
}
|
|
13583
|
+
const resolvedConnectorId = signedConnectorId ?? containerConnector?.["@id"];
|
|
13584
|
+
if ((resolvedConnectorId !== void 0 || signedCable !== void 0) && CTR.chargingSessions?.[0] !== void 0) {
|
|
13585
|
+
const matchingContainerConnector = containerConnector?.["@id"] === resolvedConnectorId ? containerConnector : void 0;
|
|
13586
|
+
const resolvedConnector = {
|
|
13587
|
+
...matchingContainerConnector,
|
|
13588
|
+
...resolvedConnectorId !== void 0 ? { "@id": resolvedConnectorId } : {},
|
|
13589
|
+
...signedCable !== void 0 ? {
|
|
13590
|
+
cable: {
|
|
13591
|
+
...matchingContainerConnector?.cable,
|
|
13592
|
+
...signedCable
|
|
13593
|
+
}
|
|
13594
|
+
} : {}
|
|
13595
|
+
};
|
|
13596
|
+
const chargingSession = CTR.chargingSessions[0];
|
|
13597
|
+
chargingSession.ConnectorId ??= resolvedConnectorId;
|
|
13598
|
+
chargingSession.Connector = resolvedConnector;
|
|
13333
13599
|
}
|
|
13334
13600
|
const measurementsByKey = /* @__PURE__ */ new Map();
|
|
13335
13601
|
for (const ocmfJSONDocument of OCMFJSONDocuments) {
|
|
@@ -13343,12 +13609,13 @@ var OCMF = class {
|
|
|
13343
13609
|
const readingUnit = effectiveReading.RU;
|
|
13344
13610
|
const readingCurrentType = effectiveReading.RT;
|
|
13345
13611
|
const cumulatedLoss = effectiveReading.CL;
|
|
13612
|
+
const errorIndex = effectiveReading.EI;
|
|
13346
13613
|
const errorFlags = effectiveReading.EF;
|
|
13347
13614
|
const status = effectiveReading.ST;
|
|
13348
13615
|
inheritedReading = effectiveReading;
|
|
13349
13616
|
if (isMandatoryString(time) && isOptionalString(transaction) && isMandatoryDecimal(readingValue) && // Note: Some vendors use a JSON string here!
|
|
13350
13617
|
isOptionalString(readingIdentification) && isMandatoryString(readingUnit) && isOptionalString(readingCurrentType) && // chargyLib.isOptionalDecimal (cumulatedLoss) &&
|
|
13351
|
-
isOptionalString(errorFlags) && isMandatoryString(status)) {
|
|
13618
|
+
isOptionalNumber(errorIndex) && isOptionalString(errorFlags) && isMandatoryString(status)) {
|
|
13352
13619
|
const timeSplit = time.split(" ");
|
|
13353
13620
|
if (timeSplit.length != 2) return {
|
|
13354
13621
|
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
@@ -13447,6 +13714,7 @@ var OCMF = class {
|
|
|
13447
13714
|
// "T" ToDo: Serialize this to a string!
|
|
13448
13715
|
"pagination": pagination,
|
|
13449
13716
|
// "9289"
|
|
13717
|
+
"errorIndex": errorIndex,
|
|
13450
13718
|
"errorFlags": errorFlags,
|
|
13451
13719
|
// ""
|
|
13452
13720
|
"cumulatedLoss": cumulatedLoss != null && cumulatedLoss !== 0 ? new Decimal(cumulatedLoss) : void 0,
|
|
@@ -13456,17 +13724,17 @@ var OCMF = class {
|
|
|
13456
13724
|
// "value": ocmfJSONDocument.signature["SD"]
|
|
13457
13725
|
// }],
|
|
13458
13726
|
"result": {
|
|
13459
|
-
"status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated
|
|
13727
|
+
"status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated */,
|
|
13728
|
+
// Surface the per-document verification diagnostics on the measurement value.
|
|
13729
|
+
...ocmfJSONDocument.validationErrors && ocmfJSONDocument.validationErrors.length > 0 ? { errors: ocmfJSONDocument.validationErrors } : {}
|
|
13460
13730
|
},
|
|
13461
13731
|
"ocmfDocument": ocmfJSONDocument
|
|
13462
13732
|
});
|
|
13463
13733
|
}
|
|
13464
13734
|
}
|
|
13465
13735
|
}
|
|
13466
|
-
if (ContainerInfos?.chargingStations !== void 0)
|
|
13467
|
-
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
13468
13736
|
if (ContainerInfos?.warnings !== void 0)
|
|
13469
|
-
CTR.warnings =
|
|
13737
|
+
CTR.warnings = (CTR.warnings ?? []).concat(ContainerInfos.warnings);
|
|
13470
13738
|
CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
|
|
13471
13739
|
if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
|
|
13472
13740
|
CTR.begin = CTR.chargingSessions[0].begin;
|
|
@@ -13603,6 +13871,20 @@ var OCMF = class {
|
|
|
13603
13871
|
// return mergedCTR;
|
|
13604
13872
|
// }
|
|
13605
13873
|
// //#endregion
|
|
13874
|
+
// Records why a verification step failed as structured data: a stable reason
|
|
13875
|
+
// key (localized via i18n.json and machine-switchable by the GUI) plus an
|
|
13876
|
+
// optional, language-neutral technical detail. Presentation is left to the GUI.
|
|
13877
|
+
AddValidationError(OCMFJSONDocument, reasonKey, detail) {
|
|
13878
|
+
const details = detail instanceof Error ? detail.message : typeof detail === "string" ? detail : void 0;
|
|
13879
|
+
(OCMFJSONDocument.validationErrors ??= []).push(
|
|
13880
|
+
CreateError(
|
|
13881
|
+
this.chargy.GetMultilanguageText(reasonKey),
|
|
13882
|
+
"high" /* high */,
|
|
13883
|
+
reasonKey,
|
|
13884
|
+
details
|
|
13885
|
+
)
|
|
13886
|
+
);
|
|
13887
|
+
}
|
|
13606
13888
|
//#region (private) validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding?)
|
|
13607
13889
|
async validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding) {
|
|
13608
13890
|
try {
|
|
@@ -13642,7 +13924,8 @@ var OCMF = class {
|
|
|
13642
13924
|
curve = new this.chargy.elliptic.ec("p256");
|
|
13643
13925
|
break;
|
|
13644
13926
|
}
|
|
13645
|
-
} catch {
|
|
13927
|
+
} catch (exception) {
|
|
13928
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_UnknownSignatureFormat", exception);
|
|
13646
13929
|
OCMFJSONDocument.validationStatus = "UnknownSignatureFormat" /* UnknownSignatureFormat */;
|
|
13647
13930
|
return OCMFJSONDocument.validationStatus;
|
|
13648
13931
|
}
|
|
@@ -13719,20 +14002,26 @@ var OCMF = class {
|
|
|
13719
14002
|
y: OCMFJSONDocument.publicKey.y
|
|
13720
14003
|
}, "hex");
|
|
13721
14004
|
}
|
|
13722
|
-
} catch {
|
|
14005
|
+
} catch (exception) {
|
|
14006
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_PublicKeyDecodingFailed", exception);
|
|
13723
14007
|
OCMFJSONDocument.validationStatus = "InvalidPublicKey" /* InvalidPublicKey */;
|
|
13724
14008
|
return OCMFJSONDocument.validationStatus;
|
|
13725
14009
|
}
|
|
13726
14010
|
try {
|
|
13727
14011
|
if (publicKey === null)
|
|
13728
14012
|
throw new Error("Missing public key!");
|
|
13729
|
-
|
|
14013
|
+
const signatureValid = publicKey.verify(OCMFJSONDocument.hashValue, OCMFJSONDocument.signatureRS);
|
|
14014
|
+
if (!signatureValid)
|
|
14015
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_SignatureMismatch");
|
|
14016
|
+
OCMFJSONDocument.validationStatus = signatureValid ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
|
|
13730
14017
|
return await Promise.resolve(OCMFJSONDocument.validationStatus);
|
|
13731
|
-
} catch {
|
|
14018
|
+
} catch (exception) {
|
|
14019
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_SignatureMalformed", exception);
|
|
13732
14020
|
OCMFJSONDocument.validationStatus = "InvalidSignature" /* InvalidSignature */;
|
|
13733
14021
|
return OCMFJSONDocument.validationStatus;
|
|
13734
14022
|
}
|
|
13735
|
-
} catch {
|
|
14023
|
+
} catch (exception) {
|
|
14024
|
+
this.AddValidationError(OCMFJSONDocument, "Verification_UnexpectedError", exception);
|
|
13736
14025
|
OCMFJSONDocument.validationStatus = "InvalidSignature" /* InvalidSignature */;
|
|
13737
14026
|
return OCMFJSONDocument.validationStatus;
|
|
13738
14027
|
}
|
|
@@ -13961,6 +14250,11 @@ var OCMF = class {
|
|
|
13961
14250
|
}
|
|
13962
14251
|
if (ocmfJSONDocumentGroup[0]) {
|
|
13963
14252
|
switch (ocmfJSONDocumentGroup[0].payload.FV) {
|
|
14253
|
+
// FV has cardinality 0..1 in OCMF. All supported 1.x
|
|
14254
|
+
// versions use the same parser, so an omitted version
|
|
14255
|
+
// is parsed as generic OCMF without changing the
|
|
14256
|
+
// signed payload or inventing a concrete version.
|
|
14257
|
+
case void 0:
|
|
13964
14258
|
case "0.1":
|
|
13965
14259
|
// OCMF 0.1 SAFE reference data uses a few legacy field names/forms (VI/VV,
|
|
13966
14260
|
// string based IS values), but the compact signed document structure is close
|
|
@@ -14982,6 +15276,184 @@ function readDERInteger(bytes, getOffset, setOffset) {
|
|
|
14982
15276
|
return hex;
|
|
14983
15277
|
}
|
|
14984
15278
|
|
|
15279
|
+
// src/PTBContainer.ts
|
|
15280
|
+
var base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
15281
|
+
var formatVersionRegExp = /^1(?:\.[0-9]+)?$/;
|
|
15282
|
+
var PTB = class {
|
|
15283
|
+
chargy;
|
|
15284
|
+
constructor(chargy) {
|
|
15285
|
+
this.chargy = chargy;
|
|
15286
|
+
}
|
|
15287
|
+
async TryToParsePTBContainer(container) {
|
|
15288
|
+
const validation = this.validateContainer(container);
|
|
15289
|
+
if (!validation.valid)
|
|
15290
|
+
return this.validationError(validation.issues);
|
|
15291
|
+
const ptbContainer = validation.container;
|
|
15292
|
+
const containerInfos = {
|
|
15293
|
+
chargingStations: [{
|
|
15294
|
+
"@id": ptbContainer.chargeboxIdentifier,
|
|
15295
|
+
address: this.normalizeAddress(ptbContainer.address),
|
|
15296
|
+
geoLocation: {
|
|
15297
|
+
lat: ptbContainer.geoLocation.lat,
|
|
15298
|
+
lng: ptbContainer.geoLocation.lng
|
|
15299
|
+
},
|
|
15300
|
+
EVSEs: [{
|
|
15301
|
+
"@id": ptbContainer.chargeboxIdentifier
|
|
15302
|
+
}]
|
|
15303
|
+
}]
|
|
15304
|
+
};
|
|
15305
|
+
return new OCMF(this.chargy).TryToParseOCMFDocuments(
|
|
15306
|
+
[ptbContainer.ocmfBegin, ptbContainer.ocmfEnd],
|
|
15307
|
+
ptbContainer.publicKey,
|
|
15308
|
+
"base64",
|
|
15309
|
+
containerInfos
|
|
15310
|
+
);
|
|
15311
|
+
}
|
|
15312
|
+
validateContainer(container) {
|
|
15313
|
+
const issues = [];
|
|
15314
|
+
if (!isMandatoryJSONObject(container))
|
|
15315
|
+
return {
|
|
15316
|
+
valid: false,
|
|
15317
|
+
issues: [{
|
|
15318
|
+
path: "$",
|
|
15319
|
+
message: "must be an object"
|
|
15320
|
+
}]
|
|
15321
|
+
};
|
|
15322
|
+
this.requireConstantString(container, "format", "ptb", issues);
|
|
15323
|
+
this.requireString(container, "publicKey", issues);
|
|
15324
|
+
this.requireString(container, "chargeboxIdentifier", issues);
|
|
15325
|
+
this.requireString(container, "ocmfBegin", issues);
|
|
15326
|
+
this.requireString(container, "ocmfEnd", issues);
|
|
15327
|
+
const formatVersion = container["formatVersion"];
|
|
15328
|
+
if (formatVersion !== void 0 && (typeof formatVersion !== "string" || !formatVersionRegExp.test(formatVersion))) {
|
|
15329
|
+
issues.push({
|
|
15330
|
+
path: "$.formatVersion",
|
|
15331
|
+
message: "must match ^1(?:\\.[0-9]+)?$"
|
|
15332
|
+
});
|
|
15333
|
+
}
|
|
15334
|
+
const publicKey = container["publicKey"];
|
|
15335
|
+
if (typeof publicKey === "string" && publicKey.length > 0 && !base64RegExp.test(publicKey))
|
|
15336
|
+
issues.push({
|
|
15337
|
+
path: "$.publicKey",
|
|
15338
|
+
message: "must be a base64 encoded string"
|
|
15339
|
+
});
|
|
15340
|
+
for (const propertyName of ["ocmfBegin", "ocmfEnd"]) {
|
|
15341
|
+
const ocmfDocument = container[propertyName];
|
|
15342
|
+
if (typeof ocmfDocument === "string" && (ocmfDocument.length < 10 || !ocmfDocument.startsWith("OCMF|"))) {
|
|
15343
|
+
issues.push({
|
|
15344
|
+
path: "$." + propertyName,
|
|
15345
|
+
message: "must be an unmodified OCMF record beginning with OCMF|"
|
|
15346
|
+
});
|
|
15347
|
+
}
|
|
15348
|
+
}
|
|
15349
|
+
const address = container["address"];
|
|
15350
|
+
if (!isMandatoryJSONObject(address))
|
|
15351
|
+
issues.push({
|
|
15352
|
+
path: "$.address",
|
|
15353
|
+
message: "must be an object"
|
|
15354
|
+
});
|
|
15355
|
+
else
|
|
15356
|
+
this.validateAddress(address, issues);
|
|
15357
|
+
const geoLocation = container["geoLocation"];
|
|
15358
|
+
if (!isMandatoryJSONObject(geoLocation))
|
|
15359
|
+
issues.push({
|
|
15360
|
+
path: "$.geoLocation",
|
|
15361
|
+
message: "must be an object"
|
|
15362
|
+
});
|
|
15363
|
+
else
|
|
15364
|
+
this.validateGeoLocation(geoLocation, issues);
|
|
15365
|
+
if (issues.length > 0)
|
|
15366
|
+
return {
|
|
15367
|
+
valid: false,
|
|
15368
|
+
issues
|
|
15369
|
+
};
|
|
15370
|
+
return {
|
|
15371
|
+
valid: true,
|
|
15372
|
+
container
|
|
15373
|
+
};
|
|
15374
|
+
}
|
|
15375
|
+
validateAddress(address, issues) {
|
|
15376
|
+
this.requireString(address, "street", issues, "$.address");
|
|
15377
|
+
for (const propertyName of ["houseNumber", "zipCode", "postalCode", "town", "city", "country"]) {
|
|
15378
|
+
const propertyValue = address[propertyName];
|
|
15379
|
+
if (propertyValue !== void 0 && typeof propertyValue !== "string")
|
|
15380
|
+
issues.push({
|
|
15381
|
+
path: "$.address." + propertyName,
|
|
15382
|
+
message: "must be a string"
|
|
15383
|
+
});
|
|
15384
|
+
else if ((propertyName === "town" || propertyName === "city") && propertyValue === "")
|
|
15385
|
+
issues.push({
|
|
15386
|
+
path: "$.address." + propertyName,
|
|
15387
|
+
message: "must be a non-empty string"
|
|
15388
|
+
});
|
|
15389
|
+
}
|
|
15390
|
+
const town = address["town"];
|
|
15391
|
+
const city = address["city"];
|
|
15392
|
+
if ((typeof town !== "string" || town.length === 0) && (typeof city !== "string" || city.length === 0)) {
|
|
15393
|
+
issues.push({
|
|
15394
|
+
path: "$.address",
|
|
15395
|
+
message: "must contain a non-empty town or city"
|
|
15396
|
+
});
|
|
15397
|
+
}
|
|
15398
|
+
}
|
|
15399
|
+
validateGeoLocation(geoLocation, issues) {
|
|
15400
|
+
const latitude = geoLocation["lat"];
|
|
15401
|
+
const longitude = geoLocation["lng"];
|
|
15402
|
+
if (typeof latitude !== "number" || !Number.isFinite(latitude) || latitude < -90 || latitude > 90)
|
|
15403
|
+
issues.push({
|
|
15404
|
+
path: "$.geoLocation.lat",
|
|
15405
|
+
message: "must be a number between -90 and 90"
|
|
15406
|
+
});
|
|
15407
|
+
if (typeof longitude !== "number" || !Number.isFinite(longitude) || longitude < -180 || longitude > 180)
|
|
15408
|
+
issues.push({
|
|
15409
|
+
path: "$.geoLocation.lng",
|
|
15410
|
+
message: "must be a number between -180 and 180"
|
|
15411
|
+
});
|
|
15412
|
+
for (const propertyName of Object.keys(geoLocation))
|
|
15413
|
+
if (propertyName !== "lat" && propertyName !== "lng")
|
|
15414
|
+
issues.push({
|
|
15415
|
+
path: "$.geoLocation." + propertyName,
|
|
15416
|
+
message: "is not allowed"
|
|
15417
|
+
});
|
|
15418
|
+
}
|
|
15419
|
+
requireString(json, propertyName, issues, parentPath = "$") {
|
|
15420
|
+
const value = json[propertyName];
|
|
15421
|
+
if (typeof value !== "string" || value.length === 0)
|
|
15422
|
+
issues.push({
|
|
15423
|
+
path: parentPath + "." + propertyName,
|
|
15424
|
+
message: "must be a non-empty string"
|
|
15425
|
+
});
|
|
15426
|
+
}
|
|
15427
|
+
requireConstantString(json, propertyName, expectedValue, issues) {
|
|
15428
|
+
if (json[propertyName] !== expectedValue)
|
|
15429
|
+
issues.push({
|
|
15430
|
+
path: "$." + propertyName,
|
|
15431
|
+
message: "must equal " + expectedValue
|
|
15432
|
+
});
|
|
15433
|
+
}
|
|
15434
|
+
normalizeAddress(address) {
|
|
15435
|
+
return {
|
|
15436
|
+
city: address.city ?? address.town,
|
|
15437
|
+
street: address.street,
|
|
15438
|
+
houseNumber: address.houseNumber,
|
|
15439
|
+
postalCode: address.postalCode ?? address.zipCode,
|
|
15440
|
+
country: address.country
|
|
15441
|
+
};
|
|
15442
|
+
}
|
|
15443
|
+
validationError(issues) {
|
|
15444
|
+
return {
|
|
15445
|
+
format: "ptb",
|
|
15446
|
+
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
15447
|
+
message: this.chargy.GetMultilanguageText("Invalid PTB OCMF container!"),
|
|
15448
|
+
certainty: 1,
|
|
15449
|
+
issues,
|
|
15450
|
+
errors: issues.map((issue) => CreateError(
|
|
15451
|
+
this.chargy.GetMultilanguageText(issue.path + " " + issue.message)
|
|
15452
|
+
))
|
|
15453
|
+
};
|
|
15454
|
+
}
|
|
15455
|
+
};
|
|
15456
|
+
|
|
14985
15457
|
// src/SAFE_XML.ts
|
|
14986
15458
|
var SAFEXML = class _SAFEXML {
|
|
14987
15459
|
chargy;
|
|
@@ -17492,6 +17964,26 @@ var Chargy = class {
|
|
|
17492
17964
|
return textContent.replace(/\s+/g, "");
|
|
17493
17965
|
return void 0;
|
|
17494
17966
|
}
|
|
17967
|
+
TryToCreatePublicKeyLookup(processedFiles) {
|
|
17968
|
+
if (processedFiles.length === 0)
|
|
17969
|
+
return void 0;
|
|
17970
|
+
const publicKeys = new Array();
|
|
17971
|
+
for (const processedFile of processedFiles) {
|
|
17972
|
+
if (IsAChargeTransparencyRecord(processedFile.result) || IsAChargeTransparencyLiveLink(processedFile.result)) {
|
|
17973
|
+
return void 0;
|
|
17974
|
+
}
|
|
17975
|
+
if (IsAPublicKey(processedFile.result))
|
|
17976
|
+
publicKeys.push(processedFile.result);
|
|
17977
|
+
else if (IsAPublicKeyLookup(processedFile.result))
|
|
17978
|
+
publicKeys.push(...processedFile.result.publicKeys);
|
|
17979
|
+
else
|
|
17980
|
+
return void 0;
|
|
17981
|
+
}
|
|
17982
|
+
if (processedFiles.length === 1 && IsAPublicKeyLookup(processedFiles[0]?.result)) {
|
|
17983
|
+
return processedFiles[0].result;
|
|
17984
|
+
}
|
|
17985
|
+
return { publicKeys };
|
|
17986
|
+
}
|
|
17495
17987
|
//#endregion
|
|
17496
17988
|
//#region QR code image files...
|
|
17497
17989
|
normalizeMIMEType(mimeType) {
|
|
@@ -18208,7 +18700,9 @@ var Chargy = class {
|
|
|
18208
18700
|
if (IsAChargeTransparencyLiveLink(JSONContent)) {
|
|
18209
18701
|
JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
|
|
18210
18702
|
processedFile.result = JSONContent;
|
|
18211
|
-
} else if (
|
|
18703
|
+
} else if (JSONContent["format"] === "ptb")
|
|
18704
|
+
processedFile.result = await new PTB(this).TryToParsePTBContainer(JSONContent);
|
|
18705
|
+
else if (isMandatoryString(JSONContext)) {
|
|
18212
18706
|
if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
|
|
18213
18707
|
processedFile.result = JSONContent;
|
|
18214
18708
|
else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
|
|
@@ -18248,18 +18742,15 @@ var Chargy = class {
|
|
|
18248
18742
|
}
|
|
18249
18743
|
processedFiles.push(processedFile);
|
|
18250
18744
|
}
|
|
18745
|
+
const publicKeyLookup = this.TryToCreatePublicKeyLookup(processedFiles);
|
|
18746
|
+
if (publicKeyLookup != null)
|
|
18747
|
+
return publicKeyLookup;
|
|
18251
18748
|
if (processedFiles.length == 1) {
|
|
18252
18749
|
const processedFile = getFirstArrayElement(processedFiles, "Missing processed file");
|
|
18253
18750
|
if (IsAChargeTransparencyRecord(processedFile.result))
|
|
18254
18751
|
return this.processChargeTransparencyRecord(processedFile.result);
|
|
18255
18752
|
if (IsAChargeTransparencyLiveLink(processedFile.result))
|
|
18256
18753
|
return processedFile.result;
|
|
18257
|
-
if (IsAPublicKeyLookup(processedFile.result))
|
|
18258
|
-
return {
|
|
18259
|
-
status: "InvalidSessionFormat" /* InvalidSessionFormat */,
|
|
18260
|
-
message: this.GetMultilanguageText("UnknownOrInvalidChargeTransparencyRecord"),
|
|
18261
|
-
certainty: 0
|
|
18262
|
-
};
|
|
18263
18754
|
return processedFile.result;
|
|
18264
18755
|
} else if (processedFiles.length > 1) {
|
|
18265
18756
|
const mergedCTR = {
|
|
@@ -18668,6 +19159,6 @@ var Chargy = class {
|
|
|
18668
19159
|
}
|
|
18669
19160
|
};
|
|
18670
19161
|
|
|
18671
|
-
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 };
|
|
19162
|
+
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 };
|
|
18672
19163
|
//# sourceMappingURL=index.js.map
|
|
18673
19164
|
//# sourceMappingURL=index.js.map
|