mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #6858 from gabrielbazan7/feat/lockByPin
Lock by PIN and Fingerprint
This commit is contained in:
commit
0e428744f2
|
@ -1,17 +1,22 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Platform } from 'ionic-angular';
|
||||
import { Platform, ModalController } from 'ionic-angular';
|
||||
import { StatusBar } from '@ionic-native/status-bar';
|
||||
import { SplashScreen } from '@ionic-native/splash-screen';
|
||||
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import { AppProvider } from '../providers/app/app';
|
||||
import { ProfileProvider } from '../providers/profile/profile';
|
||||
import { ConfigProvider } from '../providers/config/config';
|
||||
import { TouchIdProvider } from '../providers/touchid/touchid';
|
||||
|
||||
import { TabsPage } from '../pages/tabs/tabs';
|
||||
import { OnboardingPage } from '../pages/onboarding/onboarding';
|
||||
import { PinModalPage } from '../pages/pin/pin';
|
||||
import { FingerprintModalPage } from '../pages/fingerprint/fingerprint';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'app.html'
|
||||
templateUrl: 'app.html',
|
||||
providers: [TouchIdProvider]
|
||||
})
|
||||
export class CopayApp {
|
||||
rootPage: any;
|
||||
|
@ -22,7 +27,9 @@ export class CopayApp {
|
|||
private splashScreen: SplashScreen,
|
||||
private logger: Logger,
|
||||
private app: AppProvider,
|
||||
private profile: ProfileProvider
|
||||
private profile: ProfileProvider,
|
||||
private config: ConfigProvider,
|
||||
private modalCtrl: ModalController
|
||||
) {
|
||||
|
||||
this.initializeApp();
|
||||
|
@ -44,6 +51,7 @@ export class CopayApp {
|
|||
this.profile.get().then((profile: any) => {
|
||||
if (profile) {
|
||||
this.logger.info('Profile read. Go to HomePage.');
|
||||
this.openLockModal();
|
||||
this.rootPage = TabsPage;
|
||||
} else {
|
||||
// TODO: go to onboarding page
|
||||
|
@ -53,4 +61,22 @@ export class CopayApp {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
openLockModal() {
|
||||
let config = this.config.get();
|
||||
let lockMethod = config['lock']['method'];
|
||||
if (!lockMethod) return;
|
||||
if (lockMethod == 'PIN') this.openPINModal('checkPin');
|
||||
if (lockMethod == 'Fingerprint') this.openFingerprintModal();
|
||||
}
|
||||
|
||||
openPINModal(action) {
|
||||
let modal = this.modalCtrl.create(PinModalPage, { action }, { showBackdrop: false, enableBackdropDismiss: false });
|
||||
modal.present();
|
||||
}
|
||||
|
||||
openFingerprintModal() {
|
||||
let modal = this.modalCtrl.create(FingerprintModalPage, {}, { showBackdrop: false, enableBackdropDismiss: false });
|
||||
modal.present();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ import { SettingsPage } from '../pages/settings/settings';
|
|||
import { AboutPage } from '../pages/settings/about/about';
|
||||
import { AdvancedPage } from '../pages/settings/advanced/advanced';
|
||||
import { AltCurrencyPage } from '../pages/settings/alt-currency/alt-currency';
|
||||
import { FingerprintModalPage } from '../pages/fingerprint/fingerprint';
|
||||
import { LockPage } from '../pages/settings/lock/lock';
|
||||
import { PinModalPage } from '../pages/pin/pin';
|
||||
import { TermsOfUsePage } from '../pages/settings/about/terms-of-use/terms-of-use';
|
||||
|
||||
/* Send */
|
||||
|
@ -92,8 +95,11 @@ let pages: any = [
|
|||
CopayApp,
|
||||
DisclaimerPage,
|
||||
EmailPage,
|
||||
FingerprintModalPage,
|
||||
HomePage,
|
||||
LockPage,
|
||||
OnboardingPage,
|
||||
PinModalPage,
|
||||
ReceivePage,
|
||||
SendPage,
|
||||
ScanPage,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
|
||||
</ion-content>
|
|
@ -0,0 +1,20 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, NavParams, ViewController } from 'ionic-angular';
|
||||
import { TouchIdProvider } from '../../providers/touchid/touchid';
|
||||
|
||||
@Component({
|
||||
selector: 'page-fingerprint',
|
||||
templateUrl: 'fingerprint.html',
|
||||
})
|
||||
export class FingerprintModalPage {
|
||||
|
||||
constructor(
|
||||
private touchid: TouchIdProvider,
|
||||
private viewCtrl: ViewController
|
||||
) {
|
||||
touchid.check().then(() => {
|
||||
this.viewCtrl.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<ion-header>
|
||||
|
||||
<ion-navbar>
|
||||
<ion-buttons start>
|
||||
<button *ngIf="action === 'pinSetUp' || action === 'removeLock'" (click)="goBack()" ion-button icon-only>
|
||||
<ion-icon name="arrow-back"></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
<ion-title *ngIf="!confirmingPin">Please enter your PIN</ion-title>
|
||||
<ion-title *ngIf="confirmingPin">Confirm your PIN</ion-title>
|
||||
</ion-navbar>
|
||||
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<div *ngIf="disableButtons">
|
||||
<div *ngIf="!expires" translate>Incorrect PIN, try again.</div>
|
||||
<time *ngIf="expires" translate>Try again in {{expires}}</time>
|
||||
</div>
|
||||
<div class="block-code">
|
||||
<div class="circle-{{appName}}" [ngClass]="getFilledClass(1)"></div>
|
||||
<div class="circle-{{appName}}" [ngClass]="getFilledClass(2)"></div>
|
||||
<div class="circle-{{appName}}" [ngClass]="getFilledClass(3)"></div>
|
||||
<div class="circle-{{appName}}" [ngClass]="getFilledClass(4)"></div>
|
||||
</div>
|
||||
<div class="block-buttons">
|
||||
<div class="row">
|
||||
<div (click)="newEntry('1')">1</div>
|
||||
<div (click)="newEntry('2')">2</div>
|
||||
<div (click)="newEntry('3')">3</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div (click)="newEntry('4')">4</div>
|
||||
<div (click)="newEntry('5')">5</div>
|
||||
<div (click)="newEntry('6')">6</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div (click)="newEntry('7')">7</div>
|
||||
<div (click)="newEntry('8')">8</div>
|
||||
<div (click)="newEntry('9')">9</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div></div>
|
||||
<div (click)="newEntry('0')">0</div>
|
||||
<div (click)="delete()">
|
||||
<ion-icon name="arrow-round-back"></ion-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
|
@ -0,0 +1,41 @@
|
|||
page-pin {
|
||||
.block-code {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
}
|
||||
.block-buttons {
|
||||
.row {
|
||||
font-size: 1.7rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
div {
|
||||
padding: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@mixin circle {
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 3px 0px #5b5b5b;
|
||||
transition: background-color .2s ease-in-out;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
margin: 10px;
|
||||
}
|
||||
.circle-copay {
|
||||
@include circle;
|
||||
border: 1px solid #1f3598;
|
||||
}
|
||||
.circle-bitpay {
|
||||
@include circle;
|
||||
border: 1px solid #1f3598;
|
||||
}
|
||||
.filled-copay {
|
||||
background-color: #1f3598;
|
||||
}
|
||||
.filled-bitpay {
|
||||
background-color: #1f3598;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, NavParams, ViewController } from 'ionic-angular';
|
||||
import { ConfigProvider } from '../../providers/config/config';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pin',
|
||||
templateUrl: 'pin.html',
|
||||
})
|
||||
export class PinModalPage {
|
||||
|
||||
private ATTEMPT_LIMIT: number = 3;
|
||||
private ATTEMPT_LOCK_OUT_TIME: number = 5 * 60;
|
||||
public currentAttempts: number = 0;
|
||||
public currentPin: string = '';
|
||||
public firstPinEntered: string = '';
|
||||
public confirmingPin: boolean = false;
|
||||
public action: string = '';
|
||||
public appName: string = 'copay';
|
||||
public disableButtons: boolean = false;
|
||||
public expires: string = '';
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
private navParams: NavParams,
|
||||
private config: ConfigProvider,
|
||||
private logger: Logger,
|
||||
private viewCtrl: ViewController
|
||||
) {
|
||||
|
||||
switch (this.navParams.get('action')) {
|
||||
case 'checkPin':
|
||||
this.action = 'checkPin';
|
||||
break;
|
||||
case 'pinSetUp':
|
||||
this.action = 'pinSetUp';
|
||||
break;
|
||||
case 'removeLock':
|
||||
this.action = 'removeLock'
|
||||
}
|
||||
|
||||
if (this.action === 'checkPin' || this.action === 'removeLock') {
|
||||
let config = this.config.get();
|
||||
let bannedUntil = config['lock']['bannedUntil'];
|
||||
if (bannedUntil) {
|
||||
let now = Math.floor(Date.now() / 1000);
|
||||
if (now < bannedUntil) {
|
||||
this.disableButtons = true;
|
||||
this.lockTimeControl(bannedUntil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.navCtrl.pop();
|
||||
}
|
||||
|
||||
newEntry(value: string): void {
|
||||
if (this.disableButtons) return;
|
||||
this.currentPin = this.currentPin + value;
|
||||
if (!this.isComplete()) return;
|
||||
if (this.action === 'checkPin' || this.action === 'removeLock') this.checkIfCorrect();
|
||||
if (this.action === 'pinSetUp') {
|
||||
if (!this.confirmingPin) {
|
||||
this.confirmingPin = true;
|
||||
this.firstPinEntered = this.currentPin;
|
||||
this.currentPin = '';
|
||||
}
|
||||
else if (this.firstPinEntered === this.currentPin) this.save();
|
||||
else this.firstPinEntered = this.currentPin = '';
|
||||
}
|
||||
}
|
||||
|
||||
checkAttempts(): void {
|
||||
this.currentAttempts += 1;
|
||||
this.logger.info('Attempts to unlock:', this.currentAttempts);
|
||||
if (this.currentAttempts == this.ATTEMPT_LIMIT) {
|
||||
this.currentAttempts = 0;
|
||||
let bannedUntil = Math.floor(Date.now() / 1000) + this.ATTEMPT_LOCK_OUT_TIME;
|
||||
this.saveFailedAttempt(bannedUntil);
|
||||
this.lockTimeControl(bannedUntil);
|
||||
}
|
||||
}
|
||||
|
||||
lockTimeControl(bannedUntil): void {
|
||||
this.setExpirationTime(bannedUntil, null);
|
||||
var countDown = setInterval(() => {
|
||||
this.setExpirationTime(bannedUntil, countDown);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
setExpirationTime(bannedUntil, countDown) {
|
||||
let now = Math.floor(Date.now() / 1000);
|
||||
if (now > bannedUntil) {
|
||||
if (countDown) this.reset(countDown);
|
||||
} else {
|
||||
this.disableButtons = true;
|
||||
let totalSecs = bannedUntil - now;
|
||||
let m = Math.floor(totalSecs / 60);
|
||||
let s = totalSecs % 60;
|
||||
this.expires = ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2);
|
||||
}
|
||||
}
|
||||
|
||||
reset(countDown) {
|
||||
this.expires = this.disableButtons = null;
|
||||
this.currentPin = this.firstPinEntered = '';
|
||||
clearInterval(countDown);
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
if (this.disableButtons) return;
|
||||
this.currentPin = this.currentPin.substring(0, this.currentPin.length - 1);
|
||||
}
|
||||
|
||||
isComplete(): boolean {
|
||||
if (this.currentPin.length < 4) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
save(): void {
|
||||
let lock = { method: 'PIN', value: this.currentPin, bannedUntil: null };
|
||||
this.config.set({ lock });
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
checkIfCorrect(): void {
|
||||
let config = this.config.get();
|
||||
let pinValue = config['lock'] && config['lock']['value'];
|
||||
if (pinValue == this.currentPin) {
|
||||
if (this.action === 'removeLock') {
|
||||
let lock = { method: 'Disabled', value: null, bannedUntil: null };
|
||||
this.config.set({ lock });
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
if (this.action === 'checkPin') this.viewCtrl.dismiss();
|
||||
}
|
||||
else {
|
||||
this.currentPin = '';
|
||||
this.checkAttempts();
|
||||
}
|
||||
}
|
||||
|
||||
getFilledClass(limit): string {
|
||||
return this.currentPin.length >= limit ? 'filled-' + this.appName : null;
|
||||
}
|
||||
|
||||
saveFailedAttempt(bannedUntil) {
|
||||
let lock = { bannedUntil: bannedUntil };
|
||||
this.config.set({ lock });
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<ion-header>
|
||||
|
||||
<ion-navbar>
|
||||
<ion-title>Lock</ion-title>
|
||||
</ion-navbar>
|
||||
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list radio-group>
|
||||
<ion-list-header>
|
||||
Startup lock by
|
||||
</ion-list-header>
|
||||
|
||||
<ion-item *ngFor="let opt of options">
|
||||
<ion-label>{{opt.method}}</ion-label>
|
||||
<ion-radio (click)="select(opt.method)" value="{{opt.method}}" checked="{{opt.enabled}}" disabled="{{opt.disabled}}"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
|
@ -0,0 +1,66 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, NavParams, ModalController } from 'ionic-angular';
|
||||
import { ConfigProvider } from '../../../providers/config/config';
|
||||
import { TouchIdProvider } from '../../../providers/touchid/touchid';
|
||||
import { PinModalPage } from '../../pin/pin';
|
||||
|
||||
@Component({
|
||||
selector: 'page-lock',
|
||||
templateUrl: 'lock.html',
|
||||
})
|
||||
export class LockPage {
|
||||
public options: Array<{ method: string, enabled: boolean, disabled: boolean }> = [];
|
||||
public lockOptions: Object;
|
||||
|
||||
constructor(
|
||||
private modalCtrl: ModalController,
|
||||
private config: ConfigProvider,
|
||||
private touchid: TouchIdProvider,
|
||||
) {
|
||||
|
||||
this.lockOptions = this.config.get()['lock'];
|
||||
this.options = [
|
||||
{
|
||||
method: 'Disabled',
|
||||
enabled: this.lockOptions['method'] == 'Disabled' ? true : false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
method: 'PIN',
|
||||
enabled: this.lockOptions['method'] == 'PIN' ? true : false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
method: 'Fingerprint',
|
||||
enabled: this.lockOptions['method'] == 'Fingerprint' ? true : false,
|
||||
disabled: !this.touchid.isAvailable() ? true : false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
select(method): void {
|
||||
switch (method) {
|
||||
case 'PIN':
|
||||
this.openPinModal('pinSetUp');
|
||||
break;
|
||||
case 'Disabled':
|
||||
this.openPinModal('removeLock');
|
||||
break;
|
||||
case 'Fingerprint':
|
||||
this.lockByFingerprint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
openPinModal(action) {
|
||||
let modal = this.modalCtrl.create(PinModalPage, { action });
|
||||
modal.present();
|
||||
}
|
||||
|
||||
lockByFingerprint() {
|
||||
let lock = { method: 'Fingerprint', value: null, bannedUntil: null };
|
||||
this.config.set({ lock });
|
||||
}
|
||||
}
|
|
@ -57,18 +57,12 @@
|
|||
<ion-option>Urgent</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-item (click)="openLockPage()">
|
||||
<ion-icon name="lock" item-start></ion-icon>
|
||||
<ion-label>
|
||||
Lock
|
||||
</ion-label>
|
||||
<ion-select>
|
||||
<ion-option value="">Disabled</ion-option>
|
||||
<ion-option value="pin">Lock by PIN</ion-option>
|
||||
<ion-option value="finger">Lock by fingerprint</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-divider color="light">Wallets & integrations</ion-item-divider>
|
||||
<ion-item>
|
||||
<ion-icon name="folder" item-start></ion-icon>
|
||||
|
@ -81,13 +75,13 @@
|
|||
|
||||
<ion-item-divider color="light">More</ion-item-divider>
|
||||
<ion-item (click)="openAdvancedPage()">
|
||||
<ion-icon name="hammer" item-start></ion-icon>
|
||||
Advanced
|
||||
</ion-item>
|
||||
<ion-icon name="hammer" item-start></ion-icon>
|
||||
Advanced
|
||||
</ion-item>
|
||||
<ion-item (click)="openAboutPage()">
|
||||
<ion-icon name="apps" item-start></ion-icon>
|
||||
About {{appName}}
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
</ion-content>
|
||||
</ion-content>
|
|
@ -5,7 +5,7 @@ import { AppProvider } from '../../providers/app/app';
|
|||
import { LanguageProvider } from '../../providers/language/language';
|
||||
import { RateProvider } from '../../providers/rate/rate';
|
||||
import { AltCurrencyPage } from './alt-currency/alt-currency';
|
||||
|
||||
import { LockPage } from './lock/lock';
|
||||
import { AboutPage } from './about/about';
|
||||
import { AdvancedPage } from './advanced/advanced';
|
||||
|
||||
|
@ -55,4 +55,8 @@ export class SettingsPage {
|
|||
this.navCtrl.push(AboutPage);
|
||||
}
|
||||
|
||||
openLockPage() {
|
||||
this.navCtrl.push(LockPage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'rxjs/add/operator/map';
|
|||
|
||||
import { LanguageProvider } from '../../providers/language/language';
|
||||
import { ConfigProvider } from '../../providers/config/config';
|
||||
import { TouchIdProvider } from '../../providers/touchid/touchid';
|
||||
|
||||
interface App {
|
||||
WindowsStoreDisplayName: string;
|
||||
|
@ -51,7 +52,8 @@ export class AppProvider {
|
|||
public http: Http,
|
||||
private logger: Logger,
|
||||
private language: LanguageProvider,
|
||||
private config: ConfigProvider
|
||||
private config: ConfigProvider,
|
||||
private touchid: TouchIdProvider
|
||||
) {
|
||||
this.logger.info('AppProvider initialized.');
|
||||
}
|
||||
|
@ -62,6 +64,7 @@ export class AppProvider {
|
|||
// storage -> config -> language -> unit -> app
|
||||
// Everything ok
|
||||
this.language.init(config);
|
||||
this.touchid.init();
|
||||
this.getInfo().subscribe((info) => {
|
||||
this.info = info;
|
||||
resolve(true);
|
||||
|
@ -75,6 +78,6 @@ export class AppProvider {
|
|||
|
||||
getInfo() {
|
||||
return this.http.get(this.jsonPath)
|
||||
.map((res:Response) => res.json());
|
||||
.map((res: Response) => res.json());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,6 @@ export class ConfigProvider {
|
|||
if (_.isString(newOpts)) {
|
||||
newOpts = JSON.parse(newOpts);
|
||||
}
|
||||
|
||||
_.merge(config, this.configCache, newOpts);
|
||||
this.configCache = config;
|
||||
this.persistence.storeConfig(this.configCache).then(() => {
|
||||
|
|
|
@ -7,13 +7,15 @@ import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth';
|
|||
@Injectable()
|
||||
export class TouchIdProvider {
|
||||
|
||||
private _isAvailable: any = false;
|
||||
private _isAvailable: boolean = false;
|
||||
|
||||
constructor(private touchId: TouchID, private androidFingerprintAuth: AndroidFingerprintAuth, private platform: PlatformProvider) {
|
||||
this.checkDeviceFingerprint();
|
||||
}
|
||||
constructor(
|
||||
private touchId: TouchID,
|
||||
private androidFingerprintAuth: AndroidFingerprintAuth,
|
||||
private platform: PlatformProvider
|
||||
) { }
|
||||
|
||||
checkDeviceFingerprint() {
|
||||
init() {
|
||||
if (this.platform.isAndroid) this.checkAndroid();
|
||||
if (this.platform.isIOS) this.checkIOS();
|
||||
}
|
||||
|
@ -21,7 +23,7 @@ export class TouchIdProvider {
|
|||
checkIOS() {
|
||||
this.touchId.isAvailable()
|
||||
.then(
|
||||
res => this._isAvailable = 'IOS',
|
||||
res => this._isAvailable = true,
|
||||
err => console.log("Fingerprint is not available")
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +32,7 @@ export class TouchIdProvider {
|
|||
this.androidFingerprintAuth.isAvailable()
|
||||
.then(
|
||||
res => {
|
||||
if (res.isAvailable) this._isAvailable = 'ANDROID'
|
||||
if (res.isAvailable) this._isAvailable = true
|
||||
else console.log("Fingerprint is not available")
|
||||
});
|
||||
}
|
||||
|
@ -39,8 +41,8 @@ export class TouchIdProvider {
|
|||
return new Promise((resolve, reject) => {
|
||||
this.touchId.verifyFingerprint('Scan your fingerprint please')
|
||||
.then(
|
||||
res => resolve(true),
|
||||
err => reject(false)
|
||||
res => resolve(),
|
||||
err => reject()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -51,19 +53,19 @@ export class TouchIdProvider {
|
|||
.then(result => {
|
||||
if (result.withFingerprint) {
|
||||
console.log('Successfully authenticated with fingerprint.');
|
||||
resolve(true);
|
||||
resolve();
|
||||
} else if (result.withBackup) {
|
||||
console.log('Successfully authenticated with backup password!');
|
||||
resolve(true);
|
||||
resolve();
|
||||
} else console.log('Didn\'t authenticate!');
|
||||
})
|
||||
.catch(error => {
|
||||
if (error === this.androidFingerprintAuth.ERRORS.FINGERPRINT_CANCELLED) {
|
||||
console.log('Fingerprint authentication cancelled');
|
||||
reject(false);
|
||||
reject();
|
||||
} else {
|
||||
console.error(error);
|
||||
resolve(false);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -76,22 +78,22 @@ export class TouchIdProvider {
|
|||
check(): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isAvailable()) reject();
|
||||
if (this.isAvailable() == 'IOS') {
|
||||
if (this.platform.isIOS) {
|
||||
this.verifyIOSFingerprint()
|
||||
.then((success) => {
|
||||
resolve(success);
|
||||
.then(() => {
|
||||
resolve();
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
.catch(() => {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
if (this.isAvailable() == 'ANDROID') {
|
||||
if (this.platform.isAndroid) {
|
||||
this.verifyAndroidFingerprint()
|
||||
.then((success) => {
|
||||
resolve(success);
|
||||
.then(() => {
|
||||
resolve();
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
.catch(() => {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue