Feat: fingerprint provider added

This commit is contained in:
Gabriel Bazán 2017-09-27 14:51:36 -03:00
parent eb16884565
commit ed1b9908c8
6 changed files with 198 additions and 91 deletions

View File

@ -1,95 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.bitpay.copay" version="4.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Copay</name>
<description>Copay Bitcoin Wallet</description>
<author email="copay@bitpay.com" href="https://copay.io/">BitPay</author>
<content src="index.html"/>
<access origin="*"/>
<allow-navigation href="http://ionic.local/*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
<allow-intent href="tel:*"/>
<allow-intent href="sms:*"/>
<allow-intent href="mailto:*"/>
<allow-intent href="geo:*"/>
<preference name="webviewbounce" value="false"/>
<preference name="UIWebViewBounce" value="false"/>
<preference name="DisallowOverscroll" value="true"/>
<preference name="android-minSdkVersion" value="16"/>
<preference name="BackupWebStorage" value="none"/>
<preference name="SplashMaintainAspectRatio" value="true"/>
<preference name="FadeSplashScreenDuration" value="300"/>
<!--
Change these to configure how the splashscreen displays and fades in/out.
More info here: https://github.com/apache/cordova-plugin-splashscreen
-->
<preference name="SplashShowOnlyFirstTime" value="false"/>
<preference name="SplashScreen" value="screen"/>
<preference name="SplashScreenDelay" value="3000"/>
<content src="index.html" />
<access origin="*" />
<allow-navigation href="http://ionic.local/*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="webviewbounce" value="false" />
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="android-minSdkVersion" value="16" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<platform name="android">
<allow-intent href="market:*"/>
<icon src="resources/android/icon/drawable-ldpi-icon.png" density="ldpi"/>
<icon src="resources/android/icon/drawable-mdpi-icon.png" density="mdpi"/>
<icon src="resources/android/icon/drawable-hdpi-icon.png" density="hdpi"/>
<icon src="resources/android/icon/drawable-xhdpi-icon.png" density="xhdpi"/>
<icon src="resources/android/icon/drawable-xxhdpi-icon.png" density="xxhdpi"/>
<icon src="resources/android/icon/drawable-xxxhdpi-icon.png" density="xxxhdpi"/>
<splash src="resources/android/splash/drawable-land-ldpi-screen.png" density="land-ldpi"/>
<splash src="resources/android/splash/drawable-land-mdpi-screen.png" density="land-mdpi"/>
<splash src="resources/android/splash/drawable-land-hdpi-screen.png" density="land-hdpi"/>
<splash src="resources/android/splash/drawable-land-xhdpi-screen.png" density="land-xhdpi"/>
<splash src="resources/android/splash/drawable-land-xxhdpi-screen.png" density="land-xxhdpi"/>
<splash src="resources/android/splash/drawable-land-xxxhdpi-screen.png" density="land-xxxhdpi"/>
<splash src="resources/android/splash/drawable-port-ldpi-screen.png" density="port-ldpi"/>
<splash src="resources/android/splash/drawable-port-mdpi-screen.png" density="port-mdpi"/>
<splash src="resources/android/splash/drawable-port-hdpi-screen.png" density="port-hdpi"/>
<splash src="resources/android/splash/drawable-port-xhdpi-screen.png" density="port-xhdpi"/>
<splash src="resources/android/splash/drawable-port-xxhdpi-screen.png" density="port-xxhdpi"/>
<splash src="resources/android/splash/drawable-port-xxxhdpi-screen.png" density="port-xxxhdpi"/>
<allow-intent href="market:*" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
</platform>
<platform name="ios">
<allow-intent href="itms:*"/>
<allow-intent href="itms-apps:*"/>
<icon src="resources/ios/icon/icon.png" width="57" height="57"/>
<icon src="resources/ios/icon/icon@2x.png" width="114" height="114"/>
<icon src="resources/ios/icon/icon-40.png" width="40" height="40"/>
<icon src="resources/ios/icon/icon-40@2x.png" width="80" height="80"/>
<icon src="resources/ios/icon/icon-40@3x.png" width="120" height="120"/>
<icon src="resources/ios/icon/icon-50.png" width="50" height="50"/>
<icon src="resources/ios/icon/icon-50@2x.png" width="100" height="100"/>
<icon src="resources/ios/icon/icon-60.png" width="60" height="60"/>
<icon src="resources/ios/icon/icon-60@2x.png" width="120" height="120"/>
<icon src="resources/ios/icon/icon-60@3x.png" width="180" height="180"/>
<icon src="resources/ios/icon/icon-72.png" width="72" height="72"/>
<icon src="resources/ios/icon/icon-72@2x.png" width="144" height="144"/>
<icon src="resources/ios/icon/icon-76.png" width="76" height="76"/>
<icon src="resources/ios/icon/icon-76@2x.png" width="152" height="152"/>
<icon src="resources/ios/icon/icon-83.5@2x.png" width="167" height="167"/>
<icon src="resources/ios/icon/icon-small.png" width="29" height="29"/>
<icon src="resources/ios/icon/icon-small@2x.png" width="58" height="58"/>
<icon src="resources/ios/icon/icon-small@3x.png" width="87" height="87"/>
<splash src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" height="1136"/>
<splash src="resources/ios/splash/Default-667h.png" width="750" height="1334"/>
<splash src="resources/ios/splash/Default-736h.png" width="1242" height="2208"/>
<splash src="resources/ios/splash/Default-Landscape-736h.png" width="2208" height="1242"/>
<splash src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" height="1536"/>
<splash src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" height="2048"/>
<splash src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" height="768"/>
<splash src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" height="2048"/>
<splash src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" height="2732"/>
<splash src="resources/ios/splash/Default-Portrait~ipad.png" width="768" height="1024"/>
<splash src="resources/ios/splash/Default@2x~iphone.png" width="640" height="960"/>
<splash src="resources/ios/splash/Default~iphone.png" width="320" height="480"/>
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
<splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
<splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="ionic-plugin-keyboard" spec="~2.2.1"/>
<plugin name="cordova-plugin-whitelist" spec="1.3.1"/>
<plugin name="cordova-plugin-console" spec="1.0.5"/>
<plugin name="cordova-plugin-statusbar" spec="2.2.2"/>
<plugin name="cordova-plugin-device" spec="1.1.4"/>
<plugin name="cordova-plugin-splashscreen" spec="~4.0.1"/>
<plugin name="ionic-plugin-keyboard" spec="~2.2.1" />
<plugin name="cordova-plugin-whitelist" spec="1.3.1" />
<plugin name="cordova-plugin-console" spec="1.0.5" />
<plugin name="cordova-plugin-statusbar" spec="2.2.2" />
<plugin name="cordova-plugin-device" spec="1.1.4" />
<plugin name="cordova-plugin-splashscreen" spec="~4.0.1" />
<plugin name="cordova-plugin-touch-id" spec="3.2.0" />
<plugin name="cordova-plugin-android-fingerprint-auth" spec="1.4.0" />
<engine name="android" spec="6.2.3" />
<engine name="ios" spec="4.4.0" />
</widget>

View File

@ -27,6 +27,7 @@
"@angular/platform-browser-dynamic": "4.1.3",
"@angular/tsc-wrapped": "4.1.3",
"@biesbjerg/ngx-translate-po-http-loader": "1.0.1",
"@ionic-native/android-fingerprint-auth": "4.2.1",
"@ionic-native/clipboard": "4.1.0",
"@ionic-native/core": "3.12.1",
"@ionic-native/file": "4.1.0",
@ -35,6 +36,7 @@
"@ionic-native/splash-screen": "3.12.1",
"@ionic-native/status-bar": "3.12.1",
"@ionic-native/toast": "4.1.0",
"@ionic-native/touch-id": "4.2.1",
"@ionic/storage": "2.0.1",
"@ngx-translate/core": "6.0.1",
"@nsalaun/ng-logger": "2.0.1",
@ -47,11 +49,13 @@
"cordova-android": "6.2.3",
"cordova-clipboard": "1.0.0",
"cordova-ios": "4.4.0",
"cordova-plugin-android-fingerprint-auth": "1.4.0",
"cordova-plugin-console": "1.0.5",
"cordova-plugin-device": "1.1.4",
"cordova-plugin-qrscanner": "2.5.0",
"cordova-plugin-splashscreen": "4.0.3",
"cordova-plugin-statusbar": "2.2.2",
"cordova-plugin-touch-id": "3.2.0",
"cordova-plugin-whitelist": "1.3.1",
"cordova-plugin-wkwebview-engine": "git+https://github.com/ionic-team/cordova-plugin-wkwebview-engine.git",
"cordova-plugin-x-socialsharing": "5.1.8",
@ -78,7 +82,7 @@
"angular2-template-loader": "0.6.2",
"codecov": "2.2.0",
"html-loader": "0.4.5",
"ionic": "3.9.2",
"ionic": "3.12.0",
"jasmine-core": "2.6.4",
"jasmine-spec-reporter": "4.1.1",
"karma": "1.7.0",
@ -111,11 +115,13 @@
"cordova-plugin-x-toast": {},
"cordova-plugin-x-socialsharing": {},
"cordova-plugin-qrscanner": {},
"cordova-plugin-wkwebview-engine": {}
"cordova-plugin-wkwebview-engine": {},
"cordova-plugin-touch-id": {},
"cordova-plugin-android-fingerprint-auth": {}
},
"platforms": [
"android",
"ios"
]
}
}
}

View File

@ -4,12 +4,14 @@ import { HttpModule, Http } from '@angular/http';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
/* Native modules */
import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth';
import { Clipboard } from '@ionic-native/clipboard';
import { QRScanner } from '@ionic-native/qr-scanner';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { SocialSharing } from '@ionic-native/social-sharing';
import { Toast } from '@ionic-native/toast';
import { TouchID } from '@ionic-native/touch-id';
/* Modules */
import { MomentModule } from 'angular2-moment';
@ -61,6 +63,7 @@ import { PopupProvider } from '../providers/popup/popup';
import { ProfileProvider } from '../providers/profile/profile';
import { RateProvider } from '../providers/rate/rate';
import { ScanProvider } from '../providers/scan/scan';
import { TouchIdProvider } from '../providers/touchid/touchid';
import { TxFormatProvider } from '../providers/tx-format/tx-format';
import { WalletProvider } from '../providers/wallet/wallet';
@ -91,6 +94,7 @@ let pages: any = [
];
let providers: any = [
AndroidFingerprintAuth,
AppProvider,
BwcProvider,
ConfigProvider,
@ -107,6 +111,8 @@ let providers: any = [
ScanProvider,
SocialSharing,
Toast,
TouchID,
TouchIdProvider,
TxFormatProvider,
WalletProvider,
{

View File

@ -1,10 +1,9 @@
import { Injectable } from '@angular/core';
import { Platform } from 'ionic-angular';
import { AlertController } from 'ionic-angular';
@Injectable()
export class PopupProvider {
constructor(private platform: Platform, public alertCtrl: AlertController) {
constructor(public alertCtrl: AlertController) {
}
ionicAlert(title, subTitle, okText): void {

View File

@ -0,0 +1,99 @@
import { Injectable } from '@angular/core';
import { PlatformProvider } from '../platform/platform';
import { TouchID } from '@ionic-native/touch-id';
import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth';
@Injectable()
export class TouchIdProvider {
private _isAvailable: any = false;
constructor(private touchId: TouchID, private androidFingerprintAuth: AndroidFingerprintAuth, private platform: PlatformProvider) {
this.checkDeviceFingerprint();
}
checkDeviceFingerprint() {
if (this.platform.isAndroid) this.checkAndroid();
if (this.platform.isIOS) this.checkIOS();
}
checkIOS() {
this.touchId.isAvailable()
.then(
res => this._isAvailable = 'IOS',
err => console.log("Fingerprint is not available")
);
}
checkAndroid() {
this.androidFingerprintAuth.isAvailable()
.then(
res => {
if (res.isAvailable) this._isAvailable = 'ANDROID'
else console.log("Fingerprint is not available")
});
}
verifyIOSFingerprint(): Promise<any> {
return new Promise((resolve, reject) => {
this.touchId.verifyFingerprint('Scan your fingerprint please')
.then(
res => resolve(true),
err => reject(false)
);
});
}
verifyAndroidFingerprint(): Promise<any> {
return new Promise((resolve, reject) => {
this.androidFingerprintAuth.encrypt({ clientId: 'Copay' })
.then(result => {
if (result.withFingerprint) {
console.log('Successfully authenticated with fingerprint.');
resolve(true);
} else if (result.withBackup) {
console.log('Successfully authenticated with backup password!');
resolve(true);
} else console.log('Didn\'t authenticate!');
})
.catch(error => {
if (error === this.androidFingerprintAuth.ERRORS.FINGERPRINT_CANCELLED) {
console.log('Fingerprint authentication cancelled');
reject(false);
} else {
console.error(error);
resolve(false);
}
});
});
}
isAvailable() {
return this._isAvailable;
}
check(): Promise<any> {
return new Promise((resolve, reject) => {
if (!this.isAvailable()) reject();
if (this.isAvailable() == 'IOS') {
this.verifyIOSFingerprint()
.then((success) => {
resolve(success);
})
.catch(err => {
reject(err);
});
}
if (this.isAvailable() == 'ANDROID') {
this.verifyAndroidFingerprint()
.then((success) => {
resolve(success);
})
.catch(err => {
reject(err);
});
}
});
}
}