Neste artigo, mostrarei como implementar a formação de um documento eletrônico legalmente significativo na interface da web sem a necessidade de modificar o back-end. Isso pode ser do interesse daqueles que se deparam, por exemplo, com as seguintes tarefas e são limitados em recursos e tempo:
- é necessário adicionar a capacidade de enviar pedidos oficiais ou apelações ao site da empresa;
- é necessário adicionar a capacidade de assinar um acordo de conexão à interface da web do portal
- é necessário implementar uma recepcionista online.
Como um bom bônus - a capacidade de receber documentos assinados por EDS por e-mail.
Será sobre os certificados EDS emitidos pela NCA RK .
Vou formular a tarefa da seguinte forma: com base em um modelo previamente acordado, criar um documento eletrônico na interface da web, dar a oportunidade de assiná-lo com um EDS, transferi-lo para processamento a um grupo de gestores e garantir o significado jurídico em de acordo com a legislação da República do Cazaquistão.
Usarei:
- Vue.js para facilitar o desenvolvimento (tentarei não escrever nada específico, para que você possa alternar facilmente para qualquer outro);
- Bootstrap para estilização básica (quase invisível);
- axios para simplificar a rede;
- pdfmake PDF JS;
- ncalayer-js-client NCALayer;
- SIGEX .
:
- , , ;
- ;
- NCALayer.
, : https://github.com/sigex-kz/example-sign-web-form
, :
<form v-on:submit.prevent="compilePDF">
<h2>{{ formHeader }}</h2>
<p>{{ formIntro }}</p>
<div v-for="formItem in formItems" class="form-group">
<label>{{ formItem.label }}</label>
<input v-model="formItem.value" type="text" class="form-control">
</div>
<button type="submit" class="btn btn-primary"> </button>
</form>
Vue.js , HTML PDF:
new Vue({
...
data: {
formHeader: ' №1',
formIntro: ' , , , , .',
formItems: [
{ label: ' ', value: '', },
{ label: ' ', value: '', },
{ label: ' ', value: '', },
],
...
},
...
PDF JS
PDF pdfmake, PDF — JS.
, pdfmake PDF base64 :
async compilePDF() {
const pdfDefinition = {
content: [
{ text: this.formHeader, fontSize: 20, bold: true, alignment: 'center', margin: [ 0, 0, 0, 20 ] },
{ text: this.formIntro, fontSize: 15, margin: [ 0, 0, 0, 20 ] },
],
};
for (const formItem of this.formItems) {
pdfDefinition.content.push(`${formItem.label}: ${formItem.value}`);
}
this.dataB64 = await new Promise((resolve) => {
const pdfDocGenerator = pdfMake.createPdf(pdfDefinition);
pdfDocGenerator.getBase64(resolve);
});
},
, , :
<p> <a v-bind:href="`data:application/octet-stream;base64,${dataB64}`" target="_blank" v-bind:download="title">{{ title }}</a>.</p>
— NCALayer, . NCALayer — WebSocket , , ncalayer-js-client.
NCALayer , , ( ). NCALayer . , , :
const storageTypes = await this.ncaLayer.getActiveTokens();
if (storageTypes.length == 0) {
this.storageType = 'PKCS12';
} else {
this.storageType = storageTypes[0];
}
PDF. , NCALayer :
const signature = await this.ncaLayer.createCMSSignatureFromBase64(this.storageType, this.dataB64);
, , :
- PDF ;
- .
" " , .
API SIGEX , . .
let response = await axios.post(
`${this.sigexURL}/api`,
{
title: this.title,
description: this.description,
signature,
emailNotifications: { to: ['some-manager@example.kz', this.email] },
},
);
this.sigexId = response.data.documentId;
, , , .
:
const dataToSend = Uint8Array.from(atob(this.dataB64), c => c.charCodeAt(0)).buffer;
response = await axios.post(
`${this.sigexURL}/api/${this.sigexId}/data`,
dataToSend,
{
headers: { 'Content-Type': 'application/octet-stream' },
},
);
, . .
:
- gerar um documento eletrônico na interface da web com base em um modelo pré-acordado - implementado como uma página da web estática e uma pequena quantidade de código JS;
- fornecer uma oportunidade para assinar seu EDS - implementado usando o software certificado recomendado;
- transferi-lo para um grupo de gestores para processamento - implementado através do envio de documentos assinados para o endereço de e-mail dos gestores responsáveis;
- garantir significado legal de acordo com a legislação da República do Cazaquistão - implementada usando a API do serviço SIGEX.