diff --git a/esign-cert-repo/pom.xml b/esign-cert-repo/pom.xml
index 2b9f54b..e470f8a 100644
--- a/esign-cert-repo/pom.xml
+++ b/esign-cert-repo/pom.xml
@@ -4,7 +4,7 @@
4.0.0
es.keensoft.alfresco
esign-cert-repo
- 1.6.1
+ 1.6.2
esign-cert-repo Repository AMP project
amp
Manages the lifecycle of the esign-cert-repo Repository AMP (Alfresco Module Package)
diff --git a/esign-cert-share/pom.xml b/esign-cert-share/pom.xml
index 024096d..38f79b1 100644
--- a/esign-cert-share/pom.xml
+++ b/esign-cert-share/pom.xml
@@ -4,7 +4,7 @@
4.0.0
es.keensoft.alfresco
esign-cert-share
- 1.6.1
+ 1.6.2
esign-cert-share AMP project
amp
Manages the lifecycle of the esign-cert-share AMP (Alfresco Module Package)
diff --git a/esign-cert-share/src/main/amp/web/sign/constantes.js b/esign-cert-share/src/main/amp/web/sign/constantes.js
old mode 100644
new mode 100755
index 3890cad..bcd6417
--- a/esign-cert-share/src/main/amp/web/sign/constantes.js
+++ b/esign-cert-share/src/main/amp/web/sign/constantes.js
@@ -6,7 +6,7 @@ var Constants = {
// IMPORTANTE: PARA PRUEBAS, USAR SIEMPRE UNA IP O NOMBRE DE DOMINIO, NUNCA 'LOCALHOST' O '127.0.0.1'
// SI NO SE HACE ASI, AUTOFIRMA BLOQUEARA LA FIRMA POR SEGURIDAD
- // URL raiz en la que se encuentra el fichero miniapplet-full_1_5.jar
+ // URL raiz en la que se encuentra el fichero miniapplet-full_X_Y.jar
URL_BASE_APPLE : "http://XXX:8080/miniapplet",
// URL raiz en la que se despliegan los servicios
diff --git a/esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_5.jar b/esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_6_2.jar
old mode 100644
new mode 100755
similarity index 57%
rename from esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_5.jar
rename to esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_6_2.jar
index c76b051..cd5c1e5
Binary files a/esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_5.jar and b/esign-cert-share/src/main/amp/web/sign/miniapplet-full_1_6_2.jar differ
diff --git a/esign-cert-share/src/main/amp/web/sign/miniapplet.js b/esign-cert-share/src/main/amp/web/sign/miniapplet.js
old mode 100644
new mode 100755
index 10f3290..2e47582
--- a/esign-cert-share/src/main/amp/web/sign/miniapplet.js
+++ b/esign-cert-share/src/main/amp/web/sign/miniapplet.js
@@ -14,9 +14,9 @@ var originalXMLHttpRequest = window.XMLHttpRequest;
var MiniApplet = ( function ( window, undefined ) {
- var VERSION = "1.5";
+ var VERSION = "1.6.2";
- var JAR_NAME = 'miniapplet-full_1_5.jar';
+ var JAR_NAME = 'miniapplet-full_1_6_2.jar';
var JAVA_ARGUMENTS = '-Xms512M -Xmx512M ';
@@ -30,11 +30,15 @@ var MiniApplet = ( function ( window, undefined ) {
var retrieverServletAddress = null;
+ var jnlpServiceAddress = "";
+
var clientType = null;
var severeTimeDelay = false;
var selectedLocale = null;
+
+ var stickySignatory = false;
var LOCALIZED_STRINGS = new Array();
LOCALIZED_STRINGS["es_ES"] = {
@@ -107,16 +111,23 @@ var MiniApplet = ( function ( window, undefined ) {
var CHECKTIME_OBLIGATORY = "CT_OBLIGATORY";
- // Tiempo de espera entre los intentos de conexion con autofirma.
+ // Tiempo de espera entre los intentos de conexion con autofirma por socket
var AUTOFIRMA_LAUNCHING_TIME = 2000;
-
- // Reintentos de conexion totales para detectar que esta instalado AutoFirma
- var AUTOFIRMA_CONNECTION_RETRIES = 10;
+
+ // Reintentos de conexion totales para detectar que esta instalado AutoFirma por socket
+ var AUTOFIRMA_CONNECTION_RETRIES = 15;
// Variable que se puede configurar para forzar el uso del modo de comunicacion por servidor intermedio
// entre la pagina web y AutoFirma
var forceWSMode = false;
+ // Variable que se puede configurar para forzar el uso de la aplicacion
+ // nativa instalada a traves del protocolo afirma://
+ var forceAFirma = false;
+
+ // Variable que devuelve si funciona el modo JNLP
+ var bJNLP = true;
+
/* ------------------------------------ */
/* Funciones de comprobacion de entorno */
/* ------------------------------------ */
@@ -157,6 +168,24 @@ var MiniApplet = ( function ( window, undefined ) {
return isWindows8() && navigator.userAgent.indexOf("ARM;") != -1;
}
+ /** Determina con un boolean si nos encontramos en un sistema Linux. */
+ function isLinux() {
+ return getOSName() == "linux";
+ }
+
+ /**
+ * Identifica el sistema operativo del usuario para notificarselo al servicio
+ * de generacion del fichero de despliegue JNLP.
+ * @returns Codigo del sistema operativo o "unknown" si no se conoce.
+ */
+ function getOSName() {
+ var osName="unknown";
+ if (navigator.appVersion.indexOf("Win")!=-1) osName="windows";
+ if (navigator.appVersion.indexOf("Mac")!=-1) osName="mac";
+ if (navigator.appVersion.indexOf("Linux")!=-1) osName="linux";
+ return osName;
+ }
+
/** Determina con un boolean si estamos en Internet Explorer */
function isInternetExplorer() {
return !!(navigator.userAgent.match(/MSIE/)) /* Internet Explorer 10 o inferior */
@@ -168,7 +197,7 @@ var MiniApplet = ( function ( window, undefined ) {
function isOldInternetExplorer() {
return !!(navigator.userAgent.match(/MSIE/));
}
-
+
function isFirefoxUAM() {
return navigator.userAgent.indexOf("UAM") > 0;
}
@@ -184,10 +213,33 @@ var MiniApplet = ( function ( window, undefined ) {
* Determina con un boolean si se accede a la web con Chrome
*/
function isChrome() {
- return navigator.userAgent.toUpperCase().indexOf("CHROME") != -1 ||
+ return navigator.userAgent.toUpperCase().indexOf("CHROME/") != -1 ||
navigator.userAgent.toUpperCase().indexOf("CHROMIUM") != -1;
}
+ /**
+ * Determina con un boolean si se accede a la web con Safari 10. Esta version no
+ * funciona bien con la comunicacion con sockets de AutoFirma.
+ */
+ function isSafari10() {
+ navigator.sayswho= (function(){
+ var ua= navigator.userAgent, tem,
+ M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
+ if(/trident/i.test(M[1])){
+ tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
+ return 'IE '+(tem[1] || '');
+ }
+ if(M[1]=== 'Chrome'){
+ tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
+ if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
+ }
+ M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
+ if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
+ return M.join(' ');
+ })();
+ return navigator.sayswho == 'Safari 10';
+ }
+
/**
* Determina con un boolean si el navegador es Microsoft Edge
*/
@@ -195,6 +247,21 @@ var MiniApplet = ( function ( window, undefined ) {
return !!navigator.userAgent.match(/Edge\/\d+/);
}
+ /**
+ * Informa si el usuario necesitará instalar AutoFirma para
+ * completar el proceso de firma.
+ */
+ function needNativeAppInstalled() {
+ return forceAFirma || isLinux() || isFirefox() || isAndroid() || isIOS();
+ }
+
+ /**
+ * Determina con un boolean si se ejecuta mediante JNLP
+ */
+ function isJNLP() {
+ return bJNLP;
+ }
+
/** Indica si el navegador detecta Java. Este valor no es completamente fiable, ya que
* Internet Explorer siempre indica que si esta activado. */
function isJavaEnabled() {
@@ -328,6 +395,18 @@ var MiniApplet = ( function ( window, undefined ) {
forceWSMode = force;
}
+ /** Permite establecer que la invocacion con AutoFirma sea a traves
+ * del protocolo afirma:// */
+ var setForceAFirma = function (force) {
+ forceAFirma = force;
+ }
+
+ /** Establece la direccion servicio para la generacion del JNLP de
+ * carga de AutoFirma. */
+ var setJnlpService = function (jnlp){
+ jnlpServiceAddress = jnlp;
+ }
+
/** Permite habilitar la comprobacion de la hora local contra la hora del servidor y
* establecer un tiempo maximo permitido y el comportamiento si se supera.
* Parametros:
@@ -415,7 +494,7 @@ var MiniApplet = ( function ( window, undefined ) {
// Si estamos claramente en un sistema movil o que no permite la ejecucion de Java,
// cargamos directamente el Cliente JavaScript
- if (isAndroid() || isIOS() || isWindowsRT() || isChrome() || isEdge()) {
+ if (isAndroid() || isIOS() || isWindowsRT() || isChrome() || isFirefox() || isEdge()) {
cargarAppAfirma(base, defaultKeyStore);
return;
}
@@ -458,23 +537,12 @@ var MiniApplet = ( function ( window, undefined ) {
loadMiniApplet(attributes, parameters);
- if (isFirefox()) {
- clienteFirma = document.getElementById("miniApplet");
+ clienteFirma = document.getElementById("miniApplet");
- // Si no esta definido el cliente es porque se ha intentado cargar el applet
- // y no se ha podido, asi que se usara la aplicacion nativa
- if (clienteFirma == null) {
- cargarAppAfirma(codeBase, defaultKeyStore);
- }
- }
- else {
- clienteFirma = document.getElementById("miniApplet");
-
- // Si no esta definido el cliente es porque se ha intentado cargar el applet
- // y no se ha podido, asi que se usara la aplicacion nativa
- if (clienteFirma == null) {
- cargarAppAfirma(codeBase, defaultKeyStore);
- }
+ // Si no esta definido el cliente es porque se ha intentado cargar el applet
+ // y no se ha podido, asi que se usara la aplicacion nativa
+ if (clienteFirma == null) {
+ cargarAppAfirma(codeBase, defaultKeyStore);
}
}
@@ -504,6 +572,9 @@ var MiniApplet = ( function ( window, undefined ) {
forceLoad();
clienteFirma.setKeyStore(ksType != null ? ksType : defaultKeyStore);
+
+ // Al haber cambiado el almacen, no tiene sentido que la variable sticky este a true
+ setStickySignatory(false);
}
var selectCertificate = function (params, successCallback, errorCallback) {
@@ -530,7 +601,7 @@ var MiniApplet = ( function ( window, undefined ) {
}
var sign = function (dataB64, algorithm, format, params, successCallback, errorCallback) {
-
+
forceLoad();
if (clientType == TYPE_APPLET) {
@@ -675,14 +746,120 @@ var MiniApplet = ( function ( window, undefined ) {
}
}
- var getFileNameContentBase64 = function (title, extensions, description, filePath) {
+ /**
+ * Inicia el proceso de carga de un fichero.
+ * Implementada tambien en el applet Java de firma
+ * @param title Titulo de la ventana de dialogo
+ * @param extensions Extensiones permitidas
+ * @param description Descripcion del tipo de archivo a cargar
+ * @param filePath Ruta del archivo por defecto
+ * @param successCallback Funcion de callback tras exito
+ * @param errorCallback Funcion de callback tras error
+ */
+ var getFileNameContentBase64 = function (title, extensions, description, filePath, successCallback, errorCallback) {
forceLoad();
- return buildData(clienteFirma.getFileNameContentBase64(title, extensions, description, filePath));
+
+ if (clientType == TYPE_APPLET) {
+ try {
+ var filenameDataBase64Pair = buildData(clienteFirma.getFileNameContentBase64(title, extensions, description, filePath));
+ if (successCallback == undefined || successCallback == null) {
+ return filenameDataBase64Pair;
+ }
+ var sepPos = filenameDataBase64Pair.indexOf('|');
+ successCallback(filenameDataBase64Pair.substring(0, sepPos), filenameDataBase64Pair.substring(sepPos + 1));
+ } catch(e) {
+ if (errorCallback == undefined || errorCallback == null) {
+ throw e;
+ }
+ errorCallback(clienteFirma.getErrorType(), clienteFirma.getErrorMessage());
+ }
+ }
+ else {
+ clienteFirma.getFileNameContentBase64(title, extensions, description, filePath, successCallback, errorCallback)
+ }
+
}
- var getMultiFileNameContentBase64 = function (title, extensions, description, filePath) {
+ /**
+ * Inicia el proceso de carga de uno o varios ficheros.
+ * Implementada tambien en el applet Java de firma
+ * @param title Titulo de la ventana de dialogo
+ * @param extensions Extensiones permitidas
+ * @param description Descripcion del tipo de archivo a cargar
+ * @param filePath Ruta del archivo por defecto
+ * @param successCallbackFunction Funcion de callback tras exito
+ * @param errorCallbackFunction Funcion de callback tras error
+ */
+ var getMultiFileNameContentBase64 = function (title, extensions, description, filePath, successCallback, errorCallback) {
forceLoad();
- return buildData(clienteFirma.getMultiFileNameContentBase64(title, extensions, description, filePath));
+
+ if (clientType == TYPE_APPLET) {
+
+ try {
+ var filenameDataBase64Pairs = buildData(clienteFirma.getMultiFileNameContentBase64(title, extensions, description, filePath));
+ if (successCallback == undefined || successCallback == null) {
+ return filenameDataBase64Pairs;
+ }
+
+ var fileNameArray = new Array();
+ var dataB64Array = new Array();
+ for (i = 0; i < filenameDataBase64Pairs.length; i++) {
+ var sepPos = filenameDataBase64Pairs[i].indexOf("|");
+ if (sepPos == -1) {
+ fileNameArray.push(filenameDataBase64Pairs[i]);
+ dataB64Array.push("");
+ }
+ else {
+ fileNameArray.push(filenameDataBase64Pairs[i].substring(0, sepPos));
+ dataB64Array.push(filenameDataBase64Pairs[i].substring(sepPos + 1));
+ }
+ }
+ successCallback(fileNameArray, dataB64Array);
+ } catch(e) {
+ if (errorCallback == undefined || errorCallback == null) {
+ throw e;
+ }
+ errorCallback(clienteFirma.getErrorType(), clienteFirma.getErrorMessage());
+ }
+ }
+ else {
+ clienteFirma.getMultiFileNameContentBase64(title, extensions, description, filePath, successCallback, errorCallback)
+ }
+ }
+
+ var getCurrentLog = function (successCallback, errorCallback) {
+ forceLoad();
+
+ if (clientType == TYPE_APPLET) {
+ var log = " === JAVASCRIPT INFORMATION === " +
+ "\nnavigator.appCodeName: " + navigator.appCodeName +
+ "\nnavigator.appName: " + navigator.appName +
+ "\nnavigator.appVersion: " + navigator.appVersion +
+ "\nnavigator.platform: " + navigator.platform +
+ "\nnavigator.userAgent: " + navigator.userAgent+
+ "\nnavigator.javaEnabled(): " + navigator.javaEnabled() +
+ "\nscreen.width: " + (window.screen ? screen.width : 0) +
+ "\nscreen.height: " + (window.screen ? screen.height : 0) +
+ "\n\n === CLIENTE LOG === \n";
+ try {
+ log += buildData(clienteFirma.getCurrentLog());
+ } catch(e) {
+ if (errorCallback == undefined || errorCallback == null) {
+ throw e;
+ }
+ errorCallback(clienteFirma.getErrorType(), clienteFirma.getErrorMessage());
+ return;
+ }
+
+ if (successCallback == undefined || successCallback == null) {
+ return log;
+ }
+ successCallback(log);
+ }
+ else {
+ clienteFirma.getCurrentLog(successCallback, errorCallback)
+ }
+
}
var echo = function () {
@@ -690,9 +867,26 @@ var MiniApplet = ( function ( window, undefined ) {
return clienteFirma.echo();
}
- var setStickySignatory = function (sticky) {
+ /**
+ * Establece el valor de la variable "stickySignatory" que permite fijar
+ * un certicado seleccionado para futuras invocaciones, de modo que no
+ * sea necesario volver a seleccionarlo mientras el valor sea true o
+ * caduque la conexion en caso de invocacion por protocolo/socket
+ */
+ var setStickySignatory = function(sticky) {
forceLoad();
- return clienteFirma.setStickySignatory(sticky);
+
+ if (clientType == TYPE_APPLET) {
+
+ clienteFirma.setStickySignatory(sticky);
+
+ } else {
+ // En caso de no cargar el applet y utilizar autofirma, se
+ // establecera la variable con el valor seleccionado para su
+ // posterior uso en cada invocacion por protocolo
+ stickySignatory = sticky;
+ }
+
}
var setLocale = function (locale) {
@@ -709,21 +903,7 @@ var MiniApplet = ( function ( window, undefined ) {
forceLoad();
return clienteFirma.getErrorType();
}
-
- var getCurrentLog = function () {
- forceLoad();
- return " === JAVASCRIPT INFORMATION === " +
- "\nnavigator.appCodeName: " + navigator.appCodeName +
- "\nnavigator.appName: " + navigator.appName +
- "\nnavigator.appVersion: " + navigator.appVersion +
- "\nnavigator.platform: " + navigator.platform +
- "\nnavigator.userAgent: " + navigator.userAgent+
- "\nnavigator.javaEnabled(): " + navigator.javaEnabled() +
- "\nscreen.width: " + (window.screen ? screen.width : 0) +
- "\nscreen.height: " + (window.screen ? screen.height : 0) +
- "\n\n === CLIENTE LOG === \n" +
- clienteFirma.getCurrentLog();
- }
+
var setServlets = function (storageServlet, retrieverServlet) {
@@ -829,7 +1009,9 @@ var MiniApplet = ( function ( window, undefined ) {
clientType = TYPE_APPLET;
}
else if (clientType == null) {
- cargarAppAfirma(codeBase, defaultKeyStore);
+ // Inicializamos la carga de la aplicacion nativa, indicando que no se
+ // haga una precarga con JNLP, ya que ahora estamos en medio de una operacion
+ cargarAppAfirma(codeBase, defaultKeyStore, true);
}
setServlets(storageServletAddress, retrieverServletAddress);
}
@@ -867,6 +1049,82 @@ var MiniApplet = ( function ( window, undefined ) {
return buffer;
}
+ /**
+ * Abre una URL en el navegador.
+ * @param url URL que se desea abrir.
+ */
+ function openUrl (url) {
+
+ // Usamos el modo de invocacion mas apropiado segun el entorno
+ if (isChrome() || isIOS()) {
+ // Usamos document.location porque tiene mejor soporte por los navegadores que
+ // window.location que es el mecanismo estandar
+ document.location = url;
+ }
+ else {
+
+ // Si ya existe el iframe, lo eliminamos para despues volverlo a crear
+ if (document.getElementById("iframeAfirma") != null) {
+ try {
+ var element = document.getElementById("iframeAfirma");
+ element.outerHTML = "";
+ delete element;
+ }
+ catch (e) {
+ // No hacemos nada
+ }
+ }
+
+ // En el caso de ser una version de internet Explorer que soportase la deteccion de aplicacion
+ // capaces de manejar el protocolo, aprovechamos esta caracteristica (Internet Explorer para Windows 8 Modern UI)
+
+ if (navigator.msLaunchUri) {
+ navigator.msLaunchUri(
+ url,
+ null,
+ function() {
+ // Bloqueamos la conexion para evitar que se sigan haciendo comprobaciones
+ wrongInstallation = true;
+ }
+ );
+ }
+ else {
+ // Abrimos la URL por medio de un iframe
+ openUrlWithIframe(url);
+ }
+ }
+ }
+
+ /**
+ * Llama a la aplicacion de firma por medio de un iframe.
+ * @param url URL de invocacion.
+ */
+ function openUrlWithIframe (url) {
+ var iframeElem = document.createElement("iframe");
+
+ var idAttr = document.createAttribute("id");
+ idAttr.value = "iframeAfirma";
+ iframeElem.setAttributeNode(idAttr);
+
+ var srcAttr = document.createAttribute("src");
+ srcAttr.value = url;
+ iframeElem.setAttributeNode(srcAttr);
+
+ var heightAttr = document.createAttribute("height");
+ heightAttr.value = 1;
+ iframeElem.setAttributeNode(heightAttr);
+
+ var widthAttr = document.createAttribute("width");
+ widthAttr.value = 1;
+ iframeElem.setAttributeNode(widthAttr);
+
+ var styleAttr = document.createAttribute("style");
+ styleAttr.value = "display: none;";
+ iframeElem.setAttributeNode(styleAttr);
+
+ document.body.appendChild(iframeElem);
+ }
+
/**************************************************************
**************************************************************
**************************************************************
@@ -886,13 +1144,13 @@ var MiniApplet = ( function ( window, undefined ) {
* - No se fuerce el uso del servidor intermedio.
* En caso contrario, la comunicacion se realizara mediante un servidor intermedio.
*/
- function cargarAppAfirma(clientAddress, keystore) {
+ function cargarAppAfirma(clientAddress, keystore, avoidJnlpLoad) {
if (!keystore) {
keystore = getDefaultKeystore();
}
- if (!isIOS() && !isAndroid() && !isOldInternetExplorer() && !isEdge() && !forceWSMode){
+ if (!forceWSMode && !isIOS() && !isAndroid() && !isOldInternetExplorer() && !isEdge() && !isSafari10()){
clienteFirma = new AppAfirmaJSSocket(clientAddress, window, undefined);
clienteFirma.setKeyStore(keystore);
clientType = TYPE_JAVASCRIPT_SOCKET;
@@ -903,6 +1161,14 @@ var MiniApplet = ( function ( window, undefined ) {
clientType = TYPE_JAVASCRIPT_WEB_SERVICE;
}
+ // Si se dan las condiciones que requieren el uso de la aplicacion nativa,
+ // por entorno o porque se haya configurado para su uso, se intenta cargar
+ // esta version
+ if (!avoidJnlpLoad && !needNativeAppInstalled() && !!jnlpServiceAddress) {
+ // Aplicamos un retardo en la carga de la aplicacion WebStart para dar tiempo a cargar la pagina
+ var jnlpUrl = "jnlp" + jnlpServiceAddress.substring(4) + "?os=" + getOSName() + "&arg=" + Base64.encode("afirma://service?op=install", true);
+ setTimeout(openUrl, 2000, jnlpUrl);
+ }
}
var AppAfirmaJSSocket = ( function (clientAddress, window, undefined) {
@@ -915,7 +1181,7 @@ var MiniApplet = ( function ( window, undefined ) {
var errorMessage = '';
var errorType = '';
- /** Puerto actual */
+ /** Puerto a traves del que se ha conectado con la aplicacion nativa. */
var port = "";
var idSession;
@@ -1033,6 +1299,7 @@ var MiniApplet = ( function ( window, undefined ) {
data.properties = generateDataKeyValue ("properties", extraParams != null ? Base64.encode(extraParams) : null);
data.keystore = generateDataKeyValue ("keystore", defaultKeyStore != null ? defaultKeyStore : null);
data.ksb64 = generateDataKeyValue ("ksb64", defaultKeyStore != null ? Base64.encode(defaultKeyStore) : null);
+ data.sticky = generateDataKeyValue ("sticky", stickySignatory);
execAppIntent(buildUrl(data));
}
@@ -1158,6 +1425,7 @@ var MiniApplet = ( function ( window, undefined ) {
data.batchpostsignerurl = generateDataKeyValue("batchpostsignerurl", batchPostSignerUrl);
data.properties = generateDataKeyValue ("properties", extraParams != null ? Base64.encode(extraParams) : null);
data.dat = generateDataKeyValue ("dat", batchB64 == "" ? null : batchB64);
+ data.sticky = generateDataKeyValue ("sticky", stickySignatory);
return data;
}
@@ -1229,58 +1497,16 @@ var MiniApplet = ( function ( window, undefined ) {
}
}
idSession = generateNewIdSession();
- openUrl("afirma://service?ports=" + portsLine + "&v=" + PROTOCOL_VERSION + "&idsession=" + idSession);
- }
-
- /**
- * Llama a la aplicacion de firma a traves de la URL de invocacion sin que afecte
- * a la pagina que se esta mostrando.
- * @param url URL de invocacion.
- */
- function openUrl (url) {
- // Usamos document.location porque tiene mejor soporte por los navegadores que
- // window.location que es el mecanismo estandar
- if (isChrome()) {
- document.location = url;
+ // Si no se dan las condiciones que requieren el uso de la aplicacion nativa,
+ // por entorno y si se ha configurado la URL del servicio, cargamos la version JNLP
+ if (!needNativeAppInstalled() && !!jnlpServiceAddress) {
+ openUrl("jnlp" + jnlpServiceAddress.substring(4) + "?os=" + getOSName() + "&arg=" + Base64.encode("afirma://service?ports=" + portsLine + "&v=" + PROTOCOL_VERSION + "&idsession=" + idSession, true));
}
+ // En caso contrario, cargamos la version nativa
else {
-
- // Si ya existe el iframe, lo eliminamos para despues volverlo a crear
- if (document.getElementById("iframeAfirma") != null) {
- try {
- var element = document.getElementById("iframeAfirma");
- element.outerHTML = "";
- delete element;
- }
- catch (e) {
- // No hacemos nada
- }
- }
-
- var iframeElem = document.createElement("iframe");
-
- var idAttr = document.createAttribute("id");
- idAttr.value = "iframeAfirma";
- iframeElem.setAttributeNode(idAttr);
-
- var srcAttr = document.createAttribute("src");
- srcAttr.value = url;
- iframeElem.setAttributeNode(srcAttr);
-
- var heightAttr = document.createAttribute("height");
- heightAttr.value = 1;
- iframeElem.setAttributeNode(heightAttr);
-
- var widthAttr = document.createAttribute("width");
- widthAttr.value = 1;
- iframeElem.setAttributeNode(widthAttr);
-
- var styleAttr = document.createAttribute("style");
- styleAttr.value = "display: none;";
- iframeElem.setAttributeNode(styleAttr);
-
- document.body.appendChild(iframeElem);
+ bJNLP = false;
+ openUrl("afirma://service?ports=" + portsLine + "&v=" + PROTOCOL_VERSION + "&idsession=" + idSession);
}
}
@@ -1297,6 +1523,8 @@ var MiniApplet = ( function ( window, undefined ) {
data.format = generateDataKeyValue ("format", format);
data.properties = generateDataKeyValue ("properties", extraParams != null ? Base64.encode(extraParams) : null);
data.dat = generateDataKeyValue ("dat", dataB64 == "" ? null : dataB64);
+ data.sticky = generateDataKeyValue ("sticky", stickySignatory);
+
return data;
}
@@ -1315,6 +1543,23 @@ var MiniApplet = ( function ( window, undefined ) {
data.properties = generateDataKeyValue ("properties", extraParams != null ? Base64.encode(extraParams) : null);
data.filename = generateDataKeyValue ("filename", outputFileName);
data.dat = generateDataKeyValue ("dat", dataB64 == "" ? null : dataB64);
+ data.sticky = generateDataKeyValue ("sticky", stickySignatory);
+
+ return data;
+ }
+
+ /**
+ * Genera el objeto con los datos de la transaccion para la operacion
+ * de carga/multicarga
+ */
+ function generateDataToLoad(loadId, title, extensions, description, filePath, multiload) {
+ var data = new Object();
+ data.op = generateDataKeyValue("op", loadId);
+ data.title = generateDataKeyValue("title", title);
+ data.extensions = generateDataKeyValue("exts", extensions);
+ data.description = generateDataKeyValue("desc", description);
+ data.filePath = generateDataKeyValue("filePath", filePath);
+ data.multiload = generateDataKeyValue("multiload", multiload);
return data;
}
@@ -1328,9 +1573,9 @@ var MiniApplet = ( function ( window, undefined ) {
}
/**
- * Intenta conectar con la aplicación nativa mandando una peticion echo al puerto.
- * Si la aplicación responde lanzamos la ejecucion del servicio.
- * Si la aplicación no responde volvemos a lanzar cada 2 segundos otra peticion echo hasta que una
+ * Intenta conectar con la aplicacion nativa mandando una peticion echo al puerto.
+ * Si la aplicacion responde lanzamos la ejecucion del servicio.
+ * Si la aplicacion no responde volvemos a lanzar cada 2 segundos otra peticion echo hasta que una
* peticion sea aceptada.
*/
function executeEchoByService (currentPort, url, timeoutResetCounter, semaphore) {
@@ -1403,7 +1648,7 @@ var MiniApplet = ( function ( window, undefined ) {
*/
function executeOperationByService (url) {
- // Si el envio se debe fragmentar, llamamos a una función que se encarga
+ // Si el envio se debe fragmentar, llamamos a una funcion que se encarga
// de mandar la peticion recursivamente
if (url.length > URL_MAX_SIZE) {
executeOperationRecursive(url, 1, Math.ceil(url.length/URL_MAX_SIZE));
@@ -1446,7 +1691,7 @@ var MiniApplet = ( function ( window, undefined ) {
httpRequest.onerror = function(e) {
// status error 0 es que no se ha podido comunicar con la aplicacion
if (e.target.status == 0) {
- errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexión con la aplicación @firma "+e.target.statusText);
+ errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexion con la aplicacion @firma " + e.target.statusText);
}
// error desconocido
else {
@@ -1458,8 +1703,8 @@ var MiniApplet = ( function ( window, undefined ) {
}
/**
- * Manda los datos a la aplicación nativa en varios fragmentos porque ha habido que dividir los datos.
- * Se va mandando cada petición cuando se reciba la anterior.
+ * Manda los datos a la aplicacion nativa en varios fragmentos porque ha habido que dividir los datos.
+ * Se va mandando cada peticion cuando se reciba la anterior.
*/
function executeOperationRecursive (url, i, iFinal) {
@@ -1503,7 +1748,7 @@ var MiniApplet = ( function ( window, undefined ) {
httpRequest.onerror = function(e) {
// Status error 0 es que no se ha podido comunicar con la aplicacion
if (e.target.status == 0){
- errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexión con la aplicación @firma "+e.target.statusText);
+ errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexion con la aplicacion @firma " + e.target.statusText);
}
// Error desconocido
else{
@@ -1556,7 +1801,7 @@ var MiniApplet = ( function ( window, undefined ) {
httpRequest.onerror = function(e) {
// status error 0 es que no se ha podido comunicar con la aplicacion
if (e.target.status == 0){
- errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexión con la aplicación @firma "+e.target.statusText);
+ errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexion con la aplicacion @firma " + e.target.statusText);
}
// error desconocido
else{
@@ -1612,7 +1857,7 @@ var MiniApplet = ( function ( window, undefined ) {
httpRequest.onerror = function(e) {
// status error 0 es que no se ha podido comunicar con la aplicacion
if (e.target.status == 0){
- errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexión con la aplicación @firma "+e.target.statusText);
+ errorServiceResponseFunction("java.lang.IOException", "Se ha perdido la conexion con la aplicacion @firma " + e.target.statusText);
}
// error desconocido
else{
@@ -1698,7 +1943,75 @@ var MiniApplet = ( function ( window, undefined ) {
}
return;
}
-
+
+ // Vengo de getCurrentLog
+ if (data.length > 150 && data.substr(0, 150).indexOf("") != -1) {
+ var log = " === JAVASCRIPT INFORMATION === " +
+ "\nnavigator.appCodeName: " + navigator.appCodeName +
+ "\nnavigator.appName: " + navigator.appName +
+ "\nnavigator.appVersion: " + navigator.appVersion +
+ "\nnavigator.platform: " + navigator.platform +
+ "\nnavigator.userAgent: " + navigator.userAgent+
+ "\nnavigator.javaEnabled(): " + navigator.javaEnabled() +
+ "\nscreen.width: " + (window.screen ? screen.width : 0) +
+ "\nscreen.height: " + (window.screen ? screen.height : 0) +
+ "\n\n === CLIENTE LOG === \n" + data;
+ successCallback(log);
+ return;
+ }
+
+ // Compruebo si se trata de una operacion de carga/multicarga (load).
+ // El separador "|" distingue los pares "filename-1:dataBase64-1|filename-2:dataBase64-2...", uno por cada archivo cargado.
+ // Devolveremos un array en el que cada posicion sera uno de estos pares: "filename-n:dataBase64-n".
+ // La funcion de callback realizara el tratamiento deseado,
+ // pudiendo obtener cada dato del par teniendo en cuenta el
+ // separador ":"
+ if (data.indexOf(":") > 0) {
+
+ var fileNamesDataBase64 = data.split("|");
+
+ if (fileNamesDataBase64.length == 1) {
+
+ var sepPos = fileNamesDataBase64[0].indexOf(":");
+ var fileNameDataBase64 = fileNamesDataBase64[0];
+
+ if (sepPos == -1) {
+ fileName = Base64.decode(fileNameDataBase64, true);
+ }
+ else {
+ fileName = fileNameDataBase64.substring(0, sepPos);
+ dataB64 = fileNameDataBase64.substring(sepPos + 1).replace(/\-/g, "+").replace(/\_/g, "/");
+ }
+
+ successCallback(fileName,dataB64);
+
+ return;
+
+ } else if (fileNamesDataBase64.length > 1 ) {
+
+ var fileNameArray = new Array();
+ var dataB64Array = new Array();
+
+ for (i = 0; i < fileNamesDataBase64.length; i++) {
+ var sepPos = fileNamesDataBase64[i].indexOf(":");
+
+ if (sepPos == -1) {
+ fileNameArray.push(fileNamesDataBase64[i]);
+ dataB64Array.push("");
+ }
+ else {
+ fileNameArray.push(fileNamesDataBase64[i].substring(0, sepPos));
+ dataB64Array.push(fileNamesDataBase64[i].substring(sepPos + 1).replace(/\-/g, "+").replace(/\_/g, "/"));
+ }
+ }
+
+ }
+
+ successCallback(fileNameArray,dataB64Array);
+
+ return;
+ }
+
// Interpretamos el resultado como un base 64 y el certificado y los datos cifrados
var signature;
var certificate = null;
@@ -1771,8 +2084,8 @@ var MiniApplet = ( function ( window, undefined ) {
data.op = generateDataKeyValue ("op", "save");
data.title = generateDataKeyValue ("title", title);
data.filename = generateDataKeyValue ("filename", filename);
- data.extension = generateDataKeyValue ("extension", extension);
- data.description = generateDataKeyValue ("description", description);
+ data.extension = generateDataKeyValue ("exts", extension);
+ data.description = generateDataKeyValue ("desc", description);
data.dat = generateDataKeyValue ("dat", dataB64 == "" ? null : dataB64);
return data;
@@ -1803,20 +2116,76 @@ var MiniApplet = ( function ( window, undefined ) {
/**
- * Carga de un fichero. Operacion no soportada.
- * Implementada en el applet Java de firma.
+ * Inicia el proceso de carga de un fichero.
+ * Implementada tambien en el applet Java de firma
+ * @param title Titulo de la ventana de dialogo
+ * @param extensions Extensiones permitidasg
+ * @param description Descripcion del tipo de archivo a cargar
+ * @param filePath Ruta del archivo por defecto
+ * @param successCallbackFunction Funcion de callback tras exito
+ * @param errorCallbackFunction Funcion de callback tras error
*/
- function getFileNameContentBase64 (title, extensions, description) {
- throwException(UnsupportedOperationException, "La operacion de carga de ficheros no esta soportada");
+ function getFileNameContentBase64 (title, extensions, description, filePath, successCallbackFunction, errorCallbackFunction) {
+ successCallback = successCallbackFunction;
+ errorCallback = errorCallbackFunction;
+ getLoadContentBase64ByService("load", title, extensions, description, filePath, false);
}
/**
- * Carga de multiples ficheros. Operacion no soportada.
- * Implementada en el applet Java de firma.
+ * Inicia el proceso de carga de uno o varios ficheros.
+ * Implementada tambien en el applet Java de firma
+ * @param title Titulo de la ventana de dialogo
+ * @param extensions Extensiones permitidas
+ * @param description Descripcion del tipo de archivo a cargar
+ * @param filePath Ruta del archivo por defecto
+ * @param successCallbackFunction Funcion de callback tras exito
+ * @param errorCallbackFunction Funcion de callback tras error
*/
- function getMultiFileNameContentBase64 (title, extensions, description) {
- throwException(UnsupportedOperationException, "La operacion de carga de multiples ficheros no esta soportada");
+ function getMultiFileNameContentBase64 (title, extensions, description, filePath, successCallbackFunction, errorCallbackFunction) {
+ successCallback = successCallbackFunction;
+ errorCallback = errorCallbackFunction;
+ getLoadContentBase64ByService("load", title, extensions, description, filePath, true);
}
+
+ /**
+ * Inicia el proceso de obtencion del log actual de la aplicacion.
+ * Implementada tambien en el applet Java de firma
+ * @param successCallbackFunction Funcion de callback tras exito
+ * @param errorCallbackFunction Funcion de callback tras error
+ */
+ function getCurrentLog (successCallbackFunction, errorCallbackFunction) {
+ successCallback = successCallbackFunction;
+ errorCallback = errorCallbackFunction;
+ getCurrentLogByService("getLog");
+ }
+
+ /**
+ * Realiza una operacion de carga de fichero comunicandose con la
+ * aplicacion nativa por socket.
+ * @param loadId Identificador de la operacion a realizar (load).
+ * @param title Titulo de la ventana de dialogo
+ * @param extensions Extensiones permitidas
+ * @param description Descripcion del tipo de archivo a cargar
+ * @param filePath Ruta del archivo por defecto
+ * @param multiload true si permite la seleccion de varios ficheros,
+ * false si solo se permite seleccionar un fichero.
+ */
+ function getLoadContentBase64ByService (loadId, title, extensions, description, filePath, multiload) {
+
+ var data = generateDataToLoad(loadId, title, extensions, description, filePath, multiload);
+
+ execAppIntent(buildUrl(data));
+ }
+
+ /**
+ * Realiza una operacion de obtencion de log actual de la aplicacion
+ */
+ function getCurrentLogByService() {
+
+ var data = generateDataToLoad("getLog");
+
+ execAppIntent(buildUrl(data));
+ }
/**
* Funcion para la comprobacion de existencia del objeto. No hace nada.
@@ -1825,15 +2194,7 @@ var MiniApplet = ( function ( window, undefined ) {
function echo () {
return "Cliente JavaScript";
}
-
- /**
- * No hace nada.
- * Implementada en el applet Java de firma.
- */
- function setStickySignatory (sticky) {
- // No hace nada
- }
-
+
/**
* Recupera el mensaje de error asociado al ultimo error capturado.
* Implementada en el applet Java de firma.
@@ -1850,14 +2211,6 @@ var MiniApplet = ( function ( window, undefined ) {
return errorType;
}
- /**
- * Recupera el log de la aplicacion. Actualmente, el log solo esta
- * disponible en el applet, no en las aplicacion moviles.
- */
- function getCurrentLog () {
- return "Applet no cargado";
- }
-
/**
* Funcion para identificar el tipo de objeto del Cliente (javascript, applet,...).
*/
@@ -1957,7 +2310,7 @@ var MiniApplet = ( function ( window, undefined ) {
* Implementada en el applet Java de firma
*/
function selectCertificate (extraParams, successCallback, errorCallback) {
- throwException(UnsupportedOperationException, "La operacion de seleccion de certificados no esta soportada");
+ throwException("java.lang.UnsupportedOperationException", "La operacion de seleccion de certificados no esta soportada");
}
/**
@@ -2218,22 +2571,6 @@ var MiniApplet = ( function ( window, undefined ) {
}
}
- /**
- * Carga de un fichero. Operacion no soportada.
- * Implementada en el applet Java de firma.
- */
- function getFileNameContentBase64 (title, extensions, description) {
- throwException(UnsupportedOperationException, "La operacion de carga de ficheros no esta soportada");
- }
-
- /**
- * Carga de multiples ficheros. Operacion no soportada.
- * Implementada en el applet Java de firma.
- */
- function getMultiFileNameContentBase64 (title, extensions, description) {
- throwException(UnsupportedOperationException, "La operacion de carga de multiples ficheros no esta soportada");
- }
-
/**
* Funcion para la comprobacion de existencia del objeto. No hace nada.
* Implementada en el applet Java de firma.
@@ -2242,14 +2579,6 @@ var MiniApplet = ( function ( window, undefined ) {
return "Cliente JavaScript";
}
- /**
- * No hace nada.
- * Implementada en el applet Java de firma.
- */
- function setStickySignatory (sticky) {
- // No hace nada
- }
-
/**
* Recupera el mensaje de error asociado al ultimo error capturado.
* Implementada en el applet Java de firma.
@@ -2304,6 +2633,13 @@ var MiniApplet = ( function ( window, undefined ) {
* GET en un Sistema/Navegador concreto.
*/
function isURLTooLong(url) {
+
+ // En las llamadas al esquema JNLP, Java soporta una cantidad
+ // limitada de caracteres en la URL
+ if (bJNLP) {
+ return url.length > 500;
+ }
+
if (isAndroid()) {
return url.length > MAX_LONG_ANDROID_URL;
}
@@ -2456,15 +2792,20 @@ var MiniApplet = ( function ( window, undefined ) {
wrongInstallation = false;
- // Invocamos al cliente de firma movil.
- try {
- openUrl(intentURL, errorCallback);
+ // Invocamos al cliente de firma
+
+ // Si no se pide cargar la aplicacion nativa, ni el entorno lo requiere y
+ // si se ha configurado el servicio JNLP, cargamos la aplicacion JNLP
+ if (!needNativeAppInstalled() && !!jnlpServiceAddress) {
+ openUrl("jnlp" + jnlpServiceAddress.substring(4) + "?os=" + getOSName() + '&arg=' + Base64.encode(intentURL, true));
}
- catch (e) {
- //console.log("Error al abrir la aplicacion nativa: " + e);
- return;
+ // En caso contrario, desplegamos la version nativa
+ else {
+ bJNLP = false;
+ openUrl(intentURL);
}
+ // Preguntamos repetidamente por el resultado
if (successCallback != null || errorCallback != null) {
if (idSession != null && idSession != undefined &&
((successCallback != undefined && successCallback != null) ||
@@ -2541,81 +2882,6 @@ var MiniApplet = ( function ( window, undefined ) {
return buildUrl(op, newParams);
};
- /**
- * Llama a la aplicacion de firma a traves de la URL de invocacion sin que afecte
- * a la pagina que se esta mostrando.
- * @param url URL de invocacion.
- * @param errorCallback Funcion de error que deberia lanzarse (ademas de una excepcion),
- * si no fuese posible abrir la URL. Puede ser nulo.
- */
- function openUrl (url, errorCallback) {
-
- // Usamos el modo de invocacion mas apropiado segun el entorno
- if (isChrome() || isIOS()) {
- // Usamos document.location porque tiene mejor soporte por los navegadores que
- // window.location que es el mecanismo estandar
- document.location = url;
- }
- else {
-
- // Si ya existe el iframe, lo eliminamos para despues volverlo a crear
- if (document.getElementById("iframeAfirma") != null) {
- try {
- var element = document.getElementById("iframeAfirma");
- element.outerHTML = "";
- delete element;
- }
- catch (e) {
- // No hacemos nada
- }
- }
-
- // En el caso de ser una version de internet Explorer que soportase la deteccion de aplicacion
- // capaces de manejar el protocolo, aprovechamos esta caracteristica (Internet Explorer para Windows 8 Modern UI)
-
- if (navigator.msLaunchUri) {
- navigator.msLaunchUri(
- url,
- null,
- function() {
- // Bloqueamos la conexion para evitar que se sigan haciendo comprobaciones
- wrongInstallation = true;
- }
- );
- }
- else {
- // Abrimos la URL por medio de un iframe
- openUrlWithIframe(url);
- }
- }
- }
-
- /**
- * Llama a la aplicacion de firma por medio de un iframe.
- * @param url URL de invocacion.
- */
- function openUrlWithIframe (url) {
- var iframeElem = document.createElement("iframe");
-
- var idAttr = document.createAttribute("id");
- idAttr.value = "iframeAfirma";
- iframeElem.setAttributeNode(idAttr);
-
- var srcAttr = document.createAttribute("src");
- srcAttr.value = url;
- iframeElem.setAttributeNode(srcAttr);
-
- var heightAttr = document.createAttribute("height");
- heightAttr.value = 1;
- iframeElem.setAttributeNode(heightAttr);
-
- var widthAttr = document.createAttribute("width");
- widthAttr.value = 1;
- iframeElem.setAttributeNode(widthAttr);
-
- document.body.appendChild(iframeElem);
- }
-
/**
* Ejecuta el metodo de error si el html recuperado es tal o el metodo de exito si no lo es,
* en cuyo caso previamente descifrara el resultado.
@@ -2675,7 +2941,7 @@ var MiniApplet = ( function ( window, undefined ) {
}
else {
if (cipherKey != undefined && cipherKey != null) {
- certificate = decipher(html.substring(0, sepPos), cipherKey);
+ certificate = decipher(html.substring(0, sepPos), cipherKey, true);
signature = decipher(html.substring(sepPos + 1), cipherKey);
}
else {
@@ -2764,16 +3030,17 @@ var MiniApplet = ( function ( window, undefined ) {
* Realiza un descifrado DES compatible con Java (Algoritmo DES, modo CBC, sin Padding).
* Recibe en base 64 la cadena de texto cifrado antecedido por el padding anadido manualmente
* a los datos para permitir el cifrado DES (separado por un punto ('.')), ademas de la clave
- * para descifrar.
+ * para descifrar y, opcionalmente, un booleano que indica si se trata de un cifrado intermedio
+ * devuelto por la aplicacion, lo que permite reajustar el padding.
* Como resultado devuelve la cadena de texto descifrada en base 64.
*/
- function decipher(cipheredData, key) {
+ function decipher(cipheredData, key, intermediate) {
var dotPos = cipheredData.indexOf('.');
var padding = cipheredData.substr(0, dotPos);
var deciphered = Cipher.des(key, Cipher.base64ToString(fromBase64UrlSaveToBase64(cipheredData.substr(dotPos + 1))), 0, 0, null);
- return Cipher.stringToBase64(deciphered.substr(0, deciphered.length - parseInt(padding) - 8));
+ return Cipher.stringToBase64(deciphered.substr(0, deciphered.length - parseInt(padding) - (intermediate ? 0 : 8)));
}
/**
@@ -2819,6 +3086,7 @@ var MiniApplet = ( function ( window, undefined ) {
getBase64FromText : getBase64FromText,
getTextFromBase64 : getTextFromBase64,
setServlets : setServlets,
+ setJnlpService: setJnlpService,
setStickySignatory : setStickySignatory,
setLocale : setLocale,
getErrorMessage : getErrorMessage,
@@ -2859,7 +3127,7 @@ var MiniApplet = ( function ( window, undefined ) {
/* Variable para forzar el uso del mecanismo de comunicacion por servidor intermedio */
setForceWSMode : setForceWSMode,
-
+ setForceAFirma : setForceAFirma,
/* Metodos visibles. */
cargarMiniApplet : cargarMiniApplet,
cargarAppAfirma : cargarAppAfirma,
@@ -2879,13 +3147,16 @@ var MiniApplet = ( function ( window, undefined ) {
downloadRemoteData : downloadRemoteData,
setKeyStore : setKeyStore,
setServlets : setServlets,
+ setJnlpService: setJnlpService,
setStickySignatory : setStickySignatory,
setLocale : setLocale,
getErrorMessage : getErrorMessage,
getErrorType : getErrorType,
getCurrentLog : getCurrentLog,
isAndroid : isAndroid,
- isIOS : isIOS
+ isIOS : isIOS,
+ isJNLP : isJNLP,
+ needNativeAppInstalled : needNativeAppInstalled
};
})(window, undefined);
diff --git a/esign-cert-share/src/main/amp/web/sign/sign-frame.jsp b/esign-cert-share/src/main/amp/web/sign/sign-frame.jsp
index 620986c..21d3dba 100644
--- a/esign-cert-share/src/main/amp/web/sign/sign-frame.jsp
+++ b/esign-cert-share/src/main/amp/web/sign/sign-frame.jsp
@@ -24,7 +24,7 @@
{
str = str.concat('\nsignReason=' + unicodeEscape(signaturePurpose));
}
-
+
function doSign(dataToSign, signedData, signerRole) {
signedData.value = MiniApplet.sign(dataToSign.value,
signatureAlg,