diff --git a/dist/index.d.ts b/dist/index.d.ts index 40ca65a..761b03f 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -6,6 +6,7 @@ export declare class Webstorable { } export declare let WEBSTORAGE_CONFIG: { prefix: string; + secretKey: string; }; export declare class WebStorageModule { } diff --git a/dist/index.js b/dist/index.js index 395f690..e9f7198 100644 --- a/dist/index.js +++ b/dist/index.js @@ -19,7 +19,8 @@ exports.SessionStorageService = webstorage_service_2.SessionStorageService; var webstorage_utility_1 = require("./utility/webstorage.utility"); exports.WebStorageUtility = webstorage_utility_1.WebStorageUtility; exports.WEBSTORAGE_CONFIG = { - prefix: 'angular2ws_' + prefix: 'angular2ws_', + secretKey: '' }; var WebStorageModule = (function () { function WebStorageModule() { diff --git a/dist/index.js.map b/dist/index.js.map index 6ff8458..2f7e9d6 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAAA,sCAAuC;AACvC,mEAAwF;AAExF,qDAAiF;AAAxE,kCAAA,UAAU,CAAA;AAAE,oCAAA,YAAY,CAAA;AAAE,sCAAA,cAAc,CAAA;AACjD,mEAA6G;AAApG,iDAAA,iBAAiB,CAAA;AAAE,mDAAA,mBAAmB,CAAA;AAAE,qDAAA,qBAAqB,CAAA;AACtE,mEAAiE;AAAxD,iDAAA,iBAAiB,CAAA;AAIf,QAAA,iBAAiB,GAAG;IAC3B,MAAM,EAAE,aAAa;CACxB,CAAC;AAKF,IAAa,gBAAgB;IAA7B;IAA+B,CAAC;IAAD,uBAAC;AAAD,CAAC,AAAhC,IAAgC;AAAnB,gBAAgB;IAH5B,eAAQ,CAAC;QACN,SAAS,EAAE,CAAC,wCAAmB,EAAE,0CAAqB,CAAC;KAC1D,CAAC;GACW,gBAAgB,CAAG;AAAnB,4CAAgB","sourcesContent":["import {NgModule} from '@angular/core';\nimport {LocalStorageService, SessionStorageService} from './service/webstorage.service';\n\nexport { WebStorage, LocalStorage, SessionStorage } from './decorator/webstorage'\nexport { WebStorageService, LocalStorageService, SessionStorageService } from './service/webstorage.service';\nexport { WebStorageUtility } from './utility/webstorage.utility';\nexport declare class Webstorable {\n save(): void;\n}\nexport let WEBSTORAGE_CONFIG = {\n prefix: 'angular2ws_'\n};\n\n@NgModule({\n providers: [LocalStorageService, SessionStorageService]\n})\nexport class WebStorageModule {}\n"]} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAAA,sCAAuC;AACvC,mEAAwF;AAExF,qDAAiF;AAAxE,kCAAA,UAAU,CAAA;AAAE,oCAAA,YAAY,CAAA;AAAE,sCAAA,cAAc,CAAA;AACjD,mEAA6G;AAApG,iDAAA,iBAAiB,CAAA;AAAE,mDAAA,mBAAmB,CAAA;AAAE,qDAAA,qBAAqB,CAAA;AACtE,mEAAiE;AAAxD,iDAAA,iBAAiB,CAAA;AAIf,QAAA,iBAAiB,GAAG;IAC3B,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,EAAE;CAChB,CAAC;AAKF,IAAa,gBAAgB;IAA7B;IAA+B,CAAC;IAAD,uBAAC;AAAD,CAAC,AAAhC,IAAgC;AAAnB,gBAAgB;IAH5B,eAAQ,CAAC;QACN,SAAS,EAAE,CAAC,wCAAmB,EAAE,0CAAqB,CAAC;KAC1D,CAAC;GACW,gBAAgB,CAAG;AAAnB,4CAAgB","sourcesContent":["import {NgModule} from '@angular/core';\nimport {LocalStorageService, SessionStorageService} from './service/webstorage.service';\n\nexport { WebStorage, LocalStorage, SessionStorage } from './decorator/webstorage'\nexport { WebStorageService, LocalStorageService, SessionStorageService } from './service/webstorage.service';\nexport { WebStorageUtility } from './utility/webstorage.utility';\nexport declare class Webstorable {\n save(): void;\n}\nexport let WEBSTORAGE_CONFIG = {\n prefix: 'angular2ws_',\n secretKey: ''\n};\n\n@NgModule({\n providers: [LocalStorageService, SessionStorageService]\n})\nexport class WebStorageModule {}\n"]} \ No newline at end of file diff --git a/dist/utility/webstorage.utility.d.ts b/dist/utility/webstorage.utility.d.ts index f674402..e5889af 100644 --- a/dist/utility/webstorage.utility.d.ts +++ b/dist/utility/webstorage.utility.d.ts @@ -5,4 +5,6 @@ export declare class WebStorageUtility { static remove(storage: Storage, key: string): void; private static getSettable(value); private static getGettable(value); + private static encrypt(value, password); + private static decrypt(value, password); } diff --git a/dist/utility/webstorage.utility.js b/dist/utility/webstorage.utility.js index 0977483..ce778b5 100644 --- a/dist/utility/webstorage.utility.js +++ b/dist/utility/webstorage.utility.js @@ -1,20 +1,31 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var index_1 = require("../index"); +var CryptoJS = require("crypto-js"); var WebStorageUtility = (function () { function WebStorageUtility() { } WebStorageUtility.generateStorageKey = function (key) { + if (index_1.WEBSTORAGE_CONFIG.secretKey) { + return index_1.WEBSTORAGE_CONFIG.prefix + "enc_" + key; + } return "" + index_1.WEBSTORAGE_CONFIG.prefix + key; }; WebStorageUtility.get = function (storage, key) { var storageKey = WebStorageUtility.generateStorageKey(key); var value = storage.getItem(storageKey); + if (index_1.WEBSTORAGE_CONFIG.secretKey && value !== null) { + value = this.decrypt(value, index_1.WEBSTORAGE_CONFIG.secretKey) || ''; + } return WebStorageUtility.getGettable(value); }; WebStorageUtility.set = function (storage, key, value) { var storageKey = WebStorageUtility.generateStorageKey(key); - storage.setItem(storageKey, WebStorageUtility.getSettable(value)); + var strValue = WebStorageUtility.getSettable(value); + if (index_1.WEBSTORAGE_CONFIG.secretKey) { + strValue = this.encrypt(strValue, index_1.WEBSTORAGE_CONFIG.secretKey); + } + storage.setItem(storageKey, strValue); }; WebStorageUtility.remove = function (storage, key) { var storageKey = WebStorageUtility.generateStorageKey(key); @@ -33,6 +44,24 @@ var WebStorageUtility = (function () { return value; } }; + WebStorageUtility.encrypt = function (value, password) { + // Prepend sha256(value) to the value, we can use it to verify the decrypted result. + var newValue = CryptoJS.SHA256(value).toString() + value; + return CryptoJS.AES.encrypt(newValue, password).toString(); + }; + // Returns null if the password was incorrect. + WebStorageUtility.decrypt = function (value, password) { + var decrypted = CryptoJS.AES.decrypt(value, password).toString(CryptoJS.enc.Utf8); + if (decrypted.length < 64) { + return null; + } + var sha256 = decrypted.substr(0, 64); + var realValue = decrypted.substr(64); + if (CryptoJS.SHA256(realValue).toString() !== sha256) { + return null; + } + return realValue; + }; return WebStorageUtility; }()); exports.WebStorageUtility = WebStorageUtility; diff --git a/dist/utility/webstorage.utility.js.map b/dist/utility/webstorage.utility.js.map index a9408ec..3ca0083 100644 --- a/dist/utility/webstorage.utility.js.map +++ b/dist/utility/webstorage.utility.js.map @@ -1 +1 @@ -{"version":3,"file":"webstorage.utility.js","sourceRoot":"","sources":["../../src/utility/webstorage.utility.ts"],"names":[],"mappings":";;AAAA,kCAA2C;AAE3C;IAAA;IAqCA,CAAC;IApCU,oCAAkB,GAAzB,UAA0B,GAAW;QACjC,MAAM,CAAC,KAAG,yBAAiB,CAAC,MAAM,GAAG,GAAK,CAAA;IAC9C,CAAC;IAEM,qBAAG,GAAV,UAAW,OAAgB,EAAE,GAAW;QACpC,IAAI,UAAU,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE3D,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAExC,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAEM,qBAAG,GAAV,UAAW,OAAgB,EAAE,GAAW,EAAE,KAAU;QAChD,IAAI,UAAU,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE3D,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IAEM,wBAAM,GAAb,UAAc,OAAgB,EAAE,GAAW;QACvC,IAAI,UAAU,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE3D,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAEc,6BAAW,GAA1B,UAA2B,KAAU;QACjC,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAEc,6BAAW,GAA1B,UAA2B,KAAa;QACpC,EAAE,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC;YAAC,MAAM,CAAC,SAAS,CAAC;QAC5C,IAAI,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,KAAK,CAAA,CAAC,CAAC,CAAC,CAAC,CAAC;YACR,MAAM,CAAC,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IACL,wBAAC;AAAD,CAAC,AArCD,IAqCC;AArCY,8CAAiB","sourcesContent":["import {WEBSTORAGE_CONFIG} from '../index';\r\n\r\nexport class WebStorageUtility {\r\n static generateStorageKey(key: string): string {\r\n return `${WEBSTORAGE_CONFIG.prefix}${key}`\r\n }\r\n\r\n static get(storage: Storage, key: string): any {\r\n let storageKey = WebStorageUtility.generateStorageKey(key);\r\n\r\n let value = storage.getItem(storageKey);\r\n\r\n return WebStorageUtility.getGettable(value);\r\n }\r\n\r\n static set(storage: Storage, key: string, value: any): void {\r\n let storageKey = WebStorageUtility.generateStorageKey(key);\r\n\r\n storage.setItem(storageKey, WebStorageUtility.getSettable(value));\r\n }\r\n\r\n static remove(storage: Storage, key: string): void {\r\n let storageKey = WebStorageUtility.generateStorageKey(key);\r\n\r\n storage.removeItem(storageKey);\r\n }\r\n\r\n private static getSettable(value: any): string {\r\n return typeof value === \"string\" ? value : JSON.stringify(value);\r\n }\r\n\r\n private static getGettable(value: string): any {\r\n if (value === 'undefined') return undefined;\r\n try {\r\n return JSON.parse(value);\r\n } catch(e) {\r\n return value;\r\n }\r\n }\r\n}\r\n"]} \ No newline at end of file +{"version":3,"file":"webstorage.utility.js","sourceRoot":"","sources":["../../src/utility/webstorage.utility.ts"],"names":[],"mappings":"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","sourcesContent":["import {WEBSTORAGE_CONFIG} from '../index';\nimport * as CryptoJS from 'crypto-js';\n\nexport class WebStorageUtility {\n static generateStorageKey(key: string): string {\n if (WEBSTORAGE_CONFIG.secretKey) {\n return `${WEBSTORAGE_CONFIG.prefix}enc_${key}`;\n }\n return `${WEBSTORAGE_CONFIG.prefix}${key}`;\n }\n\n static get(storage: Storage, key: string): any {\n const storageKey = WebStorageUtility.generateStorageKey(key);\n let value = storage.getItem(storageKey);\n if (WEBSTORAGE_CONFIG.secretKey && value !== null) {\n value = this.decrypt(value, WEBSTORAGE_CONFIG.secretKey) || '';\n }\n return WebStorageUtility.getGettable(value);\n }\n\n static set(storage: Storage, key: string, value: any): void {\n const storageKey = WebStorageUtility.generateStorageKey(key);\n let strValue = WebStorageUtility.getSettable(value);\n if (WEBSTORAGE_CONFIG.secretKey) {\n strValue = this.encrypt(strValue, WEBSTORAGE_CONFIG.secretKey);\n }\n storage.setItem(storageKey, strValue);\n }\n\n static remove(storage: Storage, key: string): void {\n let storageKey = WebStorageUtility.generateStorageKey(key);\n\n storage.removeItem(storageKey);\n }\n\n private static getSettable(value: any): string {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n }\n\n private static getGettable(value: string): any {\n if (value === 'undefined') return undefined;\n try {\n return JSON.parse(value);\n } catch(e) {\n return value;\n }\n }\n\n private static encrypt(value: string, password: string): string {\n // Prepend sha256(value) to the value, we can use it to verify the decrypted result.\n const newValue = CryptoJS.SHA256(value).toString() + value;\n return CryptoJS.AES.encrypt(newValue, password).toString();\n }\n\n // Returns null if the password was incorrect.\n private static decrypt(value: string, password: string): string {\n const decrypted = CryptoJS.AES.decrypt(value, password).toString(CryptoJS.enc.Utf8);\n if (decrypted.length < 64) {\n return null;\n }\n const sha256 = decrypted.substr(0, 64);\n const realValue = decrypted.substr(64);\n if (CryptoJS.SHA256(realValue).toString() !== sha256) {\n return null;\n }\n return realValue;\n }\n}\n"]} \ No newline at end of file diff --git a/package.json b/package.json index 6fb85a7..8f3fece 100644 --- a/package.json +++ b/package.json @@ -37,5 +37,9 @@ "tslint": "^3.15.1", "typescript": "^2.2.1", "zone.js": "^0.7.2" + }, + "dependencies": { + "@types/crypto-js": "^3.1.33", + "crypto-js": "^3.1.9-1" } } diff --git a/src/index.ts b/src/index.ts index 61d101f..7ea5dcb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,8 @@ export declare class Webstorable { save(): void; } export let WEBSTORAGE_CONFIG = { - prefix: 'angular2ws_' + prefix: 'angular2ws_', + secretKey: '' }; @NgModule({ diff --git a/src/utility/webstorage.utility.ts b/src/utility/webstorage.utility.ts index 2a2656a..a03db6d 100644 --- a/src/utility/webstorage.utility.ts +++ b/src/utility/webstorage.utility.ts @@ -1,22 +1,30 @@ import {WEBSTORAGE_CONFIG} from '../index'; +import * as CryptoJS from 'crypto-js'; export class WebStorageUtility { static generateStorageKey(key: string): string { - return `${WEBSTORAGE_CONFIG.prefix}${key}` + if (WEBSTORAGE_CONFIG.secretKey) { + return `${WEBSTORAGE_CONFIG.prefix}enc_${key}`; + } + return `${WEBSTORAGE_CONFIG.prefix}${key}`; } static get(storage: Storage, key: string): any { - let storageKey = WebStorageUtility.generateStorageKey(key); - + const storageKey = WebStorageUtility.generateStorageKey(key); let value = storage.getItem(storageKey); - + if (WEBSTORAGE_CONFIG.secretKey && value !== null) { + value = this.decrypt(value, WEBSTORAGE_CONFIG.secretKey) || ''; + } return WebStorageUtility.getGettable(value); } static set(storage: Storage, key: string, value: any): void { - let storageKey = WebStorageUtility.generateStorageKey(key); - - storage.setItem(storageKey, WebStorageUtility.getSettable(value)); + const storageKey = WebStorageUtility.generateStorageKey(key); + let strValue = WebStorageUtility.getSettable(value); + if (WEBSTORAGE_CONFIG.secretKey) { + strValue = this.encrypt(strValue, WEBSTORAGE_CONFIG.secretKey); + } + storage.setItem(storageKey, strValue); } static remove(storage: Storage, key: string): void { @@ -37,4 +45,24 @@ export class WebStorageUtility { return value; } } + + private static encrypt(value: string, password: string): string { + // Prepend sha256(value) to the value, we can use it to verify the decrypted result. + const newValue = CryptoJS.SHA256(value).toString() + value; + return CryptoJS.AES.encrypt(newValue, password).toString(); + } + + // Returns null if the password was incorrect. + private static decrypt(value: string, password: string): string { + const decrypted = CryptoJS.AES.decrypt(value, password).toString(CryptoJS.enc.Utf8); + if (decrypted.length < 64) { + return null; + } + const sha256 = decrypted.substr(0, 64); + const realValue = decrypted.substr(64); + if (CryptoJS.SHA256(realValue).toString() !== sha256) { + return null; + } + return realValue; + } }