apacuana-sdk-core 0.1.0 → 0.3.0

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 (35) hide show
  1. package/README.md +175 -55
  2. package/coverage/clover.xml +249 -101
  3. package/coverage/coverage-final.json +9 -6
  4. package/coverage/lcov-report/index.html +45 -30
  5. package/coverage/lcov-report/src/api/certs.js.html +117 -81
  6. package/coverage/lcov-report/src/api/index.html +40 -25
  7. package/coverage/lcov-report/src/api/revocations.js.html +1 -1
  8. package/coverage/lcov-report/src/api/signatures.js.html +546 -72
  9. package/coverage/lcov-report/src/api/users.js.html +25 -61
  10. package/coverage/lcov-report/src/config/index.html +21 -21
  11. package/coverage/lcov-report/src/config/index.js.html +65 -32
  12. package/coverage/lcov-report/src/errors/index.html +5 -5
  13. package/coverage/lcov-report/src/errors/index.js.html +13 -10
  14. package/coverage/lcov-report/src/index.html +1 -1
  15. package/coverage/lcov-report/src/index.js.html +13 -4
  16. package/coverage/lcov-report/src/utils/constant.js.html +4 -4
  17. package/coverage/lcov-report/src/utils/helpers.js.html +290 -116
  18. package/coverage/lcov-report/src/utils/httpClient.js.html +646 -0
  19. package/coverage/lcov-report/src/utils/index.html +30 -15
  20. package/coverage/lcov.info +515 -181
  21. package/dist/index.js +323 -189
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +323 -189
  24. package/dist/index.mjs.map +1 -1
  25. package/package.json +1 -1
  26. package/src/api/certs.js +49 -37
  27. package/src/api/signatures.js +213 -49
  28. package/src/api/users.js +17 -29
  29. package/src/errors/index.js +1 -0
  30. package/src/index.js +4 -1
  31. package/src/utils/helpers.js +156 -98
  32. package/tests/api/certs.test.js +111 -5
  33. package/tests/api/signatures.test.js +152 -4
  34. package/tests/api/users.test.js +11 -10
  35. package/src/auth/index.js +0 -24
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">11.53% </span>
26
+ <span class="strong">100% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>3/26</span>
28
+ <span class='fraction'>25/25</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">0% </span>
33
+ <span class="strong">72.72% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>0/8</span>
35
+ <span class='fraction'>8/11</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">0% </span>
40
+ <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>0/3</span>
42
+ <span class='fraction'>4/4</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">11.53% </span>
47
+ <span class="strong">100% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>3/26</span>
49
+ <span class='fraction'>25/25</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line low'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -133,144 +133,180 @@
133
133
  <a name='L68'></a><a href='#L68'>68</a>
134
134
  <a name='L69'></a><a href='#L69'>69</a>
135
135
  <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
137
149
  <span class="cline-any cline-neutral">&nbsp;</span>
138
150
  <span class="cline-any cline-neutral">&nbsp;</span>
139
151
  <span class="cline-any cline-neutral">&nbsp;</span>
140
152
  <span class="cline-any cline-neutral">&nbsp;</span>
141
153
  <span class="cline-any cline-neutral">&nbsp;</span>
154
+ <span class="cline-any cline-yes">2x</span>
155
+ <span class="cline-any cline-yes">4x</span>
156
+ <span class="cline-any cline-yes">4x</span>
142
157
  <span class="cline-any cline-neutral">&nbsp;</span>
158
+ <span class="cline-any cline-yes">4x</span>
159
+ <span class="cline-any cline-neutral">&nbsp;</span>
160
+ <span class="cline-any cline-neutral">&nbsp;</span>
161
+ <span class="cline-any cline-neutral">&nbsp;</span>
162
+ <span class="cline-any cline-neutral">&nbsp;</span>
163
+ <span class="cline-any cline-yes">2x</span>
164
+ <span class="cline-any cline-yes">2x</span>
143
165
  <span class="cline-any cline-yes">1x</span>
144
- <span class="cline-any cline-no">&nbsp;</span>
145
- <span class="cline-any cline-no">&nbsp;</span>
146
- <span class="cline-any cline-no">&nbsp;</span>
147
- <span class="cline-any cline-no">&nbsp;</span>
148
- <span class="cline-any cline-no">&nbsp;</span>
149
166
  <span class="cline-any cline-neutral">&nbsp;</span>
150
- <span class="cline-any cline-no">&nbsp;</span>
151
167
  <span class="cline-any cline-neutral">&nbsp;</span>
152
168
  <span class="cline-any cline-neutral">&nbsp;</span>
153
169
  <span class="cline-any cline-neutral">&nbsp;</span>
154
170
  <span class="cline-any cline-neutral">&nbsp;</span>
155
171
  <span class="cline-any cline-neutral">&nbsp;</span>
172
+ <span class="cline-any cline-yes">1x</span>
173
+ <span class="cline-any cline-neutral">&nbsp;</span>
156
174
  <span class="cline-any cline-neutral">&nbsp;</span>
157
- <span class="cline-any cline-no">&nbsp;</span>
175
+ <span class="cline-any cline-yes">3x</span>
176
+ <span class="cline-any cline-yes">2x</span>
158
177
  <span class="cline-any cline-neutral">&nbsp;</span>
178
+ <span class="cline-any cline-yes">1x</span>
159
179
  <span class="cline-any cline-neutral">&nbsp;</span>
160
180
  <span class="cline-any cline-neutral">&nbsp;</span>
161
181
  <span class="cline-any cline-neutral">&nbsp;</span>
182
+ <span class="cline-any cline-yes">2x</span>
183
+ <span class="cline-any cline-yes">1x</span>
162
184
  <span class="cline-any cline-neutral">&nbsp;</span>
163
- <span class="cline-any cline-no">&nbsp;</span>
164
- <span class="cline-any cline-no">&nbsp;</span>
165
- <span class="cline-any cline-no">&nbsp;</span>
166
185
  <span class="cline-any cline-neutral">&nbsp;</span>
167
186
  <span class="cline-any cline-neutral">&nbsp;</span>
168
187
  <span class="cline-any cline-neutral">&nbsp;</span>
169
188
  <span class="cline-any cline-neutral">&nbsp;</span>
170
189
  <span class="cline-any cline-neutral">&nbsp;</span>
171
190
  <span class="cline-any cline-neutral">&nbsp;</span>
172
- <span class="cline-any cline-no">&nbsp;</span>
173
191
  <span class="cline-any cline-neutral">&nbsp;</span>
174
192
  <span class="cline-any cline-neutral">&nbsp;</span>
175
193
  <span class="cline-any cline-neutral">&nbsp;</span>
176
- <span class="cline-any cline-no">&nbsp;</span>
177
194
  <span class="cline-any cline-neutral">&nbsp;</span>
178
195
  <span class="cline-any cline-neutral">&nbsp;</span>
179
- <span class="cline-any cline-no">&nbsp;</span>
180
- <span class="cline-any cline-no">&nbsp;</span>
181
196
  <span class="cline-any cline-neutral">&nbsp;</span>
182
- <span class="cline-any cline-no">&nbsp;</span>
197
+ <span class="cline-any cline-yes">2x</span>
198
+ <span class="cline-any cline-yes">6x</span>
199
+ <span class="cline-any cline-yes">6x</span>
200
+ <span class="cline-any cline-yes">6x</span>
201
+ <span class="cline-any cline-yes">4x</span>
183
202
  <span class="cline-any cline-neutral">&nbsp;</span>
203
+ <span class="cline-any cline-yes">2x</span>
204
+ <span class="cline-any cline-yes">1x</span>
184
205
  <span class="cline-any cline-neutral">&nbsp;</span>
185
206
  <span class="cline-any cline-neutral">&nbsp;</span>
186
207
  <span class="cline-any cline-yes">1x</span>
187
- <span class="cline-any cline-no">&nbsp;</span>
188
208
  <span class="cline-any cline-neutral">&nbsp;</span>
189
- <span class="cline-any cline-no">&nbsp;</span>
190
- <span class="cline-any cline-no">&nbsp;</span>
191
- <span class="cline-any cline-no">&nbsp;</span>
192
209
  <span class="cline-any cline-neutral">&nbsp;</span>
193
- <span class="cline-any cline-no">&nbsp;</span>
194
210
  <span class="cline-any cline-neutral">&nbsp;</span>
195
211
  <span class="cline-any cline-neutral">&nbsp;</span>
196
212
  <span class="cline-any cline-neutral">&nbsp;</span>
197
213
  <span class="cline-any cline-neutral">&nbsp;</span>
198
214
  <span class="cline-any cline-neutral">&nbsp;</span>
215
+ <span class="cline-any cline-neutral">&nbsp;</span>
216
+ <span class="cline-any cline-neutral">&nbsp;</span>
217
+ <span class="cline-any cline-neutral">&nbsp;</span>
218
+ <span class="cline-any cline-neutral">&nbsp;</span>
219
+ <span class="cline-any cline-yes">2x</span>
220
+ <span class="cline-any cline-yes">1x</span>
221
+ <span class="cline-any cline-yes">1x</span>
222
+ <span class="cline-any cline-neutral">&nbsp;</span>
223
+ <span class="cline-any cline-neutral">&nbsp;</span>
224
+ <span class="cline-any cline-neutral">&nbsp;</span>
199
225
  <span class="cline-any cline-yes">1x</span>
200
- <span class="cline-any cline-no">&nbsp;</span>
201
- <span class="cline-any cline-no">&nbsp;</span>
202
- <span class="cline-any cline-no">&nbsp;</span>
203
226
  <span class="cline-any cline-neutral">&nbsp;</span>
204
227
  <span class="cline-any cline-neutral">&nbsp;</span>
205
228
  <span class="cline-any cline-neutral">&nbsp;</span>
206
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import CryptoJS from "crypto-js";
207
- import { getConfig } from "../config";
208
- import { INTEGRATION_TYPE } from "../utils/constant";
209
- import { helpers } from "../utils/helpers";
210
- import { ApacuanaAPIError } from "../errors/index";
229
+ <span class="cline-any cline-neutral">&nbsp;</span>
230
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { getConfig } from "../config/index";
211
231
  import { httpRequest } from "../utils/httpClient";
232
+ import helpers from "../utils/helpers";
233
+ import { ApacuanaAPIError } from "../errors";
234
+ import { INTEGRATION_TYPE } from "../utils/constant";
212
235
  &nbsp;
213
- const generateCertOnBoarding = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; {
214
- <span class="cstat-no" title="statement not covered" > try {</span>
215
- const config = <span class="cstat-no" title="statement not covered" >getConfig();</span>
216
- const { userData } = <span class="cstat-no" title="statement not covered" >config;</span>
217
- const keyPair = <span class="cstat-no" title="statement not covered" >await helpers.generateKeyPair();</span>
218
- const { csrBase64 } = <span class="cstat-no" title="statement not covered" >await helpers.generateCSR(keyPair, userData);</span>
219
- &nbsp;
220
- const body = <span class="cstat-no" title="statement not covered" >{</span>
221
- csr: CryptoJS.AES.encrypt(csrBase64, config.secretKey, {
222
- mode: CryptoJS.mode.ECB,
223
- padding: CryptoJS.pad.Pkcs7,
224
- }).toString(),
225
- };
236
+ const generateCertOnBoarding = async (csr = <span class="branch-0 cbranch-no" title="branch not covered" >undefined)</span> =&gt; {
237
+ try {
238
+ const encryptedCSR = helpers.encryptedCsr(csr);
226
239
  &nbsp;
227
- const response = <span class="cstat-no" title="statement not covered" >await httpRequest(</span>
240
+ const response = await httpRequest(
228
241
  "services/api/register/certificate",
229
- body,
242
+ encryptedCSR,
230
243
  "POST"
231
244
  );
232
- &nbsp;
233
- const { cert } = <span class="cstat-no" title="statement not covered" >response;</span>
234
- <span class="cstat-no" title="statement not covered" > if (!cert) {</span>
235
- <span class="cstat-no" title="statement not covered" > throw new ApacuanaAPIError(</span>
236
- "La respuesta de la API no contiene el certificado.",
245
+ const { cert } = response;
246
+ if (!cert) {
247
+ throw new ApacuanaAPIError(
248
+ "The API response does not contain the certificate.",
237
249
  response.status,
238
250
  "INVALID_API_RESPONSE"
239
251
  );
240
252
  }
241
253
  &nbsp;
242
- const exportedPrivateKey = <span class="cstat-no" title="statement not covered" >await helpers.exportPrivateKey(</span>
243
- keyPair.privateKey
244
- );
245
- &nbsp;
246
- <span class="cstat-no" title="statement not covered" > return { cert, privateKey: exportedPrivateKey };</span>
254
+ return { cert, success: true };
247
255
  } catch (error) {
248
- // Se lanza el error capturado, que ya será de tipo ApacuanaAPIError o un Error nativo.
249
- <span class="cstat-no" title="statement not covered" > if (error instanceof ApacuanaAPIError) {</span>
250
- <span class="cstat-no" title="statement not covered" > throw error;</span>
256
+ // The captured error is re-thrown, which will already be of type ApacuanaAPIError or a native Error.
257
+ if (error instanceof ApacuanaAPIError) {
258
+ throw error;
251
259
  }
252
- <span class="cstat-no" title="statement not covered" > throw new Error(`Fallo en la generación del certificado: ${error.message}`);</span>
260
+ throw new Error(`Certificate generation failed: ${error.message}`);
253
261
  }
254
262
  };
255
263
  &nbsp;
256
- export const generateCert = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; {
257
- const { integrationType } = <span class="cstat-no" title="statement not covered" >getConfig();</span>
264
+ const generateCertOnPremise = async () =&gt; {
265
+ throw new ApacuanaAPIError(
266
+ "Certificate generation is not supported for integration type: ONPREMISE",
267
+ 501,
268
+ "NOT_IMPLEMENTED"
269
+ );
270
+ };
258
271
  &nbsp;
259
- <span class="cstat-no" title="statement not covered" > if (integrationType === INTEGRATION_TYPE.ONBOARDING) {</span>
260
- <span class="cstat-no" title="statement not covered" > await generateCertOnBoarding();</span>
261
- } else <span class="cstat-no" title="statement not covered" >if (integrationType === INTEGRATION_TYPE.ONPREMISE) {</span>
262
- // eslint-disable-next-line no-console
263
- <span class="cstat-no" title="statement not covered" > console.log("-&gt; Lógica para On-premise");</span>
264
- // Aquí iría la llamada a httpRequest para el endpoint de on-premise
265
- // return httpRequest('/certs/generate-onpremise', data);
272
+ /**
273
+ * Generates a digital certificate.
274
+ * @param {string} [csr] - Optional Certificate Signing Request (CSR).
275
+ * @returns {Promise&lt;{cert: string, success: boolean}&gt;} Object with the generated certificate and a success indicator.
276
+ * @throws {ApacuanaAPIError} If the CSR is invalid, if the API response does not contain the certificate, or if the integration type is not supported.
277
+ * @throws {Error} If certificate generation fails for another reason.
278
+ */
279
+ export const generateCert = async (csr = <span class="branch-0 cbranch-no" title="branch not covered" >undefined)</span> =&gt; {
280
+ const { integrationType } = getConfig();
281
+ helpers.validateCsr(csr);
282
+ if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
283
+ return generateCertOnBoarding(csr);
284
+ }
285
+ if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
286
+ return generateCertOnPremise();
266
287
  }
288
+ &nbsp;
289
+ throw new ApacuanaAPIError(
290
+ `Unsupported integration type: ${integrationType}`,
291
+ 400,
292
+ "UNSUPPORTED_INTEGRATION_TYPE"
293
+ );
267
294
  };
268
295
  &nbsp;
269
- export const getCertStatus = <span class="fstat-no" title="function not covered" >()</span> =&gt; {
270
- const config = <span class="cstat-no" title="statement not covered" >getConfig();</span>
271
- const status = <span class="cstat-no" title="statement not covered" >helpers.getCertificateStatus(config.userData, false);</span>
272
- <span class="cstat-no" title="statement not covered" > return {</span>
296
+ /**
297
+ * Gets the user's certificate status.
298
+ * @param {boolean} [isCertificateInDevice=false] - Indicates if the certificate is already on the device.
299
+ * @returns {{status: string, success: boolean}} Object with the certificate status and a success indicator.
300
+ */
301
+ export const getCertStatus = (isCertificateInDevice = <span class="branch-0 cbranch-no" title="branch not covered" >false)</span> =&gt; {
302
+ const config = getConfig();
303
+ const status = helpers.getCertificateStatus(
304
+ config.userData,
305
+ isCertificateInDevice
306
+ );
307
+ return {
273
308
  status,
309
+ success: true,
274
310
  };
275
311
  };
276
312
  &nbsp;</pre></td></tr></table></pre>
@@ -280,7 +316,7 @@ export const getCertStatus = <span class="fstat-no" title="function not covered"
280
316
  <div class='footer quiet pad2 space-top1 center small'>
281
317
  Code coverage generated by
282
318
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
283
- at 2025-08-15T20:05:10.802Z
319
+ at 2025-08-22T21:07:16.060Z
284
320
  </div>
285
321
  <script src="../../prettify.js"></script>
286
322
  <script>
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">38.18% </span>
26
+ <span class="strong">65.32% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>21/55</span>
28
+ <span class='fraction'>81/124</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">41.37% </span>
33
+ <span class="strong">51.51% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>12/29</span>
35
+ <span class='fraction'>34/66</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">20% </span>
40
+ <span class="strong">61.11% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>1/5</span>
42
+ <span class='fraction'>11/18</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">38.18% </span>
47
+ <span class="strong">65.32% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>21/55</span>
49
+ <span class='fraction'>81/124</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line low'></div>
64
+ <div class='status-line medium'></div>
65
65
  <div class="pad1">
66
66
  <table class="coverage-summary">
67
67
  <thead>
@@ -79,18 +79,18 @@
79
79
  </tr>
80
80
  </thead>
81
81
  <tbody><tr>
82
- <td class="file low" data-value="certs.js"><a href="certs.js.html">certs.js</a></td>
83
- <td data-value="11.53" class="pic low">
84
- <div class="chart"><div class="cover-fill" style="width: 11%"></div><div class="cover-empty" style="width: 89%"></div></div>
82
+ <td class="file high" data-value="certs.js"><a href="certs.js.html">certs.js</a></td>
83
+ <td data-value="100" class="pic high">
84
+ <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
85
85
  </td>
86
- <td data-value="11.53" class="pct low">11.53%</td>
87
- <td data-value="26" class="abs low">3/26</td>
88
- <td data-value="0" class="pct low">0%</td>
89
- <td data-value="8" class="abs low">0/8</td>
90
- <td data-value="0" class="pct low">0%</td>
91
- <td data-value="3" class="abs low">0/3</td>
92
- <td data-value="11.53" class="pct low">11.53%</td>
93
- <td data-value="26" class="abs low">3/26</td>
86
+ <td data-value="100" class="pct high">100%</td>
87
+ <td data-value="25" class="abs high">25/25</td>
88
+ <td data-value="72.72" class="pct medium">72.72%</td>
89
+ <td data-value="11" class="abs medium">8/11</td>
90
+ <td data-value="100" class="pct high">100%</td>
91
+ <td data-value="4" class="abs high">4/4</td>
92
+ <td data-value="100" class="pct high">100%</td>
93
+ <td data-value="25" class="abs high">25/25</td>
94
94
  </tr>
95
95
 
96
96
  <tr>
@@ -108,19 +108,34 @@
108
108
  <td data-value="12" class="abs low">1/12</td>
109
109
  </tr>
110
110
 
111
+ <tr>
112
+ <td class="file medium" data-value="signatures.js"><a href="signatures.js.html">signatures.js</a></td>
113
+ <td data-value="56.75" class="pic medium">
114
+ <div class="chart"><div class="cover-fill" style="width: 56%"></div><div class="cover-empty" style="width: 44%"></div></div>
115
+ </td>
116
+ <td data-value="56.75" class="pct medium">56.75%</td>
117
+ <td data-value="74" class="abs medium">42/74</td>
118
+ <td data-value="42.85" class="pct low">42.85%</td>
119
+ <td data-value="35" class="abs low">15/35</td>
120
+ <td data-value="50" class="pct medium">50%</td>
121
+ <td data-value="12" class="abs medium">6/12</td>
122
+ <td data-value="56.75" class="pct medium">56.75%</td>
123
+ <td data-value="74" class="abs medium">42/74</td>
124
+ </tr>
125
+
111
126
  <tr>
112
127
  <td class="file high" data-value="users.js"><a href="users.js.html">users.js</a></td>
113
128
  <td data-value="100" class="pic high">
114
129
  <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
115
130
  </td>
116
131
  <td data-value="100" class="pct high">100%</td>
117
- <td data-value="17" class="abs high">17/17</td>
118
- <td data-value="92.3" class="pct high">92.3%</td>
119
- <td data-value="13" class="abs high">12/13</td>
132
+ <td data-value="13" class="abs high">13/13</td>
133
+ <td data-value="91.66" class="pct high">91.66%</td>
134
+ <td data-value="12" class="abs high">11/12</td>
120
135
  <td data-value="100" class="pct high">100%</td>
121
136
  <td data-value="1" class="abs high">1/1</td>
122
137
  <td data-value="100" class="pct high">100%</td>
123
- <td data-value="17" class="abs high">17/17</td>
138
+ <td data-value="13" class="abs high">13/13</td>
124
139
  </tr>
125
140
 
126
141
  </tbody>
@@ -131,7 +146,7 @@
131
146
  <div class='footer quiet pad2 space-top1 center small'>
132
147
  Code coverage generated by
133
148
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
134
- at 2025-08-15T20:05:10.802Z
149
+ at 2025-08-22T21:07:16.060Z
135
150
  </div>
136
151
  <script src="../../prettify.js"></script>
137
152
  <script>
@@ -199,7 +199,7 @@ export default requestRevocation;
199
199
  <div class='footer quiet pad2 space-top1 center small'>
200
200
  Code coverage generated by
201
201
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
202
- at 2025-08-15T20:05:10.802Z
202
+ at 2025-08-22T21:07:16.060Z
203
203
  </div>
204
204
  <script src="../../prettify.js"></script>
205
205
  <script>