@zetra/citrineos-util 1.8.3-fork.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/authorization/ApiAuthPlugin.d.ts +52 -0
  2. package/dist/authorization/ApiAuthPlugin.js +122 -0
  3. package/dist/authorization/ApiAuthPlugin.js.map +1 -0
  4. package/dist/authorization/OidcTokenProvider.d.ts +15 -0
  5. package/dist/authorization/OidcTokenProvider.js +47 -0
  6. package/dist/authorization/OidcTokenProvider.js.map +1 -0
  7. package/dist/authorization/index.d.ts +4 -0
  8. package/dist/authorization/index.js +8 -0
  9. package/dist/authorization/index.js.map +1 -0
  10. package/dist/authorization/provider/LocalByPassAuthProvider.d.ts +34 -0
  11. package/dist/authorization/provider/LocalByPassAuthProvider.js +62 -0
  12. package/dist/authorization/provider/LocalByPassAuthProvider.js.map +1 -0
  13. package/dist/authorization/provider/OIDCAuthProvider.d.ts +62 -0
  14. package/dist/authorization/provider/OIDCAuthProvider.js +173 -0
  15. package/dist/authorization/provider/OIDCAuthProvider.js.map +1 -0
  16. package/dist/authorization/rbac/RbacRulesLoader.d.ts +32 -0
  17. package/dist/authorization/rbac/RbacRulesLoader.js +105 -0
  18. package/dist/authorization/rbac/RbacRulesLoader.js.map +1 -0
  19. package/dist/authorization/rbac/UrlMatcher.d.ts +14 -0
  20. package/dist/authorization/rbac/UrlMatcher.js +44 -0
  21. package/dist/authorization/rbac/UrlMatcher.js.map +1 -0
  22. package/dist/authorizer/RealTimeAuthorizer.d.ts +28 -0
  23. package/dist/authorizer/RealTimeAuthorizer.js +152 -0
  24. package/dist/authorizer/RealTimeAuthorizer.js.map +1 -0
  25. package/dist/authorizer/index.d.ts +1 -0
  26. package/dist/authorizer/index.js +5 -0
  27. package/dist/authorizer/index.js.map +1 -0
  28. package/dist/cache/memory.d.ts +19 -0
  29. package/dist/cache/memory.js +147 -0
  30. package/dist/cache/memory.js.map +1 -0
  31. package/dist/cache/redis.d.ts +16 -0
  32. package/dist/cache/redis.js +120 -0
  33. package/dist/cache/redis.js.map +1 -0
  34. package/dist/certificate/CertificateAuthority.d.ts +38 -0
  35. package/dist/certificate/CertificateAuthority.js +233 -0
  36. package/dist/certificate/CertificateAuthority.js.map +1 -0
  37. package/dist/certificate/CertificateUtil.d.ts +60 -0
  38. package/dist/certificate/CertificateUtil.js +317 -0
  39. package/dist/certificate/CertificateUtil.js.map +1 -0
  40. package/dist/certificate/client/acme.d.ts +37 -0
  41. package/dist/certificate/client/acme.js +138 -0
  42. package/dist/certificate/client/acme.js.map +1 -0
  43. package/dist/certificate/client/hubject.d.ts +41 -0
  44. package/dist/certificate/client/hubject.js +221 -0
  45. package/dist/certificate/client/hubject.js.map +1 -0
  46. package/dist/certificate/client/interface.d.ts +12 -0
  47. package/dist/certificate/client/interface.js +5 -0
  48. package/dist/certificate/client/interface.js.map +1 -0
  49. package/dist/certificate/index.d.ts +2 -0
  50. package/dist/certificate/index.js +6 -0
  51. package/dist/certificate/index.js.map +1 -0
  52. package/dist/files/ftpServer.d.ts +4 -0
  53. package/dist/files/ftpServer.js +9 -0
  54. package/dist/files/ftpServer.js.map +1 -0
  55. package/dist/files/gcpCloudStorage.d.ts +39 -0
  56. package/dist/files/gcpCloudStorage.js +130 -0
  57. package/dist/files/gcpCloudStorage.js.map +1 -0
  58. package/dist/files/localStorage.d.ts +14 -0
  59. package/dist/files/localStorage.js +57 -0
  60. package/dist/files/localStorage.js.map +1 -0
  61. package/dist/files/s3Storage.d.ts +17 -0
  62. package/dist/files/s3Storage.js +118 -0
  63. package/dist/files/s3Storage.js.map +1 -0
  64. package/dist/index.d.ts +21 -0
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/networkconnection/WebsocketNetworkConnection.d.ts +135 -0
  68. package/dist/networkconnection/WebsocketNetworkConnection.js +474 -0
  69. package/dist/networkconnection/WebsocketNetworkConnection.js.map +1 -0
  70. package/dist/networkconnection/authenticator/Authenticator.d.ts +20 -0
  71. package/dist/networkconnection/authenticator/Authenticator.js +39 -0
  72. package/dist/networkconnection/authenticator/Authenticator.js.map +1 -0
  73. package/dist/networkconnection/authenticator/AuthenticatorFilter.d.ts +11 -0
  74. package/dist/networkconnection/authenticator/AuthenticatorFilter.js +30 -0
  75. package/dist/networkconnection/authenticator/AuthenticatorFilter.js.map +1 -0
  76. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.d.ts +17 -0
  77. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js +51 -0
  78. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js.map +1 -0
  79. package/dist/networkconnection/authenticator/ConnectedStationFilter.d.ts +14 -0
  80. package/dist/networkconnection/authenticator/ConnectedStationFilter.js +25 -0
  81. package/dist/networkconnection/authenticator/ConnectedStationFilter.js.map +1 -0
  82. package/dist/networkconnection/authenticator/NetworkProfileFilter.d.ts +16 -0
  83. package/dist/networkconnection/authenticator/NetworkProfileFilter.js +84 -0
  84. package/dist/networkconnection/authenticator/NetworkProfileFilter.js.map +1 -0
  85. package/dist/networkconnection/authenticator/UnknownStationFilter.d.ts +16 -0
  86. package/dist/networkconnection/authenticator/UnknownStationFilter.js +25 -0
  87. package/dist/networkconnection/authenticator/UnknownStationFilter.js.map +1 -0
  88. package/dist/networkconnection/authenticator/errors/AuthenticationError.d.ts +6 -0
  89. package/dist/networkconnection/authenticator/errors/AuthenticationError.js +25 -0
  90. package/dist/networkconnection/authenticator/errors/AuthenticationError.js.map +1 -0
  91. package/dist/networkconnection/authenticator/errors/IUpgradeError.d.ts +9 -0
  92. package/dist/networkconnection/authenticator/errors/IUpgradeError.js +5 -0
  93. package/dist/networkconnection/authenticator/errors/IUpgradeError.js.map +1 -0
  94. package/dist/networkconnection/authenticator/errors/UnknownError.d.ts +6 -0
  95. package/dist/networkconnection/authenticator/errors/UnknownError.js +24 -0
  96. package/dist/networkconnection/authenticator/errors/UnknownError.js.map +1 -0
  97. package/dist/networkconnection/index.d.ts +5 -0
  98. package/dist/networkconnection/index.js +9 -0
  99. package/dist/networkconnection/index.js.map +1 -0
  100. package/dist/queue/index.d.ts +4 -0
  101. package/dist/queue/index.js +8 -0
  102. package/dist/queue/index.js.map +1 -0
  103. package/dist/queue/kafka/receiver.d.ts +35 -0
  104. package/dist/queue/kafka/receiver.js +179 -0
  105. package/dist/queue/kafka/receiver.js.map +1 -0
  106. package/dist/queue/kafka/sender.d.ts +53 -0
  107. package/dist/queue/kafka/sender.js +189 -0
  108. package/dist/queue/kafka/sender.js.map +1 -0
  109. package/dist/queue/rabbit-mq/receiver.d.ts +89 -0
  110. package/dist/queue/rabbit-mq/receiver.js +472 -0
  111. package/dist/queue/rabbit-mq/receiver.js.map +1 -0
  112. package/dist/queue/rabbit-mq/sender.d.ts +90 -0
  113. package/dist/queue/rabbit-mq/sender.js +251 -0
  114. package/dist/queue/rabbit-mq/sender.js.map +1 -0
  115. package/dist/security/SignedMeterValuesUtil.d.ts +44 -0
  116. package/dist/security/SignedMeterValuesUtil.js +135 -0
  117. package/dist/security/SignedMeterValuesUtil.js.map +1 -0
  118. package/dist/security/authentication.d.ts +2 -0
  119. package/dist/security/authentication.js +26 -0
  120. package/dist/security/authentication.js.map +1 -0
  121. package/dist/util/RequestOperations.d.ts +14 -0
  122. package/dist/util/RequestOperations.js +25 -0
  123. package/dist/util/RequestOperations.js.map +1 -0
  124. package/dist/util/StringOperations.d.ts +1 -0
  125. package/dist/util/StringOperations.js +8 -0
  126. package/dist/util/StringOperations.js.map +1 -0
  127. package/dist/util/emaidCheckDigitCalculator.d.ts +15 -0
  128. package/dist/util/emaidCheckDigitCalculator.js +179 -0
  129. package/dist/util/emaidCheckDigitCalculator.js.map +1 -0
  130. package/dist/util/idGenerator.d.ts +7 -0
  131. package/dist/util/idGenerator.js +10 -0
  132. package/dist/util/idGenerator.js.map +1 -0
  133. package/dist/util/parser.d.ts +31 -0
  134. package/dist/util/parser.js +60 -0
  135. package/dist/util/parser.js.map +1 -0
  136. package/dist/util/swagger.d.ts +5 -0
  137. package/dist/util/swagger.js +154 -0
  138. package/dist/util/swagger.js.map +1 -0
  139. package/dist/util/validator.d.ts +110 -0
  140. package/dist/util/validator.js +534 -0
  141. package/dist/util/validator.js.map +1 -0
  142. package/package.json +46 -0
@@ -0,0 +1,179 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ /**
5
+ * Calculate check digit for eMAID according to eMI³ specification
6
+ * Based on the algorithm described in "Check Digit Calculation for Contract-IDs"
7
+ *
8
+ * This implementation can detect five most frequent error types:
9
+ * 1. Single error: one character is wrong
10
+ * 2. Adjacent transposition: two adjacent characters are swapped
11
+ * 3. Twin error: two identical adjacent characters are both changed
12
+ * 4. Jump transposition: abc becomes cba
13
+ * 5. Jump twin error: aca becomes bcb
14
+ *
15
+ * @param emaidWithoutCheckDigit - The first 14 characters of the eMAID (without check digit)
16
+ * @returns The calculated check digit character
17
+ */
18
+ export function calculateCheckDigit(emaidWithoutCheckDigit) {
19
+ // Ensure input is uppercase and 14 characters
20
+ const input = emaidWithoutCheckDigit.toUpperCase();
21
+ if (input.length !== 14) {
22
+ throw new Error('Input must be exactly 14 characters');
23
+ }
24
+ // Validate that input contains only alphanumeric characters
25
+ if (!/^[A-Z0-9]+$/.test(input)) {
26
+ throw new Error('Input must contain only alphanumeric characters');
27
+ }
28
+ // Lookup tables for q1, q2, r1, r2 values based on the PDF specification
29
+ const lookupTable = {
30
+ '0': { q1: 0, q2: 0, r1: 0, r2: 0 },
31
+ '1': { q1: 0, q2: 0, r1: 0, r2: 1 },
32
+ '2': { q1: 0, q2: 0, r1: 0, r2: 2 },
33
+ '3': { q1: 0, q2: 0, r1: 1, r2: 0 },
34
+ '4': { q1: 0, q2: 0, r1: 1, r2: 1 },
35
+ '5': { q1: 0, q2: 0, r1: 1, r2: 2 },
36
+ '6': { q1: 0, q2: 0, r1: 2, r2: 0 },
37
+ '7': { q1: 0, q2: 0, r1: 2, r2: 1 },
38
+ '8': { q1: 0, q2: 0, r1: 2, r2: 2 },
39
+ '9': { q1: 0, q2: 1, r1: 0, r2: 0 },
40
+ A: { q1: 0, q2: 1, r1: 0, r2: 1 },
41
+ B: { q1: 0, q2: 1, r1: 0, r2: 2 },
42
+ C: { q1: 0, q2: 1, r1: 1, r2: 0 },
43
+ D: { q1: 0, q2: 1, r1: 1, r2: 1 },
44
+ E: { q1: 0, q2: 1, r1: 1, r2: 2 },
45
+ F: { q1: 0, q2: 1, r1: 2, r2: 0 },
46
+ G: { q1: 0, q2: 1, r1: 2, r2: 1 },
47
+ H: { q1: 0, q2: 1, r1: 2, r2: 2 },
48
+ I: { q1: 1, q2: 0, r1: 0, r2: 0 },
49
+ J: { q1: 1, q2: 0, r1: 0, r2: 1 },
50
+ K: { q1: 1, q2: 0, r1: 0, r2: 2 },
51
+ L: { q1: 1, q2: 0, r1: 1, r2: 0 },
52
+ M: { q1: 1, q2: 0, r1: 1, r2: 1 },
53
+ N: { q1: 1, q2: 0, r1: 1, r2: 2 },
54
+ O: { q1: 1, q2: 0, r1: 2, r2: 0 },
55
+ P: { q1: 1, q2: 0, r1: 2, r2: 1 },
56
+ Q: { q1: 1, q2: 0, r1: 2, r2: 2 },
57
+ R: { q1: 1, q2: 1, r1: 0, r2: 0 },
58
+ S: { q1: 1, q2: 1, r1: 0, r2: 1 },
59
+ T: { q1: 1, q2: 1, r1: 0, r2: 2 },
60
+ U: { q1: 1, q2: 1, r1: 1, r2: 0 },
61
+ V: { q1: 1, q2: 1, r1: 1, r2: 1 },
62
+ W: { q1: 1, q2: 1, r1: 1, r2: 2 },
63
+ X: { q1: 1, q2: 1, r1: 2, r2: 0 },
64
+ Y: { q1: 1, q2: 1, r1: 2, r2: 1 },
65
+ Z: { q1: 1, q2: 1, r1: 2, r2: 2 },
66
+ };
67
+ // Matrix P1 powers over Z2 (modulo 2)
68
+ // The pattern repeats every 3 positions
69
+ const getP1Power = (index) => {
70
+ const position = (index % 3) + 1;
71
+ if (position === 3) {
72
+ return [
73
+ [1, 0],
74
+ [0, 1],
75
+ ]; // Identity matrix for positions 3, 6, 9, 12, 15
76
+ }
77
+ else if (position === 1) {
78
+ return [
79
+ [0, 1],
80
+ [1, 1],
81
+ ]; // P1 for positions 1, 4, 7, 10, 13
82
+ }
83
+ else {
84
+ return [
85
+ [1, 1],
86
+ [1, 0],
87
+ ]; // P1^2 for positions 2, 5, 8, 11, 14
88
+ }
89
+ };
90
+ // Matrix P2 powers over Z3 (modulo 3)
91
+ // The pattern repeats every 8 positions
92
+ const P2_powers = [
93
+ [
94
+ [0, 1],
95
+ [1, 2],
96
+ ], // P2^1
97
+ [
98
+ [1, 2],
99
+ [2, 2],
100
+ ], // P2^2
101
+ [
102
+ [2, 2],
103
+ [2, 0],
104
+ ], // P2^3
105
+ [
106
+ [2, 0],
107
+ [0, 2],
108
+ ], // P2^4
109
+ [
110
+ [0, 2],
111
+ [2, 1],
112
+ ], // P2^5
113
+ [
114
+ [2, 1],
115
+ [1, 1],
116
+ ], // P2^6
117
+ [
118
+ [1, 1],
119
+ [1, 0],
120
+ ], // P2^7
121
+ [
122
+ [1, 0],
123
+ [0, 1],
124
+ ], // P2^8 (Identity)
125
+ ];
126
+ const getP2Power = (index) => {
127
+ return P2_powers[index % 8];
128
+ };
129
+ // Initialize accumulators for check equations
130
+ const q_sum = [0, 0]; // For Z2 calculation
131
+ const r_sum = [0, 0]; // For Z3 calculation
132
+ // Process each character
133
+ for (let i = 0; i < 14; i++) {
134
+ const char = input[i];
135
+ const values = lookupTable[char];
136
+ if (!values) {
137
+ throw new Error(`Invalid character '${char}' at position ${i}`);
138
+ }
139
+ // Matrix multiplication for q (Z2)
140
+ const P1 = getP1Power(i);
141
+ const q_vec = [values.q1, values.q2];
142
+ const q_result = [
143
+ (P1[0][0] * q_vec[0] + P1[0][1] * q_vec[1]) % 2,
144
+ (P1[1][0] * q_vec[0] + P1[1][1] * q_vec[1]) % 2,
145
+ ];
146
+ q_sum[0] = (q_sum[0] + q_result[0]) % 2;
147
+ q_sum[1] = (q_sum[1] + q_result[1]) % 2;
148
+ // Matrix multiplication for r (Z3)
149
+ const P2 = getP2Power(i);
150
+ const r_vec = [values.r1, values.r2];
151
+ const r_result = [
152
+ (P2[0][0] * r_vec[0] + P2[0][1] * r_vec[1]) % 3,
153
+ (P2[1][0] * r_vec[0] + P2[1][1] * r_vec[1]) % 3,
154
+ ];
155
+ r_sum[0] = (r_sum[0] + r_result[0]) % 3;
156
+ r_sum[1] = (r_sum[1] + r_result[1]) % 3;
157
+ }
158
+ // Calculate check digit values
159
+ // For position 15: P1^15 = Identity, P2^15 = [[1,1],[1,0]]
160
+ // Solve for q15 such that the check equation equals 0
161
+ // Since P1^15 is identity, q15 = -q_sum (mod 2)
162
+ const q15 = [(2 - q_sum[0]) % 2, (2 - q_sum[1]) % 2];
163
+ // Solve for r15 such that the check equation equals 0
164
+ // For P2^15 = [[1,1],[1,0]], we solve: [r15_1, r15_2] * P2^15 = -r_sum
165
+ // This gives: r15_1 = -r_sum[1] and r15_1 + r15_2 = -r_sum[0]
166
+ const r15 = [(3 - r_sum[1]) % 3, (((3 - r_sum[0]) % 3) + r_sum[1]) % 3];
167
+ // Convert from two-dimensional to single values
168
+ const q_value = q15[0] * 2 + q15[1]; // Convert from Z2 × Z2 to {0,1,2,3}
169
+ const r_value = r15[0] * 3 + r15[1]; // Convert from Z3 × Z3 to {0,1,2,...,8}
170
+ // Combine using the formula: a = q * 9 + r
171
+ const checkValue = q_value * 9 + r_value;
172
+ // Map the check value (0-35) directly to alphanumeric characters
173
+ const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
174
+ if (checkValue < 0 || checkValue >= 36) {
175
+ throw new Error(`Invalid check value: ${checkValue}`);
176
+ }
177
+ return charset[checkValue];
178
+ }
179
+ //# sourceMappingURL=emaidCheckDigitCalculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emaidCheckDigitCalculator.js","sourceRoot":"","sources":["../../src/util/emaidCheckDigitCalculator.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AACtC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,sBAA8B;IAChE,8CAA8C;IAC9C,MAAM,KAAK,GAAG,sBAAsB,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,yEAAyE;IACzE,MAAM,WAAW,GAAuE;QACtF,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE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"}
@@ -0,0 +1,7 @@
1
+ import type { ChargingStationSequenceTypeEnumType } from '@citrineos/base';
2
+ import type { IChargingStationSequenceRepository } from '@citrineos/data';
3
+ export declare class IdGenerator {
4
+ private _stationSequenceRepository;
5
+ constructor(stationSequenceRepository: IChargingStationSequenceRepository);
6
+ generateRequestId(tenantId: number, stationId: string, type: ChargingStationSequenceTypeEnumType): Promise<number>;
7
+ }
@@ -0,0 +1,10 @@
1
+ export class IdGenerator {
2
+ _stationSequenceRepository;
3
+ constructor(stationSequenceRepository) {
4
+ this._stationSequenceRepository = stationSequenceRepository;
5
+ }
6
+ async generateRequestId(tenantId, stationId, type) {
7
+ return this._stationSequenceRepository.getNextSequenceValue(tenantId, stationId, type);
8
+ }
9
+ }
10
+ //# sourceMappingURL=idGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idGenerator.js","sourceRoot":"","sources":["../../src/util/idGenerator.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,WAAW;IACd,0BAA0B,CAAqC;IAEvE,YAAY,yBAA6D;QACvE,IAAI,CAAC,0BAA0B,GAAG,yBAAyB,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,QAAgB,EAChB,SAAiB,EACjB,IAAyC;QAEzC,OAAO,IAAI,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACzF,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ import type { OcppRequest } from '@citrineos/base';
2
+ /**
3
+ * Calculate the size of a request.
4
+ *
5
+ * @param {object} request - The ocpp request.
6
+ * @return {number} The size of the request (Bytes).
7
+ */
8
+ export declare function getSizeOfRequest(request: OcppRequest): number;
9
+ /**
10
+ * Slice array into pieces according to the given size.
11
+ *
12
+ * @param {array} array - An array.
13
+ * @param {number} size - The expected size of a batch.
14
+ * @return {map} A map with index as key and batch as value. Index is the position of the 1st batch element in the given
15
+ * array. Batch is a subarray of the given array.
16
+ */
17
+ export declare function getBatches(array: object[] | string[] | boolean[] | number[], size: number): Map<number, object[] | string[] | boolean[] | number[]>;
18
+ /**
19
+ * Get the number of fraction digits in a number, e.g, 1.23 -> 2
20
+ *
21
+ * @param num - The number to get the number of fraction digits
22
+ * @returns The number of fraction digits
23
+ */
24
+ export declare function getNumberOfFractionDigit(num: number): number;
25
+ /**
26
+ * Convert string to set. For example, 'a,b,c' -> new Set(['a', 'b', 'c'])
27
+ *
28
+ * @param input - The string to convert
29
+ * @returns Set
30
+ */
31
+ export declare function stringToSet(input: string): Set<string>;
@@ -0,0 +1,60 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ /**
5
+ * Calculate the size of a request.
6
+ *
7
+ * @param {object} request - The ocpp request.
8
+ * @return {number} The size of the request (Bytes).
9
+ */
10
+ export function getSizeOfRequest(request) {
11
+ return new TextEncoder().encode(JSON.stringify(request)).length;
12
+ }
13
+ /**
14
+ * Slice array into pieces according to the given size.
15
+ *
16
+ * @param {array} array - An array.
17
+ * @param {number} size - The expected size of a batch.
18
+ * @return {map} A map with index as key and batch as value. Index is the position of the 1st batch element in the given
19
+ * array. Batch is a subarray of the given array.
20
+ */
21
+ export function getBatches(array, size) {
22
+ if (!Number.isInteger(size) || size <= 0) {
23
+ size = array.length;
24
+ }
25
+ const batchMap = new Map();
26
+ let lastIndex = 0;
27
+ while (array.length > 0) {
28
+ const batch = array.slice(0, size);
29
+ batchMap.set(lastIndex, batch);
30
+ lastIndex += batch.length;
31
+ array = array.slice(size);
32
+ }
33
+ return batchMap;
34
+ }
35
+ /**
36
+ * Get the number of fraction digits in a number, e.g, 1.23 -> 2
37
+ *
38
+ * @param num - The number to get the number of fraction digits
39
+ * @returns The number of fraction digits
40
+ */
41
+ export function getNumberOfFractionDigit(num) {
42
+ const numString = num.toString();
43
+ const match = numString.match(/\.(\d+)/);
44
+ if (!match) {
45
+ return 0;
46
+ }
47
+ else {
48
+ return match[1].length;
49
+ }
50
+ }
51
+ /**
52
+ * Convert string to set. For example, 'a,b,c' -> new Set(['a', 'b', 'c'])
53
+ *
54
+ * @param input - The string to convert
55
+ * @returns Set
56
+ */
57
+ export function stringToSet(input) {
58
+ return new Set(input.split(',').map((item) => item.trim()));
59
+ }
60
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/util/parser.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AAItC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,KAAiD,EACjD,IAAY;IAEZ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACnC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC/B,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;QAC1B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAC;IACX,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { SystemConfig } from '@citrineos/base';
2
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
3
+ export declare const getHeaderValue: (headers: string[], key: string) => string | undefined;
4
+ export declare const getAuthorizationTokenFromRequest: (request: FastifyRequest) => string;
5
+ export declare function initSwagger(systemConfig: SystemConfig, server: FastifyInstance): Promise<void>;
@@ -0,0 +1,154 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import { HttpHeader, HttpStatus, UnauthorizedError } from '@citrineos/base';
5
+ import * as FastifyAuth from '@fastify/auth';
6
+ import fastifySwagger from '@fastify/swagger';
7
+ import fastifySwaggerUi from '@fastify/swagger-ui';
8
+ import fs from 'fs';
9
+ import { OpenAPIV2, OpenAPIV3 } from 'openapi-types';
10
+ import * as packageJson from '../../package.json' with { type: 'json' };
11
+ /**
12
+ * This transformation is used to set default tags
13
+ *
14
+ * @param {object} swaggerObject - The original Swagger object to be transformed.
15
+ * @param {object} openapiObject - The original OpenAPI object to be transformed.
16
+ * @return {object} The transformed OpenAPI object.
17
+ */
18
+ function OcppTransformObject({ swaggerObject, openapiObject, }) {
19
+ console.log('OcppTransformObject: Transforming OpenAPI object...');
20
+ if (openapiObject.paths && openapiObject.components) {
21
+ for (const pathKey in openapiObject.paths) {
22
+ const path = openapiObject.paths[pathKey];
23
+ if (path) {
24
+ for (const methodKey in path) {
25
+ const method = path[methodKey];
26
+ if (method) {
27
+ // Set tags based on path key if tags were not passed in
28
+ if (!method.tags) {
29
+ // Get tag index
30
+ // e.g, '/ocpp/1.6/evdriver' -> 'evdriver'
31
+ // e.g, '/data/evdriver' -> 'evdriver'
32
+ const pathSegments = pathKey.split('/');
33
+ const tagIndex = pathSegments.find((segment) => segment === 'data') ? 2 : 3;
34
+ method.tags = pathKey
35
+ .split('/')
36
+ .slice(tagIndex, -1)
37
+ .map((tag) => tag.charAt(0).toUpperCase() + tag.slice(1));
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ return openapiObject;
45
+ }
46
+ const registerSwaggerUi = (systemConfig, server) => {
47
+ const swaggerUiOptions = {
48
+ routePrefix: systemConfig.util.swagger?.path,
49
+ securityDefinitions: {
50
+ authorization: {
51
+ name: 'authorization',
52
+ type: 'apiKey',
53
+ in: 'header',
54
+ },
55
+ },
56
+ exposeRoute: true,
57
+ uiConfig: {
58
+ filter: true,
59
+ },
60
+ theme: {
61
+ title: 'CitrineOS Central System API',
62
+ css: [
63
+ {
64
+ filename: '',
65
+ content: '.swagger-ui .topbar { background-color: #fafafa; } .swagger-ui .topbar .download-url-wrapper { display: none; }',
66
+ },
67
+ ],
68
+ },
69
+ };
70
+ if (systemConfig.util.swagger?.logoPath) {
71
+ swaggerUiOptions['logo'] = {
72
+ type: 'image/png',
73
+ content: fs.readFileSync(systemConfig.util.swagger?.logoPath),
74
+ };
75
+ }
76
+ server.register(fastifySwaggerUi, swaggerUiOptions);
77
+ };
78
+ export const getHeaderValue = (headers, key) => {
79
+ for (let i = 0; i < headers.length; i += 2) {
80
+ if (headers[i].toLowerCase() === key.toLowerCase()) {
81
+ return headers[i + 1];
82
+ }
83
+ }
84
+ return undefined;
85
+ };
86
+ const getTokenFromAuthHeader = (authorizationHeader) => {
87
+ if (!!authorizationHeader) {
88
+ const token = authorizationHeader.split('Bearer ')[1];
89
+ return token;
90
+ }
91
+ return undefined;
92
+ };
93
+ const getAuthorizationTokenFromRawHeaders = (headers) => {
94
+ const authorizationHeader = getHeaderValue(headers, HttpHeader.Authorization);
95
+ return getTokenFromAuthHeader(authorizationHeader);
96
+ };
97
+ export const getAuthorizationTokenFromRequest = (request) => {
98
+ const token = getAuthorizationTokenFromRawHeaders(request.raw.rawHeaders);
99
+ if (!token) {
100
+ throw new UnauthorizedError('Token not found in headers');
101
+ }
102
+ return token;
103
+ };
104
+ const registerFastifyAuth = async (server) => {
105
+ await server.register(FastifyAuth).after();
106
+ console.log(server.authorization);
107
+ server.decorate('authorization', function (request, reply, done) {
108
+ try {
109
+ const token = getAuthorizationTokenFromRequest(request);
110
+ console.log('Received authorization token', token);
111
+ done();
112
+ }
113
+ catch (e) {
114
+ reply.code(HttpStatus.UNAUTHORIZED);
115
+ }
116
+ });
117
+ };
118
+ const buildLocalReference = (json, _parent, _property, i) => {
119
+ // If title is missing but $id is available, set title to $id
120
+ if (!json.title && json.$id) {
121
+ json.title = json.$id;
122
+ }
123
+ // Return title if available, otherwise fallback to $id, or def-<index> as a last resort
124
+ return json.title || json.$id || `def-${i}`;
125
+ };
126
+ const registerFastifySwagger = (systemConfig, server) => {
127
+ server.register(fastifySwagger, {
128
+ openapi: {
129
+ info: {
130
+ title: 'CitrineOS Central System API',
131
+ description: 'Central System API for OCPP 2.0.1 messaging.',
132
+ version: packageJson.default.version,
133
+ },
134
+ components: {
135
+ securitySchemes: {
136
+ authorization: {
137
+ type: 'http',
138
+ scheme: 'bearer',
139
+ },
140
+ },
141
+ },
142
+ },
143
+ transformObject: OcppTransformObject,
144
+ refResolver: {
145
+ buildLocalReference,
146
+ },
147
+ });
148
+ };
149
+ export async function initSwagger(systemConfig, server) {
150
+ registerFastifySwagger(systemConfig, server);
151
+ registerSwaggerUi(systemConfig, server);
152
+ await registerFastifyAuth(server);
153
+ }
154
+ //# sourceMappingURL=swagger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swagger.js","sourceRoot":"","sources":["../../src/util/swagger.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC;AAKtC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,KAAK,WAAW,MAAM,eAAe,CAAC;AAC7C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAExE;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,EAC3B,aAAa,EACb,aAAa,GAId;IACC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,IAAI,aAAa,CAAC,KAAK,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC;QACpD,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;YAC1C,MAAM,IAAI,GAA0B,aAAa,CAAC,KAAK,CAAC,OAAO,CAA0B,CAAC;YAC1F,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;oBAC7B,MAAM,MAAM,GAA8B,IAAI,CAAC,SAAS,CAA8B,CAAC;oBACvF,IAAI,MAAM,EAAE,CAAC;wBACX,wDAAwD;wBACxD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;4BACjB,gBAAgB;4BAChB,0CAA0C;4BAC1C,sCAAsC;4BACtC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;4BACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC5E,MAAM,CAAC,IAAI,GAAG,OAAO;iCAClB,KAAK,CAAC,GAAG,CAAC;iCACV,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;iCACnB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC9D,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,iBAAiB,GAAG,CAAC,YAA0B,EAAE,MAAuB,EAAE,EAAE;IAChF,MAAM,gBAAgB,GAAQ;QAC5B,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI;QAC5C,mBAAmB,EAAE;YACnB,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,EAAE,EAAE,QAAQ;aACb;SACF;QACD,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE;YACR,MAAM,EAAE,IAAI;SACb;QACD,KAAK,EAAE;YACL,KAAK,EAAE,8BAA8B;YACrC,GAAG,EAAE;gBACH;oBACE,QAAQ,EAAE,EAAE;oBACZ,OAAO,EACL,iHAAiH;iBACpH;aACF;SACF;KACF,CAAC;IAEF,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QACxC,gBAAgB,CAAC,MAAM,CAAC,GAAG;YACzB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAiB,EAAE,GAAW,EAAsB,EAAE;IACnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YACnD,OAAO,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,mBAAuC,EAAsB,EAAE;IAC7F,IAAI,CAAC,CAAC,mBAAmB,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,mCAAmC,GAAG,CAAC,OAAiB,EAAsB,EAAE;IACpF,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IAC9E,OAAO,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,OAAuB,EAAU,EAAE;IAClF,MAAM,KAAK,GAAG,mCAAmC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,iBAAiB,CAAC,4BAA4B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAuB,EAAE,EAAE;IAC5D,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAkB,CAAC,CAAC,KAAK,EAAE,CAAC;IAClD,OAAO,CAAC,GAAG,CAAE,MAAc,CAAC,aAAa,CAAC,CAAC;IAE3C,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,OAAY,EAAE,KAAU,EAAE,IAAS;QAC5E,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,IAAS,EAAE,OAAgB,EAAE,SAAkB,EAAE,CAAS,EAAE,EAAE;IACzF,6DAA6D;IAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;IAED,wFAAwF;IACxF,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,YAA0B,EAAE,MAAuB,EAAE,EAAE;IACrF,MAAM,CAAC,QAAQ,CAAC,cAAqB,EAAE;QACrC,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,KAAK,EAAE,8BAA8B;gBACrC,WAAW,EAAE,8CAA8C;gBAC3D,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO;aACrC;YACD,UAAU,EAAE;gBACV,eAAe,EAAE;oBACf,aAAa,EAAE;wBACb,IAAI,EAAE,MAAM;wBACZ,MAAM,EAAE,QAAQ;qBACjB;iBACF;aACF;SACF;QACD,eAAe,EAAE,mBAAmB;QACpC,WAAW,EAAE;YACX,mBAAmB;SACpB;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,YAA0B,EAAE,MAAuB;IACnF,sBAAsB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { OCPP2_0_1 } from '@citrineos/base';
2
+ import type { IChargingProfileRepository, IDeviceModelRepository, ITransactionEventRepository } from '@citrineos/data';
3
+ import type { ILogObj } from 'tslog';
4
+ import { Logger } from 'tslog';
5
+ /**
6
+ * Validate a language tag is an RFC-5646 tag, see: {@link https://tools.ietf.org/html/rfc5646},
7
+ * example: US English is: "en-US"
8
+ *
9
+ * @param languageTag
10
+ * @returns {boolean} true if the languageTag is an RFC-5646 tag
11
+ */
12
+ export declare function validateLanguageTag(languageTag: string): boolean;
13
+ /**
14
+ * Validate constraints of ChargingProfileType defined in OCPP 2.0.1
15
+ *
16
+ * @param chargingProfileType ChargingProfileType from the request
17
+ * @param tenantId tenant id the profile belongs to
18
+ * @param stationId station id
19
+ * @param deviceModelRepository deviceModelRepository
20
+ * @param chargingProfileRepository chargingProfileRepository
21
+ * @param transactionEventRepository transactionEventRepository
22
+ * @param logger logger
23
+ * @param evseId evse id
24
+ */
25
+ export declare function validateChargingProfileType(chargingProfileType: OCPP2_0_1.ChargingProfileType, tenantId: number, stationId: string, deviceModelRepository: IDeviceModelRepository, chargingProfileRepository: IChargingProfileRepository, transactionEventRepository: ITransactionEventRepository, logger: Logger<ILogObj>, evseId?: number | null): Promise<void>;
26
+ /**
27
+ * Validate ISO15693 ID token format
28
+ * ISO 15693 UID should be exactly 8 bytes (16 hex characters)
29
+ */
30
+ export declare function validateISO15693IdToken(idToken: string): boolean;
31
+ /**
32
+ * Validate ISO14443 ID token format
33
+ * ISO 14443 UID should be 4 or 7 bytes (8 or 14 hex characters)
34
+ */
35
+ export declare function validateISO14443IdToken(idToken: string): boolean;
36
+ /**
37
+ * Validate identifier string format per OCPP 2.0.1. We expect this validation already from the JSON schema,
38
+ * but we add this extra validation to be sure.
39
+ * Only allows: a-z, A-Z, 0-9, *, -, _, =, :, +, |, @, .
40
+ */
41
+ export declare function validateIdentifierStringIdToken(idToken: string): boolean;
42
+ /**
43
+ * Validates an eMAID string according to eMI³ specifications
44
+ * @param emaid - The eMAID string to validate
45
+ * @returns errors - String array with errors, empty if valid
46
+ */
47
+ export declare function validateEMAIDIdToken(emaid: string): string[];
48
+ /**
49
+ * Validate NoAuthorization ID token (should be empty)
50
+ */
51
+ export declare function validateNoAuthorizationIdToken(idToken: string): boolean;
52
+ /**
53
+ * Generic validation result for all validators
54
+ */
55
+ export interface ValidationResult {
56
+ isValid: boolean;
57
+ errorMessage?: string;
58
+ }
59
+ /**
60
+ * ID token validator - routes to appropriate validator based on type
61
+ * Returns validation result with detailed error message if invalid
62
+ */
63
+ export declare function validateIdToken(idTokenType: OCPP2_0_1.IdTokenEnumType, idToken: string): ValidationResult;
64
+ /**
65
+ * Validate ASCII content - only printable ASCII allowed (characters 32-126)
66
+ * @param content Content string to validate
67
+ * @returns {boolean} true if content contains only printable ASCII characters
68
+ */
69
+ export declare function validateASCIIContent(content: string): boolean;
70
+ /**
71
+ * Validate HTML content - checks for basic HTML structure validity
72
+ * @param content Content string to validate
73
+ * @returns {boolean} true if content appears to be valid HTML
74
+ */
75
+ export declare function validateHTMLContent(content: string): boolean;
76
+ /**
77
+ * Validate URI content - checks if content is a valid URI
78
+ * @param content Content string to validate
79
+ * @returns {boolean} true if content is a valid URI
80
+ */
81
+ export declare function validateURIContent(content: string): boolean;
82
+ /**
83
+ * Validate UTF-8 content - in JavaScript, strings are already UTF-16 encoded
84
+ * This function checks for invalid surrogate pairs and control characters
85
+ * @param content Content string to validate
86
+ * @returns {boolean} true if content is valid UTF-8
87
+ */
88
+ export declare function validateUTF8Content(content: string): boolean;
89
+ /**
90
+ * Message content validator - routes to appropriate validator based on format
91
+ * Returns validation result with detailed error message if invalid
92
+ * @param format Message format type (ASCII, HTML, URI, UTF8)
93
+ * @param content Message content to validate
94
+ * @returns {ValidationResult} Validation result with error message if invalid
95
+ */
96
+ export declare function validateMessageContent(format: OCPP2_0_1.MessageFormatEnumType, content: string): ValidationResult;
97
+ /**
98
+ * Validate a complete MessageContentType object
99
+ * Convenience function that validates both language tag (if present) and content against format
100
+ * @param messageContent MessageContentType object to validate
101
+ * @returns {ValidationResult} Validation result with error message if invalid
102
+ */
103
+ export declare function validateMessageContentType(messageContent: OCPP2_0_1.MessageContentType): ValidationResult;
104
+ /**
105
+ * Validate PEM-encoded Certificate Signing Request (CSR)
106
+ * According to RFC 2986, CSR must be PEM-encoded with proper headers and valid base64 content
107
+ * @param csr CSR string to validate
108
+ * @returns {ValidationResult} Validation result with error message if invalid
109
+ */
110
+ export declare function validatePEMEncodedCSR(csr: string): ValidationResult;