/**
*
* Parametri Oggetto irenHmac
*
* @typedef {Object} irenHmac.options - Parametri di inizializzazione dell'oggetto
* irenHmac
* @property {string} serviceUrl - url del servizio di verifica
* @property {string} method - metodo di chiamata del servizio
* (GET o POST)
* @property {string} authPrm - parametro da considerare
* nell'autenticazione
* @property {string} reqParams - Parametri di GET per il calcolo dell'Hash
* @property {string} invalidParams - Parametri di GET da non considerare
* nella creazione della Hash
* @property {string} verified - stato di verifica dell'oggetto HMac
* @property {string} path - path della pagina
* @property {string} cookie - nome del cookie dove recuperare la secret
* @property {string} secret - SECRET
* @property {string} noValidPage - pagina di redirect se validazione fallita
* @property {string} noAuthPage - pagina di redirect se nessuna
* autenticazione fornita
*/
(function () {
/**
* Classe irenHmac:
*
* @constructs irenHmac
* @requires js/sha256.js
* @requires js/jquery.js
* @param {irenHmac.options} options - Parametri di inizializzazione dell'oggetto
* irenHmac
* @return {Object} irenHmac - Oggetto irenHmac
*/
this.irenHmac = function( options ) {
// This is the easiest way to have default options.
var invalid = ['hmac'];
var prms = this.getQueryParams();;
var pathname = this.getCurrentPath();
var defaults = {
serviceUrl : "service.php",
method : "POST",
authPrm : "hmac",
reqParams : prms,
noAuthPage : "noauth.html",
noValidPage : "novalid.html",
verified : 0,
invalidParams : invalid,
path : pathname,
cookie : "___IREN___HMAC",
secret : "mysecret",
}
if (arguments[0] && typeof arguments[0] === "object") {
this.options = extendDefaults(defaults, arguments[0]);
}
else{
this.options = defaults;
}
if (!this.options.reqParams[this.options.authPrm]){
this.noAuth();
}
return this;
};
// Recupero i parametri di GET
/**
* Metodo che data una queryString ne prende i suoi parametri e restituisce
* un oggetto
* @return {Object} - Oggetto con i parametri della query string
*/
irenHmac.prototype.getQueryParams = function(){
var params = {};
if (location.search) {
var parts = location.search.substring(1).split('&');
for (var i = 0; i < parts.length; i++) {
var nv = parts[i].split('=');
if (!nv[0]) continue;
params[nv[0]] = decodeURIComponent(nv[1]) || true;
}
}
return params;
};
// Creazione della query string prendendo i parametri di GET e riordinandoli
/**
* Metodo che dati i parametri in options.reqParams li ordina i ordine alfabetico,
* elimina i parametri in options.inValidParams e restituisce una queryString
* codificata
* @return {string} QueryString
*/
irenHmac.prototype.createQueryString = function(){
var str = [];
var unsortedObj = this.options.reqParams;
obj = getSortedObject(unsortedObj);
for(var p in obj){
if (obj.hasOwnProperty(p) && (this.options.invalidParams.indexOf(p)==-1)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
//str.push(p + "=" + obj[p])
}
}
return (this.options.path + '?' + str.join("&"));
}
// Restituzione del path della pagina chiamata (Serve nel calcolo del messaggio e della Hash)
/**
* Metodo che restituisce il path della url corrente
* @return {string} Path della url corrente
*/
irenHmac.prototype.getCurrentPath = function(){
return document.location.pathname;
};
//Recupero della secret in prima battuta da Cookie altrimenti da opzioni
/**
* Metodo che restituisce la secret per creare la hash
* Se viene passato il parametro cerca nel cookie altrimenti nel cookie di default.
* Se non trova nulla usa la secret impostata nelle options
* @param {string} name nome del cookie dove recuperare la chiave di codifica
* @return {string} Chiave di codifica
*/
irenHmac.prototype.getSecret = function(name) {
if (!name) name = this.options.cookie;
match = document.cookie.match(new RegExp(name + '=([^;]+)'));
if (match) return match[1];
else
return this.options.secret;
}
// Redirect su pagina di Nessuna Autorizzazione
/**
* Metodo di redirect sulla pagina di Nessuna Autenticazione passata
* @return {void}
*/
irenHmac.prototype.noAuth = function (){
window.location.href = this.options.noAuthPage;
}
// Redirect su pagina di Validazione Fallita
/**
* Metodo di redirect sulla pagina di Autenticazione Fallita
* @return {void}
*/
irenHmac.prototype.noValid = function (){
window.location.href = this.options.noValidPage;
}
//Creazione dell'Hash data password e messaggio
/**
* Metodo di creazione della Hash
* @param {string} message messaggio da criptare
* @param {string} secret Chiave di codifica
* @return {string} Hash
*/
irenHmac.prototype.createHash = function(message,secret){
// Step 1 Crypt Password
var crypt = new jsSHA("SHA-256", "TEXT");
crypt.update(secret);
var mysecret = crypt.getHash("HEX");
//Step 2 Calculate HMac
var shaObj = new jsSHA("SHA-256", "TEXT");
shaObj.setHMACKey(mysecret, "TEXT");
shaObj.update(message);
return shaObj.getHMAC("B64");
}
//Metodo di verica dell'HMac dai dati di QueryString in Javascript Con Chiamata Ajax Funziona SU HTML
/**
* Verifica tramite chiamata AJAX
* @return {void} Reindirizzamento su pagina di autenticazione fallita
*/
irenHmac.prototype.verifyAjaxHmac = function(){
var self = this;
var d = {action: 'verify',path: this.options.path, params : this.options.reqParams};
$.ajax({
async : false,
url : this.options.serviceUrl,
method : this.options.method,
data : d,
dataType : 'json',
error : function( jqXHR, textStatus, errorThrown ){
this.noauth();
},
success: function(data, textStatus, jqXHR){
if (data.success != 1) {
self.options.verified = 0;
self.noValid();
}
else{
self.options.verified = 1;
}
}
});
};
/**
* Verifica della hash in Pure Javascript
* @return {void} Reindirizzamento alla pagina di autenticazione fallita
*/
//Metodo di verica dell'HMac dai dati di QueryString in Javascript Funziona SU HTML
irenHmac.prototype.verifyJSHmac = function(){
var string = this.createQueryString();
var hmac = this.options.reqParams[this.options.authPrm];
var secret = this.getSecret();
var hash = this.createHash(string,secret);
if (hmac==hash){
this.options.verified = 1;
}
else{
this.options.verified = 0;
this.noValid();
}
}
}());
function extendDefaults(source, properties) {
var property;
for (property in properties) {
if (properties.hasOwnProperty(property)) {
source[property] = properties[property];
}
}
return source;
}
function getSortedObject(object) {
var sortedObject = {};
var keys = Object.keys(object);
keys.sort();
for (var i = 0, size = keys.length; i < size; i++) {
key = keys[i];
value = object[key];
sortedObject[key] = value;
}
return sortedObject;
}