diff --git a/config.xml b/config.xml index 8a28ed7..70ad06e 100644 --- a/config.xml +++ b/config.xml @@ -3,7 +3,7 @@ Passy The mobile App for the Passy Password Manager Passy Team - + @@ -81,6 +81,7 @@ + diff --git a/package.json b/package.json index 509f33c..7d679b7 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@ionic-native/touch-id": "^4.2.1", "@ionic/storage": "^2.0.1", "cordova-android": "^6.2.3", + "cordova-clipboard": "^1.0.0", "cordova-ios": "^4.4.0", "cordova-plugin-compat": "^1.1.0", "cordova-plugin-console": "^1.0.7", @@ -63,7 +64,8 @@ "cordova-plugin-whitelist": {}, "ionic-plugin-keyboard": {}, "cordova-plugin-touch-id": {}, - "cordova-sqlite-storage": {} + "cordova-sqlite-storage": {}, + "cordova-clipboard": {} }, "platforms": [ "android", diff --git a/src/app/Passy.ts b/src/app/Passy.ts index a83277d..3159d3f 100644 --- a/src/app/Passy.ts +++ b/src/app/Passy.ts @@ -1,5 +1,6 @@ import {Http, Headers, RequestOptions} from "@angular/http"; import {loginScreen, popAlert} from "../pages/tabs/tabs"; +import {AlertController} from "ionic-angular"; export var passwords = []; export var archived = []; @@ -119,7 +120,7 @@ export class Passy { } - public tryLogin(name: string, pass: string, http: Http, callBack, loader) { + public tryLogin(name: string, pass: string, http: Http, callBack, loader, alertController:AlertController) { if (this.loggedIn) return; @@ -134,6 +135,7 @@ export class Passy { const data = JSON.parse(response.text()); if (data.success) { + me.accessToken = data.token[0]; me.fetchPasswords(http); @@ -159,6 +161,72 @@ export class Passy { }, 2000); } else { + if(data.msg == "two_factor_needed") { + + let twoFaPrompt = alertController.create({ + title: 'Login', + inputs: [ + { + name: 'code', + placeholder: 'Two Factor Code' + } + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + handler: data => { + callBack(false); + return; + } + }, + { + text: 'Login', + handler: data => { + + me.request(http, [{name: "a", value: "user/login"}, + {name: "username", value: name}, {name: "password", value: pass}, {name: "2faCode", value: data.code}], (response) => { + + const data = JSON.parse(response.text()); + + me.accessToken = data.token[0]; + + me.fetchPasswords(http); + loggedIn = true; + callBack(true); + + me.timer = setInterval(function () { + me.request(http, [{name: "access_token", value: me.accessToken}, { + name: "a", + value: "status" + }], function (response) { + + const json = JSON.parse(response.text()); + if (!json.data.logged_in) { + passwords = []; + archived = []; + me.accessToken = ""; + loginScreen(); + clearInterval(me.timer); + } + + }) + + }, 2000); + + + }); + + return; + } + } + ] + }); + twoFaPrompt.present(); + + + return; + } loader.dismissAll(); popAlert("Failed", "Failed to login"); } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 122ee1a..7920079 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -15,6 +15,7 @@ import {EditPassPage} from "../pages/edit-password/edit-pass"; import {ArchivePage} from "../pages/archived/archive"; import {TouchID} from "@ionic-native/touch-id"; import {IonicStorageModule} from "@ionic/storage"; +import {Clipboard} from "@ionic-native/clipboard"; @NgModule({ @@ -52,7 +53,8 @@ import {IonicStorageModule} from "@ionic/storage"; StatusBar, SplashScreen, {provide: ErrorHandler, useClass: IonicErrorHandler}, - TouchID + TouchID, + Clipboard ] diff --git a/src/pages/home/home.html b/src/pages/home/home.html index 14a0431..9fd1cff 100644 --- a/src/pages/home/home.html +++ b/src/pages/home/home.html @@ -1,47 +1,49 @@ - - Passwords - - - - - + + Passwords + + + + + + + + - - -
- - - - {{current.username || "None"}} - - - -

{{current.description || "None"}}

-
- - - - - -
- -
-
- + + +
+ + + + {{current.username || "None"}} + + + +

{{current.description || "None"}}

+
+ + + + + +
+ +
+
diff --git a/src/pages/login/LoginPage.ts b/src/pages/login/LoginPage.ts index 98c84ac..f3858f8 100644 --- a/src/pages/login/LoginPage.ts +++ b/src/pages/login/LoginPage.ts @@ -19,6 +19,11 @@ export class LoginPage { constructor(public viewCtrl: ViewController, public http: Http, private touchId: TouchID, public storage: Storage, public alertCtrl: AlertController, public loadingCtrl: LoadingController) { + + const me = this; + storage.get("save_url").then(val => { + if(val != null && val.length > 5) me.target = val; + }) } @@ -34,51 +39,58 @@ export class LoginPage { passy.tryLogin(this.username, this.password, this.http, function (succeeded) { loader.dismissAll(); if (succeeded) { - if (isCordovaAvailable()) { - me.storage.keys().then(keys => { - - - if (keys.indexOf("touch_dismiss") == -1) { - let confirm = me.alertCtrl.create({ - title: 'Enable Touch ID Login?', - message: 'Do you want to be able to login with touch id?', - buttons: [{ - text: 'Disagree', - handler: () => { - me.storage.set("touch_dismiss", true).then(_ => { - me.dismiss() - - }); - - } - }, - { - text: 'Agree', - handler: () => { - me.storage.set("touch_save", true).then(_ => { - me.storage.set("touch_user", me.username).then(_ => { - me.storage.set("touch_pass", me.password).then(_ => { - me.dismiss(); - }); - }); - }); - } - }] - }); - confirm.present(); - } else { - me.dismiss() - - } - - }); - - } else { - me.dismiss(); - } + me.storage.set("save_url", me.target).then(_ => { + if (isCordovaAvailable()) { + me.storage.keys().then(keys => { + + + if (keys.indexOf("touch_dismiss") == -1) { + + me.touchId.isAvailable().then(_ => { + let confirm = me.alertCtrl.create({ + title: 'Enable Touch ID Login?', + message: 'Do you want to be able to login with touch id?', + buttons: [{ + text: 'Disagree', + handler: () => { + me.storage.set("touch_dismiss", true).then(_ => { + me.dismiss() + + }); + + } + }, + { + text: 'Agree', + handler: () => { + me.storage.set("touch_save", true).then(_ => { + me.storage.set("touch_user", me.username).then(_ => { + me.storage.set("touch_pass", me.password).then(_ => { + me.dismiss(); + }); + }); + }); + } + }] + }); + confirm.present(); + }).catch(_ => { + me.dismiss(); + }); + } else { + me.dismiss(); + + } + + }); + + } else { + me.dismiss(); + } + }) } - }, loader); + }, loader, this.alertCtrl); } ionViewDidLoad() { @@ -107,7 +119,7 @@ export class LoginPage { loader.dismissAll(); it.dismiss() } - }); + }, loader, this.alertCtrl); }) }) }, diff --git a/src/pages/new-password/new-pass.html b/src/pages/new-password/new-pass.html index 27e7d74..5db66c0 100644 --- a/src/pages/new-password/new-pass.html +++ b/src/pages/new-password/new-pass.html @@ -1,24 +1,26 @@ - + - - Username - - + + Username + + - - Password - - - + + Password + + + + + - - Description - - - -
- - -
+ + Description + + +
+
+ + +
diff --git a/src/pages/pass-show/pass-show.html b/src/pages/pass-show/pass-show.html index 851c9fd..4043cc2 100644 --- a/src/pages/pass-show/pass-show.html +++ b/src/pages/pass-show/pass-show.html @@ -1,11 +1,20 @@ - - - - Password - - - - + + + + + Password + + + + + + + + + + + +   diff --git a/src/pages/pass-show/pass-show.ts b/src/pages/pass-show/pass-show.ts index bd13492..d943347 100644 --- a/src/pages/pass-show/pass-show.ts +++ b/src/pages/pass-show/pass-show.ts @@ -1,5 +1,8 @@ import {Component} from "@angular/core"; -import {NavParams} from "ionic-angular"; +import {NavParams, ToastController} from "ionic-angular"; +import { Clipboard } from '@ionic-native/clipboard'; +import {popAlert} from "../tabs/tabs"; + @Component({ selector: 'pass-show', templateUrl: 'pass-show.html' @@ -11,12 +14,21 @@ export class PassShow { private passwordInfo; - constructor(private navParams: NavParams) { + constructor(private navParams: NavParams, private clipboard: Clipboard, private toast:ToastController) { this.password = navParams.data.password; this.passwordInfo = navParams.data.passInf; } + copy() { + this.clipboard.copy(this.password); + let toast = this.toast.create({ + message: "Copied", + duration: 2500, + position: 'bottom' + }); + toast.present(); + } } diff --git a/src/pages/tabs/tabs.ts b/src/pages/tabs/tabs.ts index 8d79ec6..2ad788e 100644 --- a/src/pages/tabs/tabs.ts +++ b/src/pages/tabs/tabs.ts @@ -24,6 +24,8 @@ export class TabsPage { this.platform.registerBackButtonAction(() => {}); + + }