lib-digitalsignature
TypeScript icon, indicating that this package has built-in type declarations

0.0.21 • Public • Published

Do not download, this library works with an external program, I do not publish


Lib-DigitalSignature

Support License devDependency Status

This library was generated with Angular CLI version 9.1.12.

Use appropriate version based on your Angular version.

Angular 9
>=v9.1.12

Browser Support

ChromeChrome FirefoxFirefox IE / EdgeIE / Edge iOS SafariSafari OperaOpera
Latest Latest IE11, Edge Latest Latest

Requirements for quick use

dependencia version link
file-saver 2.0.2 npm 🔗
ngx-clipboard 12.3.0 npm 🔗

Installation

lib-digitalsignature is available via npm and yarn

Using npm:

$ npm install lib-digitalsignature --save

Using yarn:

$ yarn add lib-digitalsignature

Using angular-cli:

$ ng add lib-digitalsignature

Basic Usage ➡️ Add to your project

Import lib-digitalsignature and HttpClientModule in the root module(AppModule):

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
// Import library module
import { DigitalSignatureModule } from "lib-digitalsignature";
import { HttpClientModule } from "@angular/common/http";

@NgModule({
  imports: [
    // ...
    HttpClientModule,
    DigitalSignatureModule
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

Add DigitalSignatureModule service wherever you want to use the lib-digitalsignature.

import { DigitalSignatureModule } from "lib-digitalsignature";
import { saveAs } from "file-saver";

Now use in your template

<lib-digitalsignature></lib-digitalsignature>

Advanced Usage - Service ➡️ Add to your project

Import lib-digitalsignature , ClipboardModule, FormsModule and HttpClientModule in the root module(AppModule):

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
// Import library module
import { DigitalSignatureModule } from "lib-digitalsignature";
import { HttpClientModule } from "@angular/common/http";
import { ClipboardModule } from "ngx-clipboard";
import { FormsModule } from "@angular/forms";

@NgModule({
  imports: [
    // ...
    DigitalSignatureModule,
    HttpClientModule,
    ClipboardModule,
    FormsModule
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

Add DigitalSignatureModule service wherever you want to use the lib-digitalsignature.

import { DigitalSignatureModule, DigitalSignatureService, TiposDeFirma, XmlModel } from "lib-digitalsignature";
import { saveAs } from "file-saver";

Available service methods

  verificar(objeto: XmlModel, tipoFirma: TiposDeFirma)

  firmaDigital(objeto: XmlModel, tipoFirma: TiposDeFirma)

  firmaElectronica(objeto: XmlModel, tipoFirma: TiposDeFirma)

  isAlive():

Service usage example

In your component.ts
import { Component, OnInit } from '@angular/core';
import { DigitalSignatureModule, DigitalSignatureService, TiposDeFirma, XmlModel } from "lib-digitalsignature";
import { saveAs } from "file-saver";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

// Advanced Usage - Service
export class AppComponent implements OnInit {

  public TiposDeFirma: any = [
    { key: "Xades-BES - Sin ds:Object", value: TiposDeFirma.Xades_BES_Sin_ds_Object },
    { key: "Xades-BES - Con ds:Object", value: TiposDeFirma.Xades_BES_Con_ds_Object },
  ];
  public TipoDeFirma = TiposDeFirma.Xades_BES_Sin_ds_Object;
  public text: String;
  public textPreview: String = "";
  public objeto: XmlModel;
  public isEnabled = false;
  public showPreview = false;
  public fileUrl;
  public responseFirma;

  constructor(
    public signatureService: DigitalSignatureService
  ) { }

  public ngOnInit() {
    this.text = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n' +
      "<Tour>\n" +
      "   <NombreTour> The Offspring y Bad Religion </NombreTour> \n" +
      "   <Fecha> 24/10/2019 19:00:00 </Fecha>\n" +
      "   <Videos>\n" +
      // tslint:disable-next-line: max-line-length
      '       <video nombre="Bad Religion - 21st century digital boy - Luna Park - 24/10/2019">https://www.youtube.com/watch?v=iDVeAAvFb3U</video> \n' +
      '       <video nombre="The Offspring - Americana - Luna Park - 24/10/2019">https://www.youtube.com/watch?v=Zd7bAu7hVZQ</video> \n' +
      "   </Videos>\n" +
      "</Tour>";
  }

  public FirmarDigital() {
    this.isEnabled = false;
    this.showPreview = false;
    this.textPreview = "";
    this.objeto = new XmlModel();
    this.objeto.Archivo = this.text;
    this.signatureService.firmaDigital(this.objeto, this.TipoDeFirma).subscribe(
      (resp) => {
        // tslint:disable-next-line: no-empty
        if (resp === "-1") {
        } else if (resp === "-2") {
          alert("Certificado: Certificado no valido");
        } else {
          this.responseFirma = resp;
          this.isEnabled = true;
        }
      }, (err) => {
        const message = JSON.parse(err.error).ExceptionMessage;
        alert("Certificado: " + message);
      });
  }

  public FirmarElectronica() {
    this.isEnabled = false;
    this.showPreview = false;
    this.textPreview = "";
    this.objeto = new XmlModel();
    this.objeto.Archivo = this.text;
    this.signatureService.firmaElectronica(this.objeto, this.TipoDeFirma).subscribe(
      (resp) => {
        // tslint:disable-next-line: no-empty
        if (resp === "-1") {
        } else if (resp === "-2") {
          alert("Certificado: Certificado no valido");
        } else {
          this.responseFirma = resp;
          this.isEnabled = true;
        }
      }, (err) => {
        const message = JSON.parse(err.error).ExceptionMessage;
        alert("Certificado: " + message);
      });
  }

  public Verificar() {
    this.objeto = new XmlModel();
    this.objeto.Archivo = this.text;
    this.signatureService.verificar(this.objeto, this.TipoDeFirma).subscribe(
      (resp) => {

        const data = JSON.parse(JSON.stringify(resp.data));
        const cantTotalDeFirmas = data.length;
        let firmasValidas = 0;
        let firmasInvalidas = 0;

        data.forEach((element) => {
          if (data[data.indexOf(element)].IsValid === true) {
            firmasValidas = firmasValidas + 1;
          }
        });

        firmasInvalidas = cantTotalDeFirmas - firmasValidas;

        if (cantTotalDeFirmas === firmasValidas) {
          alert("Cantidad de firmas validas: " + firmasValidas);
        } else {
          alert("Cantidad de firmas validas: " + firmasValidas + " Cantidad de firmas invalidas: " + firmasInvalidas);
        }
      }, (err) => {
        const message = err.error.ExceptionMessage;
        alert("Firmas: " + message);
      });
  }

  public downloadFile() {
    const blob = new Blob([this.responseFirma], { type: "text/xml; charset=utf-8" });
    saveAs(blob, "Document.xml");
  }

  public preview() {
    this.showPreview = true;
    this.textPreview = this.responseFirma;
  }

  public changeType(event) {
    const key = event.target.value;
    const value = this.TiposDeFirma.find((item) => item.key === key).value;
    this.TipoDeFirma = value;
  }

  public copyMessage() {
    alert("Documento copiado");
  }

}
In your component.html
<section class="ss-d ss-style-triangles">
  <div>
    <button type="button" class="btn btn-success" (click)="downloadFile()" [disabled]="!isEnabled">Descargar Documento
      Firmado&nbsp;
      <i class="fa fa-download fa-lg" aria-hidden="true"></i></button></div>
</section>

<div class="container">
  <div class="form-group">
    <textarea class="form-control" id="Textarea1" rows="13" style="resize: none;" [(ngModel)]="text"></textarea>
  </div>
  <select class="custom-select" (change)="changeType($event)">
    <option *ngFor="let aType of TiposDeFirma" [ngValue]="aType">{{aType.key}}</option>
  </select>
</div>


<br>

<div class="container">
  <div class="text-center">
    <button type="button" class="btn btn-primary waves-effect waves-light" (click)='FirmarDigital()'><i
        class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp;Firmar Digital</button>
    <button type="button" class="btn btn-default waves-effect waves-light" (click)='FirmarElectronica()'><i
        class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp;Firmar Electronica</button>
    <button type="button" class="btn btn-danger waves-effect waves-light" (click)='preview()' [disabled]="!isEnabled"><i
        class="fa fa-eye fa-fw" aria-hidden="true"></i>&nbsp;Vista Previa</button>
    <button type="button" class="btn btn-warning waves-effect waves-light" (click)="Verificar()"><i
        class="fa fa-search fa-fw" aria-hidden="true"></i>&nbsp;Verificar Firmas</button>
  </div>
</div>

<br>

<div *ngIf="showPreview">
  <div class="container">
    <div class="form-group">
      <button type="button" class="btn btn-grey copy waves-effect waves-light" [ngxClipboard]="textArea2"
        (click)="copyMessage()"><i class="fa fa-clipboard" aria-hidden="true"></i>&nbsp;Copiar</button>

      <button type="button" class="btn btn-grey download waves-effect waves-light" (click)="downloadFile()"><i
          class="fa fa-download" aria-hidden="true"></i>&nbsp;Guardar</button>

      <textarea class="form-control textPreview" id="textArea2" #textArea2 rows="13" style="resize: none;"
        [(ngModel)]="textPreview" readonly></textarea>
    </div>

  </div>

</div>
In your component.scss
  :root {
  -btn-primary: #4285f4;
  -btn-default: #2bbbad;
  -btn-secondary: #a6c;
  -btn-success: #00c851;
  -btn-info: #33b5e5;
  -btn-warning: #fb3;
  -btn-danger: #ff3547;
  -btn-grey: #8dacc5;
}

body {
  font-family: 'Roboto', sans-serif;
}

.null {
  margin: 0;
}

.select{
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  text-transform: none;
  word-wrap: normal;
}

.text-center {
  text-align: center !important;
}

.btn {
  -webkit-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
  box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
  padding: .84rem 2.14rem;
  font-size: .81rem;
  -webkit-transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
  transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
  -o-transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
  transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
  transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
  margin: .375rem;
  border: 0;
  -webkit-border-radius: .125rem;
  border-radius: .125rem;
  cursor: pointer;
  text-transform: uppercase;
  white-space: normal;
  word-wrap: break-word;
  color: #fff;
}

.btn:focus, .btn:hover {
  text-decoration: none;
}

.btn:active, .btn:focus, .btn:hover {
  -webkit-box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
  box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
  outline: 0;
}

.btn:not(:disabled):not(.disabled) {
  cursor: pointer;
}

.waves-effect {
  position: relative;
  cursor: pointer;
  overflow: hidden;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}


.btn-primary:hover {
  color: #fff;
  background-color: #0069d9;
  border-color: #0062cc;
}

.btn-primary:not([disabled]):not(.disabled).active, .btn-primary:not([disabled]):not(.disabled):active, .show>.btn-primary.dropdown-toggle {
  -webkit-box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
  box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
  background-color: #0b51c5!important;
}

.btn:disabled, .btn.disabled,
fieldset:disabled .btn {
  pointer-events: none;
  opacity: 0.4;
}

.btn-default {
  background-color: #2bbbad!important;
  color: #fff;
}

.btn-primary {
  background-color: #4285f4!important;
  color: rgb(255, 255, 255);
}

.btn-secondary {
  background-color: #a6c!important;
  color: #fff;
}

.btn-success {
  background-color: #00c851!important;
  color: #fff;
}

.btn-info {
  background-color: #33b5e5!important;
  color: #fff;
}

.btn-warning {
  background-color: #fb3!important;
  color: #fff;
}

.btn-danger {
  background-color: #ff3547!important;
  color: #fff;
}

.btn-grey {
  background-color: #8dacc5!important;
  color: #fff;
  width:auto;
  height:auto;
  padding:5px 5px;
  text-align:center;
}

.copy {
  position: relative;;
  float: right;
  top: 3.2em;
}

.download {
  position: relative;;
  float: right;
  top: 3.2em;
}

.textPreview{
  font-size: 12px;
  font-family: monospace;
  white-space: pre;
}


.ss-d {
  position: relative;
  background-color: rgba(155, 168, 174, 0.3);
  padding-top:20px;
  padding-bottom:20px;
  margin-top:15px;
  margin-bottom:80px;
  text-align: center;
  height: 96px;
}

/* Common style for pseudo-elements */
.ss-d::before,
.ss-d::after {
  position: absolute;
  content: '';
  pointer-events: none;
}

/* Triangles */
.ss-style-triangles::before,
.ss-style-triangles::after {
  left: 50%;
  width: 30px;
  height: 30px;
  -webkit-transform: translateX(-50%) rotate(45deg);
  transform: translateX(-50%) rotate(45deg);
}

.ss-style-triangles::before {
  top: -15px;
  background: #ecf0f5;
}

.container {
width: 100%;
padding-right: 1rem;
padding-left: 1rem;
margin-right: auto;
margin-left: auto;
}

@media (min-width: 576px) {
.container {
  max-width: 540px;
}
}

@media (min-width: 768px) {
.container {
  max-width: 720px;
}
}

@media (min-width: 992px) {
.container {
  max-width: 960px;
}
}

@media (min-width: 1200px) {
.container {
  max-width: 1140px;
}
}

@media (min-width: 1400px) {
.container {
  max-width: 1320px;
}
}


.form-control {
display: block;
width: 100%;
min-height: calc(1.5em + 0.75rem + 2px);
padding: 0.375rem 0.75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
.form-control {
  transition: none;
}
}

.form-control:focus {
color: #495057;
background-color: #fff;
border-color: #8bbafe;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}

.form-control::-webkit-input-placeholder {
color: #6c757d;
opacity: 1;
}

.form-control::-moz-placeholder {
color: #6c757d;
opacity: 1;
}

.form-control::-ms-input-placeholder {
color: #6c757d;
opacity: 1;
}

.form-control::placeholder {
color: #6c757d;
opacity: 1;
}

.form-control:disabled, .form-control[readonly] {
background-color: #e9ecef;
opacity: 1;
}
In your index.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

Project example

If you want to see an example, it is recommended to download the project, compile the library and run with ng serve

Build the library

Download the source code from github. Run ng build lib-digitalsignature --prod to build the project. The build artifacts will be stored in the dist/ directory.

Creator

Patricio E. Arena

Future Plan

  • Smaller bundle

License

lib-digitalsignature is MIT licensed.

Package Sidebar

Install

npm i lib-digitalsignature

Weekly Downloads

15

Version

0.0.21

License

MIT

Unpacked Size

397 kB

Total Files

27

Last publish

Collaborators

  • patricioarena