diff --git app/ionic.config.json app/ionic.config.json index d2e1d8f..1b487ce 100644 --- app/ionic.config.json +++ app/ionic.config.json @@ -1,7 +1,9 @@ { "name": "Hybric OSN", - "integrations": { - "cordova": {} + "integrations": + { + "cordova": + {} }, - "type": "ionic-angular" -} \ No newline at end of file + "type": "angular" +} diff --git app/package-lock.json app/package-lock.json index e686dba..d53d9e7 100644 --- app/package-lock.json +++ app/package-lock.json @@ -1,6 +1,6 @@ { - "name": "HybridOSN", - "version": "0.5.1", + "name": "hybrid-osn", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -829,8 +829,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "body": { "version": "5.1.0", @@ -2469,7 +2468,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2487,11 +2487,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2504,15 +2506,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -2615,7 +2620,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -2625,6 +2631,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2637,17 +2644,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2664,6 +2674,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2736,7 +2747,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2746,6 +2758,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2821,7 +2834,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2851,6 +2865,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2868,6 +2883,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2906,11 +2922,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -3649,6 +3667,11 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, "in-publish": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", @@ -4367,8 +4390,7 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", @@ -4566,6 +4588,14 @@ "vm-browserify": "0.0.4" } }, + "node-localstorage": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.1.tgz", + "integrity": "sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==", + "requires": { + "write-file-atomic": "^1.1.4" + } + }, "node-rsa": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.0.2.tgz", @@ -4838,6 +4868,33 @@ "wrappy": "1" } }, + "openpgp": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/openpgp/-/openpgp-4.7.1.tgz", + "integrity": "sha512-UX4AXpjxUiIHfReStsBvbAcL5XyIWSb3sh7uleGlKdg1VWK/4LOncNd+89fYur6fbjZXORVR6m6YELupeWT1Iw==", + "requires": { + "asn1.js": "^5.0.0", + "node-fetch": "^2.1.2", + "node-localstorage": "~1.3.0" + }, + "dependencies": { + "asn1.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz", + "integrity": "sha512-Q7hnYGGNYbcmGrCPulXfkEw7oW7qjWeM4ZTALmgpuIcZLxyqqKYWxCZg2UBm8bklrnB4m2mGyJPWfoktdORD8A==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + } + } + }, "optjs": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", @@ -5009,9 +5066,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "requires": { "isarray": "0.0.1" }, @@ -5774,6 +5831,11 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7405,6 +7467,16 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, "ws": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.2.tgz", diff --git app/src/app/app.component.ts app/src/app/app.component.ts index d35471a..761f19e 100644 --- app/src/app/app.component.ts +++ app/src/app/app.component.ts @@ -21,7 +21,7 @@ export class MyApp { nav: Nav; rootPage: any; - pages: Array<{ title: string; icon: string; component: any }>; + pages: Array < { title: string;icon: string;component: any } > ; user: any; constructor( @@ -53,17 +53,20 @@ export class MyApp { async initApp() { const isLoggedIn = await this.authProvider.isLoggedIn(); - + console.log('isLoggedin var is:', isLoggedIn); + this.rootPage = LoginPage; if (isLoggedIn) { this.rootPage = HomePage; await this.setUser(); } else { + console.log('redirecting to login page'); this.rootPage = LoginPage; } } async setUser() { const userId = await this.storage.get("userId"); + console.log('fetching user'); this.user = await this.twitter.fetchUser(userId); } diff --git app/src/components/profile-header/profile-header.ts app/src/components/profile-header/profile-header.ts index e2ce94b..e29ffe0 100644 --- app/src/components/profile-header/profile-header.ts +++ app/src/components/profile-header/profile-header.ts @@ -13,7 +13,24 @@ export class ProfileHeaderComponent { constructor( private twitter: TwitterApiProvider, private photoViewer: PhotoViewer - ) {} + ) { + + // if (typeof Worker !== 'undefined') { + // // Create a new + // const worker = new Worker('./profile-header.worker'); + // let message = "fuckgi"; + // worker.onmessage = (ev: MessageEvent) => { + // worker.terminate(); + // }; + // worker.postMessage(message); + // } else { + // console.log('webworkers are not supported'); + // return; + // // Web Workers are not supported in this environment. + // // You should add a fallback so that your program still executes correctly. + // } + + } get banner() { if (this.user.profile_banner_url) { diff --git app/src/index.html app/src/index.html index c4b4376..64fb4d5 100644 --- app/src/index.html +++ app/src/index.html @@ -1,51 +1,44 @@ + Ionic App - - - - - - + + - - + - - - - + diff --git app/src/pages/login/login.html app/src/pages/login/login.html index fb8f719..6da6d64 100644 --- app/src/pages/login/login.html +++ app/src/pages/login/login.html @@ -10,4 +10,4 @@ Learn more - \ No newline at end of file + diff --git app/src/pages/login/login.ts app/src/pages/login/login.ts index 691edbc..fac836e 100644 --- app/src/pages/login/login.ts +++ app/src/pages/login/login.ts @@ -35,8 +35,7 @@ export class LoginPage { login() { const alertText = { title: "Login failed", - subTitle: - "Somthing went wrong while trying to log you in. Please try again.", + subTitle: "Somthing went wrong while trying to log you in. Please try again.", buttons: ["OK"] }; diff --git app/src/pages/settings/settings.html app/src/pages/settings/settings.html index 9e1eba0..8143601 100644 --- app/src/pages/settings/settings.html +++ app/src/pages/settings/settings.html @@ -24,6 +24,8 @@ generate a pair of keys. If you run the app on multiple devices, please enter everywhere the same pair of keys.

+ Enter Passphrase: + Private Key: Public Key: @@ -35,4 +37,4 @@ - \ No newline at end of file + diff --git app/src/pages/settings/settings.ts app/src/pages/settings/settings.ts index c2f6bfd..1d966e9 100644 --- app/src/pages/settings/settings.ts +++ app/src/pages/settings/settings.ts @@ -17,6 +17,7 @@ export class SettingsPage { keywords: string; privateKey: string; publicKey: string; + passphrase: string; constructor( public navCtrl: NavController, @@ -33,6 +34,7 @@ export class SettingsPage { async loadValuesFromStorage() { this.privateKey = await this.storage.get("privateKey"); this.publicKey = await this.storage.get("publicKey"); + this.passphrase = await this.storage.get("passphrase"); this.keywords = await this.storage.get("keywords"); } @@ -63,7 +65,8 @@ export class SettingsPage { } private async startKeyGeneration() { - const keys = await this.cryptoUtils.generateRsaKeys(); + // const keys = await this.cryptoUtils.generateRsaKeys(); + const keys = await this.cryptoUtils.generateKeys(this.passphrase); this.publicKey = await this.cryptoUtils.extractPublicKey(keys); this.privateKey = await this.cryptoUtils.extractPrivateKey(keys); @@ -73,6 +76,7 @@ export class SettingsPage { this.storage.set("publicKey", this.publicKey); this.storage.set("privateKey", this.privateKey); this.storage.set("keywords", this.keywords ? this.keywords.trim() : ""); + this.storage.set("passphrase", this.passphrase); this.showToast("Successfully saved!"); } diff --git app/src/pages/write-tweet/write-tweet.ts app/src/pages/write-tweet/write-tweet.ts index f468d43..4b9c8f7 100644 --- app/src/pages/write-tweet/write-tweet.ts +++ app/src/pages/write-tweet/write-tweet.ts @@ -35,9 +35,10 @@ export class WriteTweetPage { openpgp; privateKey; publicKey; - pk: any[]=[]; - passp = 'super long and hard to guess secret' ; - + revocationCertificate; + pk: any[] = []; + passp = 'super long and hard to guess secret'; + constructor( public navCtrl: NavController, @@ -64,100 +65,108 @@ export class WriteTweetPage { } - public async encryptDecryptFunction () { - await openpgp.initWorker({path:'assets/scripts/openpgp.worker.js'}); - let a = await this.generateKeys(); - console.log('a is:',a.publicKeyArmored); - let b = await this.generateKeys(); - console.log('b is:',b.publicKeyArmored); - let c = await this.generateKeys(); - this.privateKey =c.privateKeyArmored; + public async encryptDecryptFunction() { + await openpgp.initWorker({ path: 'assets/scripts/openpgp.worker.js' }); + let a = await this.generateKeys(); + console.log('a is:', a.publicKeyArmored); + let b = await this.generateKeys(); + console.log('b is:', b.publicKeyArmored); + let c = await this.generateKeys(); + this.privateKey = c.privateKeyArmored; this.publicKey = c.publicKeyArmored; - + await this.uploadPubKeytoServer(this.publicKey); + this.revocationCertificate = c.revocationCertificate; this.pk.push(a.publicKeyArmored); this.pk.push(b.publicKeyArmored); -// this.pk = [`----BEGIN PGP PUBLIC KEY BLOCK----- -// Version: OpenPGP.js v4.7.1 -// Comment: https://openpgpjs.org - -// xjMEXfAn1xYJKwYBBAHaRw8BAQdAAMVNOABw8MBtrtYR8KC3tSro3wITyApT -// TVjKVCppD+DNG0pvbiBTbWl0aCA8am9uQGV4YW1wbGUuY29tPsJ3BBAWCgAf -// BQJd8CfXBgsJBwgDAgQVCAoCAxYCAQIZAQIbAwIeAQAKCRD+efBRXzuMsfA7 -// AQCEgoToFzv2hT9BREdiQp531/AHSyoZWmWvSZSvmga40gD8C+zwbCySnkhQ -// pb4L0DCKtSDa7pLg2g0OcxJlbSZWHQ3OOARd8CfXEgorBgEEAZdVAQUBAQdA -// p4mVY17dPWf6VCBqW10Ybk5JgUO6FK0OsETWw3gG2zcDAQgHwmEEGBYIAAkF -// Al3wJ9cCGwwACgkQ/nnwUV87jLFHbAD9GyoL7dcTDGQoqtrhKozdgnzfugTb -// er0bwU15WNMjefkA/jEqK9YUNcRrFKIuac9PVibGgutL8ak7ukysw6iTcCsM -// =fmhE -// -----END PGP PUBLIC KEY BLOCK-----`, -// `-----BEGIN PGP PUBLIC KEY BLOCK----- -// Version: OpenPGP.js v4.7.1 -// Comment: https://openpgpjs.org - -// xjMEXfAn1hYJKwYBBAHaRw8BAQdAsF1ivpd0HU8ogj02LDv6BTOxNMWGZaEc -// OyZBwqoYJPrNG0pvbiBTbWl0aCA8am9uQGV4YW1wbGUuY29tPsJ3BBAWCgAf -// BQJd8CfWBgsJBwgDAgQVCAoCAxYCAQIZAQIbAwIeAQAKCRDEruv77flRJ32B -// AP93GIBcUW2okROoZZhdPVeqjRD72Ft64imXpdZ0jx4ohgEA5Kv9vs2kV73q -// k6fcdf7qD/i5gMExU0+vV05c9VxBYwfOOARd8CfWEgorBgEEAZdVAQUBAQdA -// 1J7E03ZopUnsIeNzeiZvba6qxhhUbpmBZ1aN1HhWUlEDAQgHwmEEGBYIAAkF -// Al3wJ9YCGwwACgkQxK7r++35USdTqQD/ZEg8X5tMx75nQe4mGlyiRjmmtWLw -// n9bslTdjBIszs/EA/R1WIm6ji4Ru1dJWc3ISisz78xTM2H8U7fnP8yjFcWcD -// =hgnW -// -----END PGP PUBLIC KEY BLOCK-----`]; - console.log('array of pub keys is :',this.pk); - this.pk = this.pk.map(async (key) => { + console.log('array of pub keys is :', this.pk); + this.pk = this.pk.map(async (key) => { return (await openpgp.key.readArmored(key)).keys[0] }); - console.log('priv key: ',this.privateKey,'this.pubkey',this.pk); + console.log('priv key: ', this.privateKey, 'this.pubkey', this.pk); let encrypted; const privKeyObj = (await openpgp.key.readArmored(this.privateKey)).keys[0]; - console.log('privKeyObj',privKeyObj); - const bla = await privKeyObj.decrypt(this.passp); - - // const options = { - // message: openpgp.message.fromText('Hello, World!'), // input as Message object - // publicKeys: (await openpgp.key.readArmored(this.publicKey)).keys, // for encryption - // privateKeys: [privKeyObj] // for signing (optional) - // } - + console.log('privKeyObj', privKeyObj); const options = { - message: openpgp.message.fromText('Hello, World!'), // input as Message object - publicKeys: await Promise.all(this.pk), // for encryption - privateKeys: [privKeyObj] // for signing (optional) + message: openpgp.message.fromText('Hello, World!'), // input as Message object + publicKeys: await Promise.all(this.pk), // for encryption + privateKeys: [privKeyObj] // for signing (optional) } const ciphertext = await openpgp.encrypt(options); - encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----' - console.log('encrypted is:',encrypted); - - let aprivKeyObj = (await openpgp.key.readArmored(a.privateKeyArmored)).keys[0]; - await aprivKeyObj.decrypt(this.passp); + encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----' + console.log('encrypted is:', encrypted); + + let aprivKeyObj = (await openpgp.key.readArmored(a.privateKeyArmored)).keys[0]; + await aprivKeyObj.decrypt(this.passp); const options2 = { - message: await openpgp.message.readArmored(encrypted), // parse armored message - privateKeys: [aprivKeyObj] // for decryption + message: await openpgp.message.readArmored(encrypted), // parse armored message + privateKeys: [aprivKeyObj] // for decryption } - console.log('options2 is: ',options2); + console.log('options2 is: ', options2); let plaintext = await openpgp.decrypt(options2); - console.log('decrypted text is:',plaintext,plaintext.data); + console.log('decrypted text is:', plaintext, plaintext.data); + + //lookup key + await this.lookupKeys(); + await this.test(); return plaintext.data // 'Hello, World!' } - public async generateKeys(){ + public async test(){ + console.log("----------------INSIDE TEST-----------------"); + await this.revokeKey(); + await this.lookupKeys(); + } + + public async generateKeys() { let options = { - userIds: [{ name:'Jon Smith', email:'jon@example.com' }], // multiple user IDs - curve: "ed25519", // ECC curve name - passphrase: this.passp // protects the private key + userIds: [{ name: 'Rohit Gowda', email: 'rohit.s.gowda91@gmail.com' }], // multiple user IDs + curve: "ed25519", // ECC curve name + passphrase: this.passp // protects the private key }; - - let a = await openpgp.generateKey(options); - return a; - // console.log('resolved a = ',a); - // this.privateKey =a.privateKeyArmored; - // this.publicKey = a.publicKeyArmored; - // this.encryptDecryptFunction(); + + let a = await openpgp.generateKey(options); + return a; + } + + public async uploadPubKeytoServer(pubkey){ + var hkp = new openpgp.HKP('https://pgp.mit.edu'); + hkp.upload(pubkey).then(function() { + console.log("pubkey succesfully uploaded"); + }); + } + + public async lookupKeys(){ + var hkp = new openpgp.HKP(); // Defaults to https://keyserver.ubuntu.com, or pass another keyserver URL as a string + + var options = { + query: 'rohit.s.gowda91@gmail.com' + }; + + let armoredPubkey = await hkp.lookup(options); + let pubkey = await openpgp.key.readArmored(armoredPubkey); + console.log('Found public key:',pubkey); + } + + public async revokeKey(){ + //using revocation certificate + var options = { + key: openpgp.key.readArmored(this.publicKey).keys[0], + revocationCertificate: this.revocationCertificate + }; + + //alternatively revoke using private key + let options2 = { + key: openpgp.key.readArmored(this.privateKey).keys[0] + }; + + openpgp.revokeKey(options2).then(function(key) { + var pubkey = key.publicKeyArmored; // '-----BEGIN PGP PUBLIC KEY BLOCK ... ' + console.log("public key revoked"); + }); } @@ -171,7 +180,8 @@ export class WriteTweetPage { } private containsTriggerWord(triggerWords: string): ValidatorFn { - return (control: AbstractControl): { [key: string]: any } | null => { + return (control: AbstractControl): { + [key: string]: any } | null => { if (triggerWords) { const regexList = triggerWords .toLowerCase() @@ -179,9 +189,9 @@ export class WriteTweetPage { .join("|"); const regex = new RegExp(regexList); const containsTriggerWord = regex.test(control.value.toLowerCase()); - return containsTriggerWord - ? { containsTriggerWord: { value: control.value } } - : null; + return containsTriggerWord ? + { containsTriggerWord: { value: control.value } } : + null; } else { return null; } @@ -219,8 +229,7 @@ export class WriteTweetPage { this.alertCtrl .create({ title: "Watch Out!", - message: - "Your tweet contains words you have previously defined to only share securely via P2P. Currently P2P mode is not selected.", + message: "Your tweet contains words you have previously defined to only share securely via P2P. Currently P2P mode is not selected.", buttons: ["OK"] }) .present(); @@ -238,12 +247,11 @@ export class WriteTweetPage { ) { loading.setContent("Publish private tweet..."); await this.tweetPrivate(); - } else { + } else { loading.dismiss(); const alert = this.alertCtrl.create({ title: "Oooops...", - message: - "Please verify that you have set a private and public key in the settings and that your latest public key was published." + message: "Please verify that you have set a private and public key in the settings and that your latest public key was published." }); alert.present(); return; @@ -319,7 +327,7 @@ export class WriteTweetPage { } catch (err) { console.error( "There is no user signed up to twitter with username: " + - mention.screenName + mention.screenName ); } return mention; diff --git app/src/providers/crypto/crypto.ts app/src/providers/crypto/crypto.ts index 8714a1d..98a67e8 100644 --- app/src/providers/crypto/crypto.ts +++ app/src/providers/crypto/crypto.ts @@ -2,6 +2,7 @@ import { Injectable } from "@angular/core"; import { TwitterApiProvider } from "../twitter-api/twitter-api"; import { P2pStorageIpfsProvider } from "../p2p-storage-ipfs/p2p-storage-ipfs"; import { Storage } from "@ionic/storage"; +import * as openpgp from 'openpgp'; import NodeRSA from "node-rsa"; declare var TextDecoder: any; declare var TextEncoder: any; @@ -10,6 +11,7 @@ export class CryptoProvider { ownUserId: string; IV_LENGTH = 12; HYBRID_OSN_AES_KEY = "Z1vxAULQnZdoWhJOvv+hWEvVpyUHzNjD/ichEE2c8i4="; + openpgp; constructor( private twitter: TwitterApiProvider, @@ -46,13 +48,19 @@ export class CryptoProvider { }; } - // Ecnrypt key history - const encryptedPublicKeyHistory = await this.aesEncrypt( - JSON.stringify(publicKeyHistory) - ); + //encrypt key history with openpgp with published public key + const options = { + message: openpgp.message.fromText(JSON.stringify(publicKeyHistory)), // input as Message object + publicKeys: (await openpgp.key.readArmored(key)).keys, // for encryption + } + + let encryptedPublicKeyHistory = await openpgp.encrypt(options); + let encrypted = await encryptedPublicKeyHistory.data // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----' + console.log('encrypted public key history', encrypted); + // Publish updated key history... - const res = await this.ipfs.storePublicKey(encryptedPublicKeyHistory); + const res = await this.ipfs.storePublicKey(encrypted); // tweet ipfs link const tweetResponse = await this.twitter.tweet( @@ -85,9 +93,21 @@ export class CryptoProvider { // Fetch public key history if (link.length) { const encryptedKeyHistory = await this.ipfs.fetchJson(link); - // Decrypt key history - const keyHistory = await this.aesDecrypt(encryptedKeyHistory.toString()); - return JSON.parse(keyHistory); + + let privateKey = await this.storage.get("privateKey"); + const privKeyObj = (await openpgp.key.readArmored(privateKey)).keys[0]; + console.log('privKeyObj', privKeyObj); + const options = { + message: await openpgp.message.readArmored(encryptedKeyHistory.toString()), // parse armored message + // publicKeys: (await openpgp.key.readArmored(pubkey)).keys, // for verification (optional) + privateKeys: [privKeyObj] // for decryption + } + + openpgp.decrypt(options).then(plaintext => { + console.log('decrypted key history: ', plaintext.data) + return plaintext.data // 'Hello, World!' + }) + } else { return null; } @@ -123,8 +143,7 @@ export class CryptoProvider { * Generates a RSA key pair object */ public async generateRsaKeys() { - return await crypto.subtle.generateKey( - { + return await crypto.subtle.generateKey({ name: "RSA-OAEP", modulusLength: 1024, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), @@ -135,36 +154,40 @@ export class CryptoProvider { ); } + /** + * Generates an openPGP key pair object + */ + + public async generateKeys(passp: string) { + let options = { + userIds: [{ name: 'Rohit Gowda', email: 'rohit.s.gowda91@gmail.com' }], // multiple user IDs + curve: "ed25519", // ECC curve name + passphrase: passp // protects the private key + }; + + return await openpgp.generateKey(options); + } + /** * extracts the private key from the key object and transforms it to readable text * @param keys key object */ - public async extractPrivateKey(keys): Promise { - return btoa( - String.fromCharCode.apply( - null, - new Uint8Array(await crypto.subtle.exportKey("pkcs8", keys.privateKey)) - ) - ); + public async extractPrivateKey(keys): Promise < string > { + return keys.privateKeyArmored; } /** * extracts the public key from the key object and transforms it to readable text * @param keys key object */ - public async extractPublicKey(keys): Promise { - return btoa( - String.fromCharCode.apply( - null, - new Uint8Array(await crypto.subtle.exportKey("spki", keys.publicKey)) - ) - ); + public async extractPublicKey(keys): Promise < string > { + return keys.publicKeyArmored; } /** * checks if the latest published key is the same as the one saved in app settings */ - public async isPublicKeyPublished(): Promise { + public async isPublicKeyPublished(): Promise < boolean > { const publicKey = await this.storage.get("publicKey"); const keyHistory = await this.getKeyHistory(this.ownUserId); @@ -179,7 +202,7 @@ export class CryptoProvider { /** * checks if a private key is already set */ - public async isPrivateKeySet(): Promise { + public async isPrivateKeySet(): Promise < boolean > { const privateKey = await this.storage.get("privateKey"); return privateKey; } @@ -212,7 +235,7 @@ export class CryptoProvider { * Fetches the public key history for a given user id * @param userId user id */ - public async fetchPublicKeyHistoryForUser(userId: string): Promise { + public async fetchPublicKeyHistoryForUser(userId: string): Promise < object[] > { const keyHistory = await this.getKeyHistory(userId); return keyHistory["keys"].reverse(); } diff --git app/src/providers/feed/feed.ts app/src/providers/feed/feed.ts index e87a22f..d4a3cc8 100644 --- app/src/providers/feed/feed.ts +++ app/src/providers/feed/feed.ts @@ -28,20 +28,23 @@ export class FeedProvider { */ public async loadUserTimeline( userId, - oldestPublicTweet?, - oldestPrivateTweet? + oldestPublicTweet ? , + oldestPrivateTweet ? ) { + console.log('fetch usertimeline'); const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined; // Fetch tweets from Twitter let tweets = await this.twitter.fetchUserTimeline(userId, maxId); + console.log('tweets are:',tweets); if (tweets.length === 0) return tweets; tweets = tweets.filter(tweet => tweet.id_str != maxId); // Determine start and end of time interval to look for private tweets - const intervalStart: Date = oldestPrivateTweet - ? new Date(oldestPrivateTweet["created_at"]) - : new Date(); + const intervalStart: Date = oldestPrivateTweet ? + new Date(oldestPrivateTweet["created_at"]) : + new Date(); const intervalEnd: Date = this.getOldestTweetTimestamp(tweets); + console.log('intervalEnd',intervalEnd); // Fetch private tweet hashs from P2P DB for corresponding interval const privateTweetHashs: object[] = await this.gun.fetchPrivateTweetHashsForUserInInterval( @@ -68,16 +71,16 @@ export class FeedProvider { * @param oldestPublicTweet oldest public tweet * @param oldestPrivateTweet oldest private tweet */ - public async loadHomeTimeline(oldestPublicTweet?, oldestPrivateTweet?) { + public async loadHomeTimeline(oldestPublicTweet ? , oldestPrivateTweet ? ) { // Fetch tweets from Twitter const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined; let tweets = await this.twitter.fetchHomeFeed(maxId); tweets = tweets.filter(tweet => tweet.id_str != maxId); // Determine start and end of time interval to look for private tweets - const intervalStart: Date = oldestPrivateTweet - ? new Date(oldestPrivateTweet["created_at"]) - : new Date(); + const intervalStart: Date = oldestPrivateTweet ? + new Date(oldestPrivateTweet["created_at"]) : + new Date(); const intervalEnd: Date = this.getOldestTweetTimestamp(tweets); // Fetch user's friends @@ -89,7 +92,7 @@ export class FeedProvider { .concat([this.userId]); // Fetch ipfs hashs for period - const promises: Promise[] = friendsAndUserIds.map(accountId => { + const promises: Promise < object[] > [] = friendsAndUserIds.map(accountId => { return this.gun.fetchPrivateTweetHashsForUserInInterval( accountId, intervalStart, @@ -169,12 +172,12 @@ export class FeedProvider { return ""; } - private async addUserToTweet(tweet: object): Promise { + private async addUserToTweet(tweet: object): Promise < object > { tweet["user"] = await this.twitter.fetchUser(tweet["user_id"]); return tweet; } - private async addQuotedStatusToTweet(tweet: object): Promise { + private async addQuotedStatusToTweet(tweet: object): Promise < object > { if (!tweet["quoted_status_id"]) return tweet; const quoted_status = await this.twitter.fetchTweet( tweet["quoted_status_id"] @@ -183,13 +186,13 @@ export class FeedProvider { return tweet; } - private async addOriginalStatusToTweet(tweet: object): Promise { + private async addOriginalStatusToTweet(tweet: object): Promise < object > { if (!tweet["in_reply_to_status_id"]) return tweet; const originalTweet = await this.twitter.fetchTweet( tweet["in_reply_to_status_id"] ); tweet["in_reply_to_screen_name"] = - originalTweet["data"]["user"]["screen_name"]; + originalTweet["data"]["user"]["screen_name"]; return tweet; } diff --git app/src/providers/p2p-database-gun/p2p-database-gun.ts app/src/providers/p2p-database-gun/p2p-database-gun.ts index 213173e..8d80de1 100644 --- app/src/providers/p2p-database-gun/p2p-database-gun.ts +++ app/src/providers/p2p-database-gun/p2p-database-gun.ts @@ -15,7 +15,7 @@ export class P2pDatabaseGunProvider { * Hashtags are stored without reference to the users to provide these information on an extra dashboard to twitter * @param hashtagEntity extracted hashtags */ - public async publishHashtags(hashtagEntity): Promise { + public async publishHashtags(hashtagEntity): Promise < void > { const timestamp = new Date().setHours(0, 0, 1, 0); const hashtagsSeparated = hashtagEntity .map(el => el.hashtag) @@ -29,10 +29,10 @@ export class P2pDatabaseGunProvider { .put({ hashtags: hashtagsSeparated }); this.gun - .get(this.osnPrefix) - .get("hashtags") - .get(timestamp) - .set(hashtags); + .get(this.osnPrefix) + .get("hashtags") + .get(timestamp) + .set(hashtags); } /** @@ -63,7 +63,7 @@ export class P2pDatabaseGunProvider { userId, intervalStart, intervalEnd - ): Promise { + ): Promise < object[] > { const privateTweets = await this.gun .get(this.osnPrefix) .get("tweets") @@ -73,8 +73,8 @@ export class P2pDatabaseGunProvider { if (privateTweets) { const entries = await Promise.all( Object.keys(privateTweets) - .filter(key => key !== "_") - .map(key => this.gun.get(key).then()) + .filter(key => key !== "_") + .map(key => this.gun.get(key).then()) ); return entries diff --git app/tsconfig.json app/tsconfig.json index 5d53142..2ce1629 100644 --- app/tsconfig.json +++ app/tsconfig.json @@ -1,5 +1,6 @@ { - "compilerOptions": { + "compilerOptions": + { "allowSyntheticDefaultImports": true, "declaration": false, "emitDecoratorMetadata": true, @@ -22,7 +23,8 @@ "src/**/__tests__/*.ts" ], "compileOnSave": false, - "atom": { + "atom": + { "rewriteTsconfig": false } } diff --git app/tslint.json app/tslint.json index dd8e8d8..9754821 100644 --- app/tslint.json +++ app/tslint.json @@ -1,5 +1,6 @@ { - "rules": { + "rules": + { "no-duplicate-variable": true, "no-unused-variable": [ true