1/** 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import userAuth from '@ohos.userIAM.userAuth'; 17import { BusinessError } from '@ohos.base'; 18import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 19import hilog from '@ohos.hilog' 20 21const RANDOM_DATA_LENGTH = 16; 22const DOMAIN = 0x0000; 23const TAG = 'CheckUserAuthModel'; 24function hilogInfo(message: string): void { 25 hilog.info(DOMAIN, TAG, message); 26} 27function hilogError(message: string): void { 28 hilog.error(DOMAIN, TAG, message); 29} 30 31export class CheckUserAuthModel { 32 public isAuthTypeSupported(authType: userAuth.UserAuthType): boolean { 33 try { 34 userAuth.getAvailableStatus(authType, userAuth.AuthTrustLevel.ATL1); 35 hilogInfo('[CM&CheckUserAuthModel]: ' + 'userAuthType' + authType + 'is supported'); 36 return true; 37 } catch (error) { 38 let err: BusinessError = error as BusinessError; 39 hilogError(`[CM&CheckUserAuthModel]: userAuthType ${authType} is not supported, message is ${err?.message}`); 40 return false; 41 } 42 } 43 44 /** 45 * Generate a 16-byte random data. 46 * @throws { Error } - getRandomData failed. 47 */ 48 private getRandomData(): Uint8Array { 49 let randData: Uint8Array; 50 try { 51 const rand: cryptoFramework.Random = cryptoFramework.createRandom(); 52 const dataBlob: cryptoFramework.DataBlob = rand.generateRandomSync(RANDOM_DATA_LENGTH); 53 randData = dataBlob.data; 54 } catch (err) { 55 hilogInfo('generate random failed'); 56 throw new Error('getRandomData failed.'); 57 } 58 return randData; 59 } 60 61 public auth(titleStr: string, callback: (authResult: boolean) => void): void { 62 let fingerPrint: boolean = this.isAuthTypeSupported(userAuth.UserAuthType.FINGERPRINT); 63 let pin: boolean = this.isAuthTypeSupported(userAuth.UserAuthType.PIN); 64 let authTypeArray = [userAuth.UserAuthType.FINGERPRINT]; 65 if (fingerPrint) { 66 authTypeArray = [userAuth.UserAuthType.FINGERPRINT]; 67 if (pin) { 68 authTypeArray = [userAuth.UserAuthType.FINGERPRINT, userAuth.UserAuthType.PIN]; 69 } 70 } else if (pin) { 71 authTypeArray = [userAuth.UserAuthType.PIN]; 72 } else { 73 /* The user does not set identity authentication. */ 74 callback(true); 75 return; 76 } 77 78 let randomData: Uint8Array; 79 try { 80 randomData = this.getRandomData(); 81 } catch (err) { 82 callback(false); 83 return; 84 } 85 86 const authParam: userAuth.AuthParam = { 87 challenge: randomData, 88 authType: authTypeArray, 89 authTrustLevel: userAuth.AuthTrustLevel.ATL1 90 } 91 const widgetParam: userAuth.WidgetParam = { 92 title: titleStr 93 }; 94 95 try { 96 let userAuthInstance = userAuth.getUserAuthInstance(authParam, widgetParam); 97 hilogInfo('get userAuth instance success'); 98 userAuthInstance.start(); 99 100 userAuthInstance.on('result', { 101 onResult(result) { 102 if (result.result === userAuth.UserAuthResultCode.SUCCESS) { 103 callback(true); 104 } else if (result.result === userAuth.UserAuthResultCode.CANCELED) { 105 /* User cancels authentication. */ 106 callback(false); 107 } else { 108 /* User authentication failed. */ 109 callback(false); 110 } 111 } 112 }) 113 } catch (error) { 114 let err: BusinessError = error as BusinessError; 115 hilogError(`auth catch error. code is ${err?.code}, message is ${err?.message}`); 116 } 117 } 118} 119 120let checkUserAuthModel = new CheckUserAuthModel(); 121 122export default checkUserAuthModel as CheckUserAuthModel;