apacuana-sdk-core 0.1.0 → 0.2.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 +117 -46
- package/coverage/clover.xml +205 -91
- package/coverage/coverage-final.json +9 -6
- package/coverage/lcov-report/index.html +48 -33
- package/coverage/lcov-report/src/api/certs.js.html +74 -83
- package/coverage/lcov-report/src/api/index.html +36 -21
- package/coverage/lcov-report/src/api/revocations.js.html +1 -1
- package/coverage/lcov-report/src/api/signatures.js.html +528 -81
- package/coverage/lcov-report/src/api/users.js.html +5 -2
- package/coverage/lcov-report/src/config/index.html +21 -21
- package/coverage/lcov-report/src/config/index.js.html +65 -32
- package/coverage/lcov-report/src/errors/index.html +5 -5
- package/coverage/lcov-report/src/errors/index.js.html +13 -10
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/index.js.html +13 -4
- package/coverage/lcov-report/src/utils/constant.js.html +4 -4
- package/coverage/lcov-report/src/utils/helpers.js.html +268 -145
- package/coverage/lcov-report/src/utils/httpClient.js.html +646 -0
- package/coverage/lcov-report/src/utils/index.html +32 -17
- package/coverage/lcov.info +429 -167
- package/dist/index.js +390 -150
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +390 -150
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/certs.js +27 -30
- package/src/api/signatures.js +205 -50
- package/src/api/users.js +1 -0
- package/src/errors/index.js +1 -0
- package/src/index.js +4 -1
- package/src/utils/helpers.js +140 -99
- package/tests/api/certs.test.js +126 -4
- package/tests/api/signatures.test.js +207 -4
- package/tests/api/users.test.js +1 -0
- package/src/auth/index.js +0 -24
package/package.json
CHANGED
package/src/api/certs.js
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { getConfig } from "../config";
|
|
3
|
-
import { INTEGRATION_TYPE } from "../utils/constant";
|
|
4
|
-
import { helpers } from "../utils/helpers";
|
|
5
|
-
import { ApacuanaAPIError } from "../errors/index";
|
|
1
|
+
import { getConfig } from "../config/index";
|
|
6
2
|
import { httpRequest } from "../utils/httpClient";
|
|
3
|
+
import helpers from "../utils/helpers";
|
|
4
|
+
import { ApacuanaAPIError } from "../errors";
|
|
5
|
+
import { INTEGRATION_TYPE } from "../utils/constant";
|
|
7
6
|
|
|
8
|
-
const generateCertOnBoarding = async () => {
|
|
7
|
+
const generateCertOnBoarding = async (csr = undefined) => {
|
|
9
8
|
try {
|
|
10
|
-
const
|
|
11
|
-
const { userData } = config;
|
|
12
|
-
const keyPair = await helpers.generateKeyPair();
|
|
13
|
-
const { csrBase64 } = await helpers.generateCSR(keyPair, userData);
|
|
14
|
-
|
|
15
|
-
const body = {
|
|
16
|
-
csr: CryptoJS.AES.encrypt(csrBase64, config.secretKey, {
|
|
17
|
-
mode: CryptoJS.mode.ECB,
|
|
18
|
-
padding: CryptoJS.pad.Pkcs7,
|
|
19
|
-
}).toString(),
|
|
20
|
-
};
|
|
9
|
+
const encryptedCSR = helpers.encryptedCsr(csr);
|
|
21
10
|
|
|
22
11
|
const response = await httpRequest(
|
|
23
12
|
"services/api/register/certificate",
|
|
24
|
-
|
|
13
|
+
encryptedCSR,
|
|
25
14
|
"POST"
|
|
26
15
|
);
|
|
27
|
-
|
|
28
16
|
const { cert } = response;
|
|
29
17
|
if (!cert) {
|
|
30
18
|
throw new ApacuanaAPIError(
|
|
@@ -34,11 +22,7 @@ const generateCertOnBoarding = async () => {
|
|
|
34
22
|
);
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
keyPair.privateKey
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
return { cert, privateKey: exportedPrivateKey };
|
|
25
|
+
return { cert, success: true };
|
|
42
26
|
} catch (error) {
|
|
43
27
|
// Se lanza el error capturado, que ya será de tipo ApacuanaAPIError o un Error nativo.
|
|
44
28
|
if (error instanceof ApacuanaAPIError) {
|
|
@@ -48,23 +32,36 @@ const generateCertOnBoarding = async () => {
|
|
|
48
32
|
}
|
|
49
33
|
};
|
|
50
34
|
|
|
51
|
-
export const generateCert = async () => {
|
|
35
|
+
export const generateCert = async (csr = undefined) => {
|
|
52
36
|
const { integrationType } = getConfig();
|
|
53
|
-
|
|
37
|
+
helpers.validateCsr(csr);
|
|
54
38
|
if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
|
|
55
|
-
|
|
56
|
-
}
|
|
39
|
+
return generateCertOnBoarding(csr);
|
|
40
|
+
}
|
|
41
|
+
if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
|
|
57
42
|
// eslint-disable-next-line no-console
|
|
58
43
|
console.log("-> Lógica para On-premise");
|
|
59
44
|
// Aquí iría la llamada a httpRequest para el endpoint de on-premise
|
|
60
45
|
// return httpRequest('/certs/generate-onpremise', data);
|
|
46
|
+
return Promise.resolve(); // Retornar una promesa resuelta para consistencia
|
|
61
47
|
}
|
|
48
|
+
|
|
49
|
+
// Lanzar un error si el tipo de integración no es soportado
|
|
50
|
+
throw new ApacuanaAPIError(
|
|
51
|
+
`Tipo de integración no soportado: ${integrationType}`,
|
|
52
|
+
400,
|
|
53
|
+
"UNSUPPORTED_INTEGRATION_TYPE"
|
|
54
|
+
);
|
|
62
55
|
};
|
|
63
56
|
|
|
64
|
-
export const getCertStatus = () => {
|
|
57
|
+
export const getCertStatus = (isCertificateInDevice = false) => {
|
|
65
58
|
const config = getConfig();
|
|
66
|
-
const status = helpers.getCertificateStatus(
|
|
59
|
+
const status = helpers.getCertificateStatus(
|
|
60
|
+
config.userData,
|
|
61
|
+
isCertificateInDevice
|
|
62
|
+
);
|
|
67
63
|
return {
|
|
68
64
|
status,
|
|
65
|
+
success: true,
|
|
69
66
|
};
|
|
70
67
|
};
|
package/src/api/signatures.js
CHANGED
|
@@ -1,77 +1,232 @@
|
|
|
1
1
|
// src/api/signatures.js
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @param {object} documentData - Datos del documento a firmar.
|
|
8
|
-
* @param {object} signatureData - Datos de la firma.
|
|
9
|
-
* @returns {Promise<object>} Objeto con el resultado de la firma.
|
|
10
|
-
*/
|
|
11
|
-
export const signDocument = async (documentData, signatureData) => {
|
|
12
|
-
console.log("-> Función 'signDocument' ejecutada.");
|
|
13
|
-
console.log('Parámetros recibidos para firmar documento:', {
|
|
14
|
-
documentData,
|
|
15
|
-
signatureData,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
if (!documentData || !signatureData) {
|
|
19
|
-
throw new Error(
|
|
20
|
-
'Datos de documento y firma son requeridos para signDocument.',
|
|
21
|
-
);
|
|
22
|
-
}
|
|
2
|
+
import { getConfig } from "../config/index";
|
|
3
|
+
import { httpRequest } from "../utils/httpClient";
|
|
4
|
+
import { ApacuanaAPIError } from "../errors";
|
|
5
|
+
import helpers from "../utils/helpers";
|
|
6
|
+
import { INTEGRATION_TYPE } from "../utils/constant";
|
|
23
7
|
|
|
8
|
+
/*
|
|
9
|
+
const signDocumentOnBoarding = async (documentData, signatureData) => {
|
|
24
10
|
try {
|
|
25
11
|
const response = await httpRequest(
|
|
26
|
-
|
|
12
|
+
"/docs/sign",
|
|
27
13
|
{ documentData, signatureData },
|
|
28
|
-
|
|
29
|
-
);
|
|
30
|
-
console.log(
|
|
31
|
-
'Respuesta del servidor simulada para firmar documento:',
|
|
32
|
-
response,
|
|
14
|
+
"POST"
|
|
33
15
|
);
|
|
34
16
|
if (!response.success) {
|
|
35
17
|
throw new ApacuanaAPIError(
|
|
36
|
-
response.message ||
|
|
18
|
+
response.message || "Error desconocido al firmar documento."
|
|
37
19
|
);
|
|
38
20
|
}
|
|
39
21
|
return { signedDocId: response.id, status: response.message };
|
|
40
22
|
} catch (error) {
|
|
41
|
-
|
|
23
|
+
if (error.name === "ApacuanaAPIError") {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
throw new ApacuanaAPIError(
|
|
27
|
+
`Fallo en la firma del documento (on-boarding): ${error.message}`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const signDocumentOnPremise = async (signature, cert, privateKey) => {
|
|
33
|
+
helpers.validateSignOnPremiseData({ signature, cert, privateKey });
|
|
34
|
+
try {
|
|
35
|
+
const digestBody = {
|
|
36
|
+
publickey: cert,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const digestResponse = await httpRequest(
|
|
40
|
+
`services/api/documents/getdigest/${signature.id}`,
|
|
41
|
+
digestBody,
|
|
42
|
+
"POST"
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const digest = digestResponse.data?.digest || digestResponse.digest;
|
|
46
|
+
if (!digest) {
|
|
47
|
+
throw new ApacuanaAPIError(
|
|
48
|
+
"La generación de firma ha fallado: no se pudo obtener el digest del documento."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const signedDigest = await helpers.signDigest(digest, privateKey);
|
|
53
|
+
|
|
54
|
+
const signBody = {
|
|
55
|
+
positions: JSON.stringify(
|
|
56
|
+
signature.positions.map((p) => ({
|
|
57
|
+
x: p.x,
|
|
58
|
+
y: p.y,
|
|
59
|
+
page: p.page,
|
|
60
|
+
status: 1,
|
|
61
|
+
}))
|
|
62
|
+
),
|
|
63
|
+
publickey: cert,
|
|
64
|
+
signeddigest: signedDigest,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const signResponse = await httpRequest(
|
|
68
|
+
`services/api/documents/sign/${signature.id}`,
|
|
69
|
+
signBody,
|
|
70
|
+
"PUT"
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return signResponse;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error.name === "ApacuanaAPIError") {
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
throw new ApacuanaAPIError(
|
|
79
|
+
`Fallo en la firma del documento (on-premise): ${error.message}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Firma un documento PDF con un certificado digital.
|
|
87
|
+
* @param {object} data - Datos para la firma. Para 'on-boarding', debe contener {documentData, signatureData}. Para 'on-premise', debe contener {signature, cert, privateKey}.
|
|
88
|
+
* @returns {Promise<object>} Objeto con el resultado de la firma.
|
|
89
|
+
*/
|
|
90
|
+
/*
|
|
91
|
+
export const signDocument = async (signData) => {
|
|
92
|
+
if (
|
|
93
|
+
!signData ||
|
|
94
|
+
typeof signData !== "object" ||
|
|
95
|
+
Object.keys(signData).length === 0
|
|
96
|
+
) {
|
|
97
|
+
throw new ApacuanaAPIError(
|
|
98
|
+
"El parámetro 'data' es requerido y debe ser un objeto no vacío.",
|
|
99
|
+
400,
|
|
100
|
+
"INVALID_PARAMETER"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const { integrationType } = getConfig();
|
|
105
|
+
|
|
106
|
+
if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
|
|
107
|
+
return signDocumentOnBoarding(signData);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
|
|
111
|
+
return signDocumentOnPremise(signData);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
throw new ApacuanaAPIError(
|
|
115
|
+
`Tipo de integración no soportado: ${integrationType}`,
|
|
116
|
+
400,
|
|
117
|
+
"UNSUPPORTED_INTEGRATION_TYPE"
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
const addSignerOnBoarding = async (signerData) => {
|
|
123
|
+
helpers.validateOnBoardingSignerData(signerData);
|
|
124
|
+
try {
|
|
125
|
+
// La lógica actual de httpRequest se mueve aquí
|
|
126
|
+
await httpRequest("services/api/documents/signing", signerData, "POST");
|
|
127
|
+
return { signer: signerData.typedoc + signerData.doc, success: true };
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (error instanceof ApacuanaAPIError) {
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Fallo al agregar firmante en On-Boarding: ${error.message}`
|
|
134
|
+
);
|
|
42
135
|
}
|
|
43
136
|
};
|
|
44
137
|
|
|
138
|
+
const addSignerOnPremise = async () =>
|
|
139
|
+
Promise.resolve({ signerId: "on-premise-signer-id", status: "added" });
|
|
140
|
+
|
|
45
141
|
/**
|
|
46
|
-
*
|
|
142
|
+
* Agrega un firmante a un documento, manejando diferentes tipos de integración.
|
|
47
143
|
* @param {object} signerData - Datos del firmante a agregar.
|
|
48
144
|
* @returns {Promise<object>} Objeto con el resultado de agregar el firmante.
|
|
49
145
|
*/
|
|
50
146
|
export const addSigner = async (signerData) => {
|
|
51
|
-
|
|
52
|
-
|
|
147
|
+
if (
|
|
148
|
+
!signerData ||
|
|
149
|
+
typeof signerData !== "object" ||
|
|
150
|
+
Object.keys(signerData).length === 0
|
|
151
|
+
) {
|
|
152
|
+
throw new ApacuanaAPIError(
|
|
153
|
+
"Los datos del firmante (signerData) son requeridos y deben ser un objeto no vacío.",
|
|
154
|
+
400,
|
|
155
|
+
"INVALID_PARAMETER"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
53
158
|
|
|
54
|
-
|
|
55
|
-
|
|
159
|
+
const { integrationType } = getConfig();
|
|
160
|
+
|
|
161
|
+
if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
|
|
162
|
+
return addSignerOnBoarding(signerData);
|
|
56
163
|
}
|
|
57
164
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
165
|
+
if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
|
|
166
|
+
return addSignerOnPremise(signerData);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
throw new ApacuanaAPIError(
|
|
170
|
+
`Tipo de integración no soportado: ${integrationType}`,
|
|
171
|
+
400,
|
|
172
|
+
"UNSUPPORTED_INTEGRATION_TYPE"
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const getDocsOnPremise = async () => {
|
|
177
|
+
throw new ApacuanaAPIError(
|
|
178
|
+
"La obtención de documentos no está soportada para el tipo de integración: ONBOARDING",
|
|
179
|
+
501,
|
|
180
|
+
"NOT_IMPLEMENTED"
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const getDocsOnBoarding = async (data) => {
|
|
185
|
+
const { customerId } = getConfig();
|
|
186
|
+
if (!customerId) {
|
|
187
|
+
throw new ApacuanaAPIError(
|
|
188
|
+
"El 'customerId' no está configurado. Por favor, configure el SDK.",
|
|
189
|
+
400,
|
|
190
|
+
"CONFIGURATION_ERROR"
|
|
67
191
|
);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
const apiUrl = `services/api/documents/listcustomer?page=${data.page}&customerid=${customerId}&size=${data.size}&status=${data.status}`;
|
|
196
|
+
|
|
197
|
+
const response = await httpRequest(apiUrl, {}, "GET");
|
|
198
|
+
return response;
|
|
74
199
|
} catch (error) {
|
|
75
|
-
|
|
200
|
+
if (error.name === "ApacuanaAPIError") {
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
throw new ApacuanaAPIError(
|
|
204
|
+
`Fallo al obtener la lista de documentos (on-premise): ${error.message}`
|
|
205
|
+
);
|
|
76
206
|
}
|
|
77
207
|
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Obtiene una lista de documentos.
|
|
211
|
+
* @param {object} data - Objeto con los parámetros de paginación. Debe contener {page, size}.
|
|
212
|
+
* @returns {Promise<object>} Objeto con la lista de documentos.
|
|
213
|
+
*/
|
|
214
|
+
export const getDocs = async (data) => {
|
|
215
|
+
helpers.validateGetDocsData(data);
|
|
216
|
+
|
|
217
|
+
const { integrationType } = getConfig();
|
|
218
|
+
|
|
219
|
+
if (integrationType === INTEGRATION_TYPE.ONBOARDING) {
|
|
220
|
+
return getDocsOnBoarding(data);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (integrationType === INTEGRATION_TYPE.ONPREMISE) {
|
|
224
|
+
return getDocsOnPremise();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
throw new ApacuanaAPIError(
|
|
228
|
+
`La obtención de documentos no está soportada para un tipo de integración desconocido: ${integrationType}`,
|
|
229
|
+
501,
|
|
230
|
+
"NOT_IMPLEMENTED"
|
|
231
|
+
);
|
|
232
|
+
};
|
package/src/api/users.js
CHANGED
package/src/errors/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export class ApacuanaAPIError extends Error {
|
|
|
9
9
|
this.name = "ApacuanaAPIError";
|
|
10
10
|
this.statusCode = statusCode;
|
|
11
11
|
this.errorCode = errorCode;
|
|
12
|
+
this.success = false; // Añadir el atributo success con valor false
|
|
12
13
|
|
|
13
14
|
// Mantener el stack trace correcto
|
|
14
15
|
if (Error.captureStackTrace) {
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// src/index.js
|
|
2
1
|
import { setConfig, getConfig } from "./config/index";
|
|
3
2
|
import { initHttpClient, setAuthToken } from "./utils/httpClient";
|
|
4
3
|
import getCustomer from "./api/users";
|
|
5
4
|
import requestRevocation from "./api/revocations";
|
|
6
5
|
import { getCertStatus } from "./api/certs";
|
|
6
|
+
import { addSigner, getDocs } from "./api/signatures";
|
|
7
7
|
|
|
8
8
|
const apacuana = {
|
|
9
9
|
/**
|
|
@@ -62,6 +62,9 @@ const apacuana = {
|
|
|
62
62
|
getConfig,
|
|
63
63
|
requestRevocation,
|
|
64
64
|
getCertStatus,
|
|
65
|
+
getCustomer,
|
|
66
|
+
addSigner,
|
|
67
|
+
getDocs,
|
|
65
68
|
};
|
|
66
69
|
|
|
67
70
|
export default apacuana;
|