copay-crown
Version:
A Secure Crown Wallet
146 lines (134 loc) • 4.05 kB
text/typescript
import { Injectable } from '@angular/core';
import { Logger } from '../../providers/logger/logger';
import { ConfigProvider } from '../config/config';
import { PlatformProvider } from '../platform/platform';
import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth';
import { TouchID } from '@ionic-native/touch-id';
export class TouchIdProvider {
constructor(
private touchId: TouchID,
private androidFingerprintAuth: AndroidFingerprintAuth,
private platform: PlatformProvider,
private config: ConfigProvider,
private logger: Logger
) { }
public isAvailable(): Promise<any> {
return new Promise((resolve, reject) => {
if (this.platform.isCordova && this.platform.isAndroid) {
this.checkAndroid().then((isAvailable) => {
return resolve(isAvailable);
});
}
else if (this.platform.isCordova && this.platform.isIOS) {
this.checkIOS().then((isAvailable) => {
return resolve(isAvailable);
});
}
else {
return resolve(false);
}
});
}
private checkIOS(): Promise<any> {
return new Promise((resolve, reject) => {
this.touchId.isAvailable()
.then(
res => {
return resolve(true);
},
err => {
this.logger.debug("Fingerprint is not available");
return resolve(false);
}
);
});
}
private checkAndroid() {
return new Promise((resolve, reject) => {
this.androidFingerprintAuth.isAvailable()
.then(
res => {
if (res.isAvailable) return resolve(true);
else {
this.logger.debug("Fingerprint is not available");
return resolve(false);
}
});
});
}
private verifyIOSFingerprint(): Promise<any> {
return new Promise((resolve, reject) => {
this.touchId.verifyFingerprint('Scan your fingerprint please')
.then(
res => resolve(),
err => reject()
);
});
}
private verifyAndroidFingerprint(): Promise<any> {
return new Promise((resolve, reject) => {
this.androidFingerprintAuth.encrypt({ clientId: 'Copay' })
.then(result => {
if (result.withFingerprint) {
this.logger.debug('Successfully authenticated with fingerprint.');
resolve();
} else if (result.withBackup) {
this.logger.debug('Successfully authenticated with backup password!');
resolve();
} else this.logger.debug('Didn\'t authenticate!');
}).catch(error => {
if (error === this.androidFingerprintAuth.ERRORS.FINGERPRINT_CANCELLED) {
this.logger.debug('Fingerprint authentication cancelled');
reject();
} else {
this.logger.warn(error);
reject();
};
});
});
}
public check(): Promise<any> {
return new Promise((resolve, reject) => {
if (this.platform.isIOS) {
this.verifyIOSFingerprint()
.then(() => {
resolve();
})
.catch(() => {
reject();
});
};
if (this.platform.isAndroid) {
this.verifyAndroidFingerprint()
.then(() => {
resolve();
})
.catch(() => {
reject();
});
};
});
}
private isNeeded(wallet: any): string {
let config: any = this.config.get();
config.touchIdFor = config.touchIdFor || {};
return config.touchIdFor[wallet.credentials.walletId];
}
public checkWallet(wallet: any): Promise<any> {
return new Promise((resolve, reject) => {
this.isAvailable().then((isAvailable: boolean) => {
if (!isAvailable) return resolve();
if (this.isNeeded(wallet)) {
this.check().then(() => {
return resolve();
}).catch(() => {
return reject();
});
} else {
return resolve();
}
})
});
}
}