apacuana-sdk-core 0.6.0 → 0.7.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.
- package/README.md +105 -250
- package/babel.config.cjs +11 -0
- package/coverage/clover.xml +189 -195
- package/coverage/coverage-final.json +8 -8
- package/coverage/lcov-report/api/index.html +131 -0
- package/coverage/lcov-report/api/signatures.js.html +1093 -0
- package/coverage/lcov-report/api/users.js.html +292 -0
- package/coverage/lcov-report/config/index.html +116 -0
- package/coverage/lcov-report/config/index.js.html +208 -0
- package/coverage/lcov-report/errors/index.html +116 -0
- package/coverage/lcov-report/errors/index.js.html +148 -0
- package/coverage/lcov-report/index.html +41 -41
- package/coverage/lcov-report/src/api/certs.js.html +55 -34
- package/coverage/lcov-report/src/api/index.html +25 -25
- package/coverage/lcov-report/src/api/revocations.js.html +135 -30
- package/coverage/lcov-report/src/api/signatures.js.html +76 -4
- package/coverage/lcov-report/src/api/users.js.html +1 -1
- package/coverage/lcov-report/src/config/index.html +13 -13
- package/coverage/lcov-report/src/config/index.js.html +69 -18
- package/coverage/lcov-report/src/errors/index.html +1 -1
- package/coverage/lcov-report/src/errors/index.js.html +8 -8
- package/coverage/lcov-report/src/index.html +15 -15
- package/coverage/lcov-report/src/index.js.html +14 -68
- package/coverage/lcov-report/src/utils/constant.js.html +1 -1
- package/coverage/lcov-report/src/utils/helpers.js.html +18 -51
- package/coverage/lcov-report/src/utils/httpClient.js.html +6 -72
- package/coverage/lcov-report/src/utils/index.html +19 -19
- package/coverage/lcov-report/utils/constant.js.html +145 -0
- package/coverage/lcov-report/utils/httpClient.js.html +646 -0
- package/coverage/lcov-report/utils/index.html +131 -0
- package/coverage/lcov.info +334 -337
- package/dist/api/certs.d.ts +11 -1
- package/dist/api/revocations.d.ts +32 -12
- package/dist/api/signatures.d.ts +37 -5
- package/dist/config/index.d.ts +13 -2
- package/dist/index.d.ts +4 -1
- package/dist/index.js +436 -290
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +436 -290
- package/dist/index.mjs.map +1 -1
- package/dist/utils/helpers.d.ts +1 -1
- package/jest.config.cjs +6 -1
- package/package.json +12 -7
- package/rollup.config.js +1 -1
- package/src/api/certs.js +17 -10
- package/src/api/revocations.js +55 -20
- package/src/api/signatures.js +25 -1
- package/src/config/index.js +25 -8
- package/src/index.js +4 -22
- package/src/utils/helpers.js +11 -22
- package/src/utils/httpClient.js +0 -22
- package/tests/api/certs.test.js +30 -48
- package/tsconfig.json +2 -1
- package/.babelrc +0 -3
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ declare function encryptedCsr(csr: any, encryptKey?: string): {
|
|
|
17
17
|
csr: any;
|
|
18
18
|
};
|
|
19
19
|
declare function validateOnBoardingSignerData(signerData: any): void;
|
|
20
|
-
declare function validateCsr(
|
|
20
|
+
declare function validateCsr(encryptedCSR: any): void;
|
|
21
21
|
declare function validateGetDocsData(data: any): void;
|
|
22
22
|
declare function validateGetDigestData(signData: any): void;
|
|
23
23
|
declare function validateOnBoardingSignDocumentData(signData: any): void;
|
package/jest.config.cjs
CHANGED
|
@@ -3,5 +3,10 @@ module.exports = {
|
|
|
3
3
|
testEnvironment: "node", // Para tests de backend, si tu SDK es universal
|
|
4
4
|
collectCoverage: true,
|
|
5
5
|
coverageDirectory: "coverage",
|
|
6
|
-
|
|
6
|
+
transformIgnorePatterns: [
|
|
7
|
+
"/node_modules/(?!react-native-get-random-values/)",
|
|
8
|
+
],
|
|
9
|
+
transform: {
|
|
10
|
+
"^.+\\.jsx?$": "babel-jest",
|
|
11
|
+
},
|
|
7
12
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apacuana-sdk-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Core SDK para interacciones con las APIs de Apacuana.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -25,20 +25,25 @@
|
|
|
25
25
|
"author": "Gega",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@babel/core": "^7.24.
|
|
29
|
-
"@babel/
|
|
28
|
+
"@babel/core": "^7.24.5",
|
|
29
|
+
"@babel/plugin-transform-class-properties": "^7.24.1",
|
|
30
|
+
"@babel/plugin-transform-private-methods": "^7.24.1",
|
|
31
|
+
"@babel/plugin-transform-private-property-in-object": "^7.24.1",
|
|
32
|
+
"@babel/preset-env": "^7.24.5",
|
|
33
|
+
"@babel/preset-flow": "^7.24.1",
|
|
30
34
|
"@rollup/plugin-babel": "^6.0.4",
|
|
31
|
-
"@rollup/plugin-commonjs": "^
|
|
35
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
32
36
|
"@rollup/plugin-json": "^6.1.0",
|
|
33
|
-
"@rollup/plugin-node-resolve": "^
|
|
37
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
38
|
+
"babel-jest": "^29.7.0",
|
|
34
39
|
"eslint": "^8.57.0",
|
|
35
40
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
36
41
|
"eslint-config-prettier": "^10.1.8",
|
|
37
42
|
"eslint-plugin-import": "^2.29.1",
|
|
38
43
|
"jest": "^29.7.0",
|
|
39
|
-
"rollup": "^4.18.0",
|
|
40
44
|
"rimraf": "^5.0.7",
|
|
41
|
-
"
|
|
45
|
+
"rollup": "^4.17.2",
|
|
46
|
+
"typescript": "^5.9.2"
|
|
42
47
|
},
|
|
43
48
|
"engines": {
|
|
44
49
|
"node": ">=14.0.0"
|
package/rollup.config.js
CHANGED
package/src/api/certs.js
CHANGED
|
@@ -7,6 +7,7 @@ import { INTEGRATION_TYPE } from "../utils/constant";
|
|
|
7
7
|
/**
|
|
8
8
|
* @typedef {object} GenerateCertResponse
|
|
9
9
|
* @property {string} cert - El certificado generado en formato string.
|
|
10
|
+
* @property {string} certifiedid - El ID del certificado generado.
|
|
10
11
|
* @property {boolean} success - Indica si la operación fue exitosa.
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -16,17 +17,23 @@ import { INTEGRATION_TYPE } from "../utils/constant";
|
|
|
16
17
|
* @property {boolean} success - Indica si la operación fue exitosa.
|
|
17
18
|
*/
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {object} EncryptedCSRObject
|
|
22
|
+
* @property {string} csr - The encrypted Certificate Signing Request.
|
|
23
|
+
*/
|
|
22
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {EncryptedCSRObject} encryptedCSR
|
|
27
|
+
*/
|
|
28
|
+
const generateCertOnBoarding = async (encryptedCSR) => {
|
|
29
|
+
try {
|
|
23
30
|
const response = await httpRequest(
|
|
24
31
|
"services/api/register/certificate",
|
|
25
32
|
encryptedCSR,
|
|
26
33
|
"POST"
|
|
27
34
|
);
|
|
28
|
-
const { cert } = response;
|
|
29
|
-
if (!cert) {
|
|
35
|
+
const { cert, certifiedid } = response;
|
|
36
|
+
if (!cert || !certifiedid) {
|
|
30
37
|
throw new ApacuanaAPIError(
|
|
31
38
|
"The API response does not contain the certificate.",
|
|
32
39
|
response.status,
|
|
@@ -34,7 +41,7 @@ const generateCertOnBoarding = async (csr = undefined) => {
|
|
|
34
41
|
);
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
return { cert, success: true };
|
|
44
|
+
return { cert, certifiedid, success: true };
|
|
38
45
|
} catch (error) {
|
|
39
46
|
// The captured error is re-thrown, which will already be of type ApacuanaAPIError or a native Error.
|
|
40
47
|
if (error instanceof ApacuanaAPIError) {
|
|
@@ -54,16 +61,16 @@ const generateCertOnPremise = async () => {
|
|
|
54
61
|
|
|
55
62
|
/**
|
|
56
63
|
* Generates a digital certificate.
|
|
57
|
-
* @param {
|
|
64
|
+
* @param {EncryptedCSRObject} encryptedCSR - Certificate Signing Request (CSR) object.
|
|
58
65
|
* @returns {Promise<GenerateCertResponse>} Object with the generated certificate and a success indicator.
|
|
59
66
|
* @throws {ApacuanaAPIError} If the CSR is invalid, if the API response does not contain the certificate, or if the integration type is not supported.
|
|
60
67
|
* @throws {Error} If certificate generation fails for another reason.
|
|
61
68
|
*/
|
|
62
|
-
export const generateCert = async (
|
|
69
|
+
export const generateCert = async (encryptedCSR) => {
|
|
63
70
|
const { integrationType } = getConfig();
|
|
64
|
-
helpers.validateCsr(
|
|
71
|
+
helpers.validateCsr(encryptedCSR);
|
|
65
72
|
if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
|
|
66
|
-
return generateCertOnBoarding(
|
|
73
|
+
return generateCertOnBoarding(encryptedCSR);
|
|
67
74
|
}
|
|
68
75
|
if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
|
|
69
76
|
return generateCertOnPremise();
|
package/src/api/revocations.js
CHANGED
|
@@ -12,37 +12,72 @@ import { ApacuanaAPIError } from "../errors/index";
|
|
|
12
12
|
* @param {string} reasonCode - Código o descripción del motivo de la revocación.
|
|
13
13
|
* @returns {Promise<RequestRevocationResponse>} Objeto con el estado de la solicitud de revocación.
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} RevocationResponse
|
|
17
|
+
* @property {boolean} success - Indicates if the revocation request was successful.
|
|
18
|
+
* @property {string} [message] - A message providing details about the outcome.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {object} RevocationReason
|
|
23
|
+
* @property {string} code - The code for the revocation reason.
|
|
24
|
+
* @property {string} description - The description of the revocation reason.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {object} RevocationReasonsResponse
|
|
29
|
+
* @property {boolean} success - Indicates if the request was successful.
|
|
30
|
+
* @property {RevocationReason[]} reasons - A list of revocation reasons.
|
|
31
|
+
*/
|
|
20
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Requests the revocation of a certificate.
|
|
35
|
+
* @param {number} reasonCode - Código o descripción del motivo de la revocación.
|
|
36
|
+
* @returns {Promise<RevocationResponse>} An object indicating the success of the request.
|
|
37
|
+
* @throws {ApacuanaAPIError} If the revocation request fails.
|
|
38
|
+
*/
|
|
39
|
+
export const requestRevocation = async (reasonCode) => {
|
|
21
40
|
if (!reasonCode) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
"ID de certificado y motivo son requeridos para requestRevocation."
|
|
24
|
-
);
|
|
41
|
+
throw new Error("Código de motivo es requerido para requestRevocation.");
|
|
25
42
|
}
|
|
26
43
|
|
|
27
44
|
try {
|
|
28
45
|
const response = await httpRequest(
|
|
29
|
-
"
|
|
46
|
+
"services/api/onboardingclient/requestcert",
|
|
30
47
|
{ reason: reasonCode },
|
|
31
48
|
"POST"
|
|
32
49
|
);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
throw new ApacuanaAPIError(
|
|
36
|
-
response.message || "Error desconocido al solicitar revocación."
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
revocationStatus: response.status || "pending",
|
|
41
|
-
requestId: response.id,
|
|
42
|
-
};
|
|
50
|
+
|
|
51
|
+
return response;
|
|
43
52
|
} catch (error) {
|
|
44
53
|
throw new Error(`Fallo en la solicitud de revocación: ${error.message}`);
|
|
45
54
|
}
|
|
46
55
|
};
|
|
47
56
|
|
|
48
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Retrieves the available reasons for certificate revocation.
|
|
59
|
+
* @returns {Promise<RevocationReasonsResponse>} An object containing the list of revocation reasons.
|
|
60
|
+
* @throws {ApacuanaAPIError} If fetching the reasons fails.
|
|
61
|
+
*/
|
|
62
|
+
export const getRevocationReasons = async () => {
|
|
63
|
+
try {
|
|
64
|
+
const response = await httpRequest(
|
|
65
|
+
"config/api/revocation/reasonsonboarding",
|
|
66
|
+
{},
|
|
67
|
+
"GET"
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (!response.records) {
|
|
71
|
+
throw new ApacuanaAPIError("Failed to fetch revocation reasons.");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return response.records;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof ApacuanaAPIError) {
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
throw new Error(
|
|
80
|
+
"Failed to get revocation reasons. Please try again later."
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
};
|
package/src/api/signatures.js
CHANGED
|
@@ -21,7 +21,6 @@ import { INTEGRATION_TYPE } from "../utils/constant";
|
|
|
21
21
|
* Define la estructura de datos para añadir un firmante.
|
|
22
22
|
* @typedef {object} SignerData
|
|
23
23
|
* @property {string} docId - Identificador único del documento.
|
|
24
|
-
* @property {Signer} signer - Objeto con la información del firmante.
|
|
25
24
|
*/
|
|
26
25
|
|
|
27
26
|
/**
|
|
@@ -280,6 +279,31 @@ export const getDigest = async (signData) => {
|
|
|
280
279
|
* @returns {Promise<AddSignerResponse>} Una promesa que resuelve a un objeto con el resultado de la operación.
|
|
281
280
|
* @throws {ApacuanaAPIError} Si los datos del firmante son inválidos, la llamada a la API falla, o el tipo de integración no es soportado.
|
|
282
281
|
*/
|
|
282
|
+
/**
|
|
283
|
+
* @typedef {object} SignaturePosition
|
|
284
|
+
* @property {number} page - The page number for the signature.
|
|
285
|
+
* @property {number} x - The x-coordinate for the signature's position (from 0 to 1).
|
|
286
|
+
* @property {number} y - The y-coordinate for the signature's position (from 0 to 1).
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* @typedef {object} OnboardingSignerData
|
|
291
|
+
* @property {string} name - The name of the document.
|
|
292
|
+
* @property {string} reference - An external reference for the document.
|
|
293
|
+
* @property {string} typedoc - The type of document of the signer (e.g., "V", "E", "J").
|
|
294
|
+
* @property {string} doc - The document number of the signer.
|
|
295
|
+
* @property {SignaturePosition[]} signature - An array of signature positions.
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Adds a new signer to the signature process.
|
|
300
|
+
* This function acts as a dispatcher, delegating to the appropriate implementation
|
|
301
|
+
* based on the configured integration type.
|
|
302
|
+
*
|
|
303
|
+
* @param {OnboardingSignerData | object} signerData - The signer's data. The structure depends on the integration type.
|
|
304
|
+
* @returns {Promise<object>} The result from the API.
|
|
305
|
+
* @throws {ApacuanaAPIError} If signerData is invalid or if the integration type is not supported.
|
|
306
|
+
*/
|
|
283
307
|
export const addSigner = async (signerData) => {
|
|
284
308
|
if (
|
|
285
309
|
!signerData ||
|
package/src/config/index.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
// src/config/index.js
|
|
2
|
-
import { INTEGRATION_TYPE } from
|
|
2
|
+
import { INTEGRATION_TYPE } from "../utils/constant";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {object} SDKConfig
|
|
6
|
+
* @property {string} apiUrl
|
|
7
|
+
* @property {string} secretKey
|
|
8
|
+
* @property {string} apiKey
|
|
9
|
+
* @property {string} verificationId
|
|
10
|
+
* @property {string} customerId
|
|
11
|
+
* @property {string} integrationType
|
|
12
|
+
* @property {object} [userData]
|
|
13
|
+
* @property {string} [token]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const defaultConfig = {
|
|
5
17
|
apiUrl: "",
|
|
6
18
|
secretKey: "",
|
|
7
19
|
apiKey: "",
|
|
@@ -12,8 +24,12 @@ let config = {
|
|
|
12
24
|
token: undefined,
|
|
13
25
|
};
|
|
14
26
|
|
|
27
|
+
/** @type {SDKConfig} */
|
|
28
|
+
let config = { ...defaultConfig };
|
|
29
|
+
|
|
15
30
|
export const setConfig = (newConfig) => {
|
|
16
|
-
const { apiUrl, secretKey, apiKey, verificationId, integrationType } =
|
|
31
|
+
const { apiUrl, secretKey, apiKey, verificationId, integrationType } =
|
|
32
|
+
newConfig;
|
|
17
33
|
|
|
18
34
|
if (!apiUrl || !secretKey || !apiKey || !verificationId || !integrationType) {
|
|
19
35
|
throw new Error(
|
|
@@ -26,16 +42,17 @@ export const setConfig = (newConfig) => {
|
|
|
26
42
|
if (!Object.values(INTEGRATION_TYPE).includes(integrationType)) {
|
|
27
43
|
throw new Error(
|
|
28
44
|
`Apacuana SDK: El valor de integrationType ('${integrationType}') no es válido. ` +
|
|
29
|
-
|
|
45
|
+
`Valores permitidos: ${Object.values(INTEGRATION_TYPE).join(", ")}`
|
|
30
46
|
);
|
|
31
47
|
}
|
|
32
48
|
|
|
33
49
|
config = { ...config, ...newConfig };
|
|
34
50
|
// eslint-disable-next-line no-console
|
|
35
|
-
console.log("[Config] SDK Configuración actualizada (desde config):", {
|
|
36
|
-
...config,
|
|
37
|
-
secretKey: "********",
|
|
38
|
-
});
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
export const getConfig = () => ({ ...config });
|
|
54
|
+
|
|
55
|
+
export const cleanConfig = () => {
|
|
56
|
+
config = { ...defaultConfig };
|
|
57
|
+
console.log("Apacuana SDK: Configuración limpiada.");
|
|
58
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { setConfig, getConfig } from "./config/index";
|
|
1
|
+
import { setConfig, getConfig, cleanConfig } from "./config/index";
|
|
2
2
|
import { initHttpClient, setAuthToken } from "./utils/httpClient";
|
|
3
3
|
import getCustomer from "./api/users";
|
|
4
|
-
import requestRevocation from "./api/revocations";
|
|
4
|
+
import { requestRevocation, getRevocationReasons } from "./api/revocations";
|
|
5
5
|
import { generateCert, getCertStatus } from "./api/certs";
|
|
6
6
|
import { addSigner, getDigest, getDocs, signDocument } from "./api/signatures";
|
|
7
7
|
|
|
@@ -19,19 +19,9 @@ const apacuana = {
|
|
|
19
19
|
* @returns {Promise<object>} retorna los detalles del usuario si la inicialización es exitosa.
|
|
20
20
|
*/
|
|
21
21
|
init: async (config) => {
|
|
22
|
-
// eslint-disable-next-line no-console
|
|
23
|
-
console.log(
|
|
24
|
-
"-> apacuana-sdk: Iniciando configuración y validando usuario..."
|
|
25
|
-
);
|
|
26
|
-
|
|
27
22
|
try {
|
|
28
|
-
// 1. Guardar la configuración inicial
|
|
29
23
|
setConfig(config);
|
|
30
|
-
|
|
31
|
-
// 2. Inicializar el cliente HTTP con la configuración guardada
|
|
32
24
|
initHttpClient();
|
|
33
|
-
|
|
34
|
-
// 3. Opcional: Validar que la configuración se guardó correctamente
|
|
35
25
|
const currentConfig = getConfig();
|
|
36
26
|
if (!currentConfig.customerId) {
|
|
37
27
|
throw new Error(
|
|
@@ -39,19 +29,9 @@ const apacuana = {
|
|
|
39
29
|
" correctamente."
|
|
40
30
|
);
|
|
41
31
|
}
|
|
42
|
-
|
|
43
|
-
// 4. Obtener los detalles del usuario como parte de la inicialización
|
|
44
32
|
const { token, userData } = await getCustomer();
|
|
45
|
-
|
|
46
|
-
// Opcional: Guardar los detalles del usuario en la configuración
|
|
47
|
-
// para acceso futuro si fuera necesario
|
|
48
33
|
setConfig({ ...currentConfig, token, userData });
|
|
49
34
|
setAuthToken(token);
|
|
50
|
-
// eslint-disable-next-line no-console
|
|
51
|
-
console.log(
|
|
52
|
-
"-> apacuana-sdk: Inicialización completa. Usuario validado:",
|
|
53
|
-
token
|
|
54
|
-
);
|
|
55
35
|
return true;
|
|
56
36
|
} catch (error) {
|
|
57
37
|
// eslint-disable-next-line no-console
|
|
@@ -59,6 +39,7 @@ const apacuana = {
|
|
|
59
39
|
throw error;
|
|
60
40
|
}
|
|
61
41
|
},
|
|
42
|
+
close: () => cleanConfig(),
|
|
62
43
|
getConfig,
|
|
63
44
|
requestRevocation,
|
|
64
45
|
getCertStatus,
|
|
@@ -68,6 +49,7 @@ const apacuana = {
|
|
|
68
49
|
generateCert,
|
|
69
50
|
signDocument,
|
|
70
51
|
getDigest,
|
|
52
|
+
getRevocationReasons,
|
|
71
53
|
};
|
|
72
54
|
|
|
73
55
|
export default apacuana;
|
package/src/utils/helpers.js
CHANGED
|
@@ -143,29 +143,18 @@ const validateOnBoardingSignerData = (signerData) => {
|
|
|
143
143
|
});
|
|
144
144
|
};
|
|
145
145
|
|
|
146
|
-
const validateCsr = (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (typeof csr !== "string" || csr.trim() === "") {
|
|
158
|
-
throw new ApacuanaAPIError(
|
|
159
|
-
"El CSR debe ser una cadena de texto válida y no puede estar vacía.",
|
|
160
|
-
400,
|
|
161
|
-
"INVALID_PARAMETER_FORMAT"
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (!base64Regex.test(csr)) {
|
|
146
|
+
const validateCsr = (encryptedCSR) => {
|
|
147
|
+
if (
|
|
148
|
+
!encryptedCSR ||
|
|
149
|
+
typeof encryptedCSR !== "object" ||
|
|
150
|
+
!encryptedCSR.csr ||
|
|
151
|
+
typeof encryptedCSR.csr !== "string" ||
|
|
152
|
+
encryptedCSR.csr.trim() === ""
|
|
153
|
+
) {
|
|
166
154
|
throw new ApacuanaAPIError(
|
|
167
|
-
"
|
|
168
|
-
|
|
155
|
+
'The "encryptedCSR" parameter is required and must be an object ' +
|
|
156
|
+
'with a non-empty "csr" string property.',
|
|
157
|
+
400, // Bad Request
|
|
169
158
|
"INVALID_PARAMETER_FORMAT"
|
|
170
159
|
);
|
|
171
160
|
}
|
package/src/utils/httpClient.js
CHANGED
|
@@ -83,12 +83,6 @@ export const initHttpClient = () => {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
);
|
|
86
|
-
|
|
87
|
-
// eslint-disable-next-line no-console
|
|
88
|
-
console.log(
|
|
89
|
-
"[HTTP Client] Cliente HTTP (Axios) REAL inicializado con URL base:",
|
|
90
|
-
config.apiUrl
|
|
91
|
-
);
|
|
92
86
|
};
|
|
93
87
|
|
|
94
88
|
/**
|
|
@@ -109,9 +103,6 @@ export const setAuthToken = (token) => {
|
|
|
109
103
|
// Actualizamos la cabecera Authorization de la instancia de Axios.
|
|
110
104
|
axiosInstance.defaults.headers.common.Authorization = `Bearer ${token}`;
|
|
111
105
|
// eslint-disable-next-line no-console
|
|
112
|
-
console.log(
|
|
113
|
-
"[HTTP Client] Cabecera Authorization actualizada con nuevo token."
|
|
114
|
-
);
|
|
115
106
|
};
|
|
116
107
|
|
|
117
108
|
/**
|
|
@@ -137,18 +128,6 @@ export const httpRequest = async (path, data = {}, method = "POST") => {
|
|
|
137
128
|
...data,
|
|
138
129
|
};
|
|
139
130
|
|
|
140
|
-
// eslint-disable-next-line no-console
|
|
141
|
-
console.log(
|
|
142
|
-
`[HTTP Client] Realizando petición ${method} a: ${axiosInstance.defaults.baseURL}${path}`
|
|
143
|
-
);
|
|
144
|
-
// eslint-disable-next-line no-console
|
|
145
|
-
console.log(
|
|
146
|
-
"[HTTP Client] Headers (via Axios config):",
|
|
147
|
-
axiosInstance.defaults.headers
|
|
148
|
-
);
|
|
149
|
-
// eslint-disable-next-line no-console
|
|
150
|
-
console.log("[HTTP Client] Datos enviados:", dataToSend);
|
|
151
|
-
|
|
152
131
|
try {
|
|
153
132
|
let response;
|
|
154
133
|
switch (method.toUpperCase()) {
|
|
@@ -175,7 +154,6 @@ export const httpRequest = async (path, data = {}, method = "POST") => {
|
|
|
175
154
|
// Si la promesa se resolvió, la respuesta es exitosa.
|
|
176
155
|
// El interceptor ya manejó los errores 4xx/5xx y los errores lógicos 2xx.
|
|
177
156
|
// eslint-disable-next-line no-console
|
|
178
|
-
console.log(`[HTTP Client] Respuesta exitosa de ${path}:`, response.data);
|
|
179
157
|
return response.data;
|
|
180
158
|
} catch (error) {
|
|
181
159
|
// Si la petición falla, el interceptor ya procesó el error.
|
package/tests/api/certs.test.js
CHANGED
|
@@ -15,42 +15,38 @@ describe("Certificate API - certs.js", () => {
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
describe("generateCert", () => {
|
|
18
|
-
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// TEST 1: Probar el camino feliz de ONBOARDING
|
|
23
|
+
it("should call generateCertOnBoarding for ONBOARDING integration", async () => {
|
|
19
24
|
getConfig.mockReturnValue({
|
|
20
25
|
integrationType: INTEGRATION_TYPE.ONBOARDING,
|
|
21
26
|
});
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
const mockEncryptedCsr = { csr: "onboarding-csr" };
|
|
28
|
+
const mockApiResponse = {
|
|
29
|
+
cert: "onboarding-cert",
|
|
30
|
+
certifiedid: "onboarding-certified-id",
|
|
31
|
+
};
|
|
32
|
+
httpRequest.mockResolvedValue(mockApiResponse);
|
|
24
33
|
|
|
25
|
-
const result = await generateCert(
|
|
34
|
+
const result = await generateCert(mockEncryptedCsr);
|
|
26
35
|
|
|
27
|
-
expect(helpers.validateCsr).toHaveBeenCalledWith("some-csr");
|
|
28
|
-
expect(helpers.encryptedCsr).toHaveBeenCalledWith("some-csr");
|
|
29
36
|
expect(httpRequest).toHaveBeenCalledWith(
|
|
30
|
-
"services/api/register/certificate",
|
|
31
|
-
|
|
37
|
+
"services/api/register/certificate", // Endpoint de Onboarding
|
|
38
|
+
mockEncryptedCsr,
|
|
32
39
|
"POST"
|
|
33
40
|
);
|
|
34
|
-
expect(result).toEqual({
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
getConfig.mockReturnValue({
|
|
39
|
-
integrationType: INTEGRATION_TYPE.ONBOARDING,
|
|
41
|
+
expect(result).toEqual({
|
|
42
|
+
cert: "onboarding-cert",
|
|
43
|
+
certifiedid: "onboarding-certified-id",
|
|
44
|
+
success: true,
|
|
40
45
|
});
|
|
41
|
-
helpers.encryptedCsr.mockReturnValue("encrypted-csr");
|
|
42
|
-
httpRequest.mockResolvedValue({ success: false });
|
|
43
|
-
|
|
44
|
-
await expect(generateCert("some-csr")).rejects.toThrow(
|
|
45
|
-
new ApacuanaAPIError(
|
|
46
|
-
"The API response does not contain the certificate.",
|
|
47
|
-
undefined,
|
|
48
|
-
"INVALID_API_RESPONSE"
|
|
49
|
-
)
|
|
50
|
-
);
|
|
51
46
|
});
|
|
52
47
|
|
|
53
|
-
|
|
48
|
+
// TEST 2: Probar el error de ONPREMISE
|
|
49
|
+
it("should throw an error for ONPREMISE integration", async () => {
|
|
54
50
|
getConfig.mockReturnValue({
|
|
55
51
|
integrationType: INTEGRATION_TYPE.ONPREMISE,
|
|
56
52
|
});
|
|
@@ -64,34 +60,20 @@ describe("Certificate API - certs.js", () => {
|
|
|
64
60
|
);
|
|
65
61
|
});
|
|
66
62
|
|
|
67
|
-
|
|
63
|
+
// TEST 3: Probar el error para un tipo inválido
|
|
64
|
+
it("should throw an error for an unsupported integration type", async () => {
|
|
68
65
|
getConfig.mockReturnValue({ integrationType: "INVALID_TYPE" });
|
|
69
|
-
await expect(generateCert("some-csr")).rejects.toThrow(
|
|
70
|
-
"Unsupported integration type: INVALID_TYPE"
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should re-throw ApacuanaAPIError if httpRequest fails", async () => {
|
|
75
|
-
getConfig.mockReturnValue({
|
|
76
|
-
integrationType: INTEGRATION_TYPE.ONBOARDING,
|
|
77
|
-
});
|
|
78
|
-
const apiError = new ApacuanaAPIError("API Error", 500, "API_ERROR");
|
|
79
|
-
httpRequest.mockRejectedValue(apiError);
|
|
80
|
-
|
|
81
|
-
await expect(generateCert("some-csr")).rejects.toThrow(apiError);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("should throw a generic error if something else fails", async () => {
|
|
85
|
-
getConfig.mockReturnValue({
|
|
86
|
-
integrationType: INTEGRATION_TYPE.ONBOARDING,
|
|
87
|
-
});
|
|
88
|
-
const genericError = new Error("Something failed");
|
|
89
|
-
httpRequest.mockRejectedValue(genericError);
|
|
90
66
|
|
|
91
67
|
await expect(generateCert("some-csr")).rejects.toThrow(
|
|
92
|
-
|
|
68
|
+
new ApacuanaAPIError(
|
|
69
|
+
"Unsupported integration type: INVALID_TYPE",
|
|
70
|
+
400,
|
|
71
|
+
"UNSUPPORTED_INTEGRATION_TYPE"
|
|
72
|
+
)
|
|
93
73
|
);
|
|
94
74
|
});
|
|
75
|
+
|
|
76
|
+
// Se eliminan los otros tests que asumían un comportamiento "estándar"
|
|
95
77
|
});
|
|
96
78
|
|
|
97
79
|
describe("getCertStatus", () => {
|
package/tsconfig.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "es2020",
|
|
4
4
|
"module": "esnext",
|
|
5
|
+
"lib": ["es2022", "dom"],
|
|
5
6
|
"allowJs": true,
|
|
6
7
|
"declaration": true,
|
|
7
8
|
"emitDeclarationOnly": true,
|
|
@@ -11,5 +12,5 @@
|
|
|
11
12
|
"esModuleInterop": true
|
|
12
13
|
},
|
|
13
14
|
"include": ["src"],
|
|
14
|
-
"exclude": ["
|
|
15
|
+
"exclude": ["nodev_modules", "dist", "tests"]
|
|
15
16
|
}
|
package/.babelrc
DELETED