1/** 2 * Copyright (c) 2021-2022 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 */ 15import BaseModel from '../../../../../../../common/utils/src/main/ets/default/model/BaseModel'; 16import ConfigData from '../../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 17import LogUtil from '../../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 18import { PasswordSettingItem } from '../../../../../../../common/utils/src/main/ets/default/bean/PasswordSettingItem'; 19import util from '@ohos.util'; 20import osAccount from '@ohos.account.osAccount' 21 22/** 23 * Credential type for authentication 24 */ 25export enum AuthType { 26 /** 27 * Indicates the PIN authentication type. 28 */ 29 PIN = 1, 30 31 /** 32 * Indicates the FACE authentication type. 33 */ 34 FACE = 2 35} 36 37export enum PinSubType { 38 /** 39 * Indicates the 6-digit credential. 40 */ 41 PIN_SIX = 10000, 42 43 /** 44 * Indicates the self-defined digital credential. 45 */ 46 PIN_NUMBER = 10001, 47 48 /** 49 * Indicates the self-defined mixed credential. 50 */ 51 PIN_MIXED = 10002, 52 53 /** 54 * Indicates the 2D face credential. 55 */ 56 FACE_2D = 20000, 57 58 /** 59 * Indicates the 3D face credential. 60 */ 61 FACE_3D = 20001 62} 63 64/** 65 * Result code 66 */ 67export enum ResultCode { 68 /** 69 * success 70 */ 71 SUCCESS = 0, 72 /** 73 * fails 74 */ 75 FAIL = 1, 76} 77 78/** 79 * Authentication method 80 */ 81export enum AuthMethod { 82 /** 83 * Authentication method PIN. 84 */ 85 PIN_ONLY = 0xF, 86 /** 87 * Authentication method face. 88 */ 89 FACE_ONLY = 0xF0 90} 91 92/** 93 * Credibility level of certification results 94 */ 95enum AuthTrustLevel { 96 /** 97 * Authentication result trusted level 1. 98 */ 99 ATL1 = 10000, 100 /** 101 * Authentication result trusted level 2. 102 */ 103 ATL2 = 20000, 104 /** 105 * Authentication result trusted level 3. 106 */ 107 ATL3 = 30000, 108 /** 109 * Authentication result trusted level 4. 110 */ 111 ATL4 = 40000 112} 113 114/** 115 * Actuator attribute list 116 */ 117enum GetPropertyType { 118 /** 119 * Authentication remain times. 120 */ 121 AUTH_SUB_TYPE = 1, 122 /** 123 * Authentication remain times. 124 */ 125 REMAIN_TIMES = 2, 126 /** 127 * Authentication freezing time. 128 */ 129 FREEZING_TIME = 3 130} 131 132export class PasswordModel extends BaseModel { 133 private TAG = ConfigData.TAG + 'PasswordModel#'; 134 pinAuth: any; 135 userAuth: any; 136 userIdentityManager: any; 137 password: string; 138 pinSubType: number; 139 private passwordList: PasswordSettingItem[][] = [ 140 [ 141 { 142 "settingIsSectionTitle": true, 143 "settingShouldDisplay": false, 144 "settingTitle": $r('app.string.biometrics'), 145 "settingAlias": "biometrics_section_title" 146 }, 147 { 148 "settingIsSectionTitle": false, 149 "settingShouldDisplay": true, 150 "settingTitle": $r('app.string.face_recognition'), 151 "settingAlias": "face_recognition", 152 'settingArrow': $r('app.media.ic_settings_arrow').toString(), 153 } 154 ], 155 [ 156 { 157 "settingIsSectionTitle": true, 158 "settingShouldDisplay": false, 159 "settingTitle": $r('app.string.password'), 160 "settingAlias": "password_section_title" 161 }, 162 { 163 "settingIsSectionTitle": false, 164 "settingShouldDisplay": true, 165 "settingTitle": $r('app.string.password_lock_screen'), 166 "settingAlias": "password_lock_screen", 167 'settingArrow': $r('app.media.ic_settings_arrow').toString(), 168 "settingRequestCode": ConfigData.PAGE_REQUEST_CODE_PASSWORD_CREATE, 169 "settingUri": "pages/passwordInput" 170 }, 171 { 172 "settingIsSectionTitle": false, 173 "settingShouldDisplay": false, 174 "settingTitle": $r('app.string.password_change_password'), 175 "settingAlias": "password_change_password", 176 'settingArrow': $r('app.media.ic_settings_arrow').toString(), 177 "settingRequestCode": ConfigData.PAGE_REQUEST_CODE_PASSWORD_CHANGE, 178 "settingUri": "pages/passwordCheck" 179 }, 180 { 181 "settingIsSectionTitle": false, 182 "settingShouldDisplay": false, 183 "settingTitle": $r('app.string.password_disable_password'), 184 "settingAlias": "password_disable_password", 185 'settingArrow': '', 186 "settingRequestCode": ConfigData.PAGE_REQUEST_CODE_PASSWORD_DISABLE, 187 "settingUri": "pages/passwordCheck" 188 } 189 ] 190 ] 191 192 /** 193 * constructor 194 */ 195 constructor() { 196 super(); 197 this.userIdentityManager = new osAccount.UserIdentityManager(); 198 this.pinAuth = new osAccount.PINAuth(); 199 this.userAuth = new osAccount.UserAuth(); 200 } 201 202 /** 203 * Get password list data 204 * @return password list data 205 */ 206 getPageData(): any[] { 207 return this.passwordList; 208 } 209 210 u8AToStr(val: Uint8Array): any{ 211 LogUtil.debug(`${this.TAG}u8AToStr in.`); 212 if (!val) { 213 LogUtil.debug(`${this.TAG}u8AToStr : param is null.`); 214 return '' 215 } 216 var dataString = ""; 217 var arrNumber = []; 218 for (var i = 0; i < val.length; i++) { 219 arrNumber.push(val[i]); 220 } 221 dataString = JSON.stringify(arrNumber); 222 LogUtil.debug(`${this.TAG}u8AToStr out.`); 223 return dataString 224 } 225 226 /** 227 * Convert array json to Uint8Array 228 * 229 * @return Uint8Array 230 */ 231 strToU8A(val: string): Uint8Array{ 232 LogUtil.debug(`${this.TAG}strToU8A in.`); 233 if (!val) { 234 LogUtil.debug(`${this.TAG}strToU8A : param is null.`); 235 return new Uint8Array([]) 236 } 237 var arr = JSON.parse(val); 238 var tmpUint8Array = new Uint8Array(arr); 239 LogUtil.debug(`${this.TAG}strToU8A out.`); 240 return tmpUint8Array 241 } 242 243 /** 244 * Convert encode string to Uint8Array 245 * 246 * @return Uint8Array 247 */ 248 encodeToU8A(val: string): Uint8Array{ 249 LogUtil.debug(`${this.TAG}encodeToU8A in.`); 250 if (!val) { 251 LogUtil.debug(`${this.TAG}encodeToU8A : param is null.`); 252 return new Uint8Array([]) 253 } 254 var textEncoder = new util.TextEncoder(); 255 LogUtil.debug(`${this.TAG}encodeToU8A out.`); 256 return textEncoder.encode(val); 257 } 258 259 /** 260 * Register Inputer 261 */ 262 registerInputer(): boolean { 263 LogUtil.debug(`${this.TAG}registerInputer in.`); 264 let result = false; 265 try { 266 result = this.pinAuth.registerInputer({ 267 onGetData: (authSubType, inputData) => { 268 let u8aPwd = this.encodeToU8A(this.password); 269 LogUtil.info(`${this.TAG} before set data, type: ${this.pinSubType}.`); 270 inputData.onSetData(this.pinSubType, u8aPwd); 271 } 272 }); 273 if(!result){ 274 this.unregisterInputer(); 275 result = this.pinAuth.registerInputer({ 276 onGetData: (authSubType, inputData) => { 277 let u8aPwd = this.encodeToU8A(this.password); 278 inputData.onSetData(this.pinSubType, u8aPwd); 279 } 280 }); 281 } 282 } catch { 283 LogUtil.error(`${this.TAG}registerInputer failed`); 284 } 285 LogUtil.info(`${this.TAG}registerInputer out.`); 286 return result; 287 } 288 289 /** 290 * UnregisterInputer 291 */ 292 unregisterInputer(): void { 293 LogUtil.debug(`${this.TAG}unregisterInputer in.`); 294 try { 295 this.pinAuth.unregisterInputer(); 296 } catch { 297 LogUtil.debug(`${this.TAG}unregisterInputer failed`); 298 } 299 LogUtil.debug(`${this.TAG}unregisterInputer out.`); 300 } 301 302 /** 303 * Open Session 304 * A challenge value of 0 indicates that opensession failed 305 * 306 * @returns challenge value 307 */ 308 openSession(callback: (challenge: string) => void): void { 309 LogUtil.debug(`${this.TAG}openSession in.`); 310 try { 311 this.userIdentityManager.openSession() 312 .then((data) =>{ 313 callback(this.u8AToStr(data)); 314 LogUtil.info(`${this.TAG} openSession success`); 315 }) 316 .catch((err) => { 317 LogUtil.error(`${this.TAG} openSession failed` + JSON.stringify(err)); 318 }) 319 } catch { 320 LogUtil.error(`${this.TAG}openSession failed`); 321 callback('0'); 322 } 323 LogUtil.debug(`${this.TAG}openSession out.`); 324 } 325 326 /** 327 * Close session 328 */ 329 closeSession(): void { 330 LogUtil.debug(`${this.TAG}closeSession in.`); 331 try { 332 this.userIdentityManager.closeSession() 333 LogUtil.debug(`${this.TAG}closeSession success`); 334 } catch (e) { 335 LogUtil.error(`${this.TAG}closeSession failed:` + e); 336 } 337 LogUtil.debug(`${this.TAG}closeSession out.`); 338 } 339 340 /** 341 * Cancel entry and pass in challenge value 342 * 343 * @param challenge challenge value. 344 */ 345 cancel(challenge: string): number { 346 LogUtil.debug(`${this.TAG}cancel in.`); 347 let result = ResultCode.FAIL; 348 try { 349 let data = this.strToU8A(challenge); 350 let result = this.userIdentityManager.cancel(data) 351 LogUtil.debug(`${this.TAG}cancel success`); 352 } catch (e) { 353 LogUtil.debug(`${this.TAG}cancel failed:` + e); 354 } 355 LogUtil.debug(`${this.TAG}cancel out.`); 356 return result; 357 } 358 359 /** 360 * Add user credential information, pass in credential addition method and credential information 361 * (credential type, subclass, if adding user's non password credentials, pass in password authentication token), 362 * and get the result callback 363 * 364 * @param pinSubType pinSubType 365 * @param password password 366 * @param onResultCall Get results callback. 367 */ 368 addPinCredential(pinSubType: number, password: string, onResultCall: (result: number) => void): void { 369 LogUtil.debug(`${this.TAG}addPinCredential in.`); 370 try { 371 this.pinSubType = pinSubType; 372 this.password = password; 373 let token = new Uint8Array([]); 374 let credentialInfo = { 375 credType: AuthType.PIN, credSubType: pinSubType, token: token 376 } 377 let callback = { 378 onResult: (result, extraInfo) => { 379 LogUtil.info(`${this.TAG} Add pin credential, result: ${result}`); 380 onResultCall(result); 381 } 382 }; 383 this.userIdentityManager.addCredential(credentialInfo, callback); 384 } catch (e) { 385 LogUtil.debug(`${this.TAG}addPinCredential failed:` + e); 386 } 387 LogUtil.debug(`${this.TAG}addPinCredential out.`); 388 } 389 390 /** 391 * Update user credential information 392 * 393 * @param credentialInfo (credential type, subclass, password authentication token). 394 * @param onResult Get results callback. 395 */ 396 updateCredential(pinSubType: number, password: string, token: string, onResultCall: (result: number, extraInfo: { 397 credentialId?: string; 398 }) => void): void { 399 LogUtil.info(`${this.TAG}updateCredential in.`); 400 try { 401 this.pinSubType = pinSubType; 402 this.password = password; 403 let dataToken = this.strToU8A(token); 404 let credentialInfo = { 405 credType: AuthType.PIN, credSubType: pinSubType, token: dataToken 406 } 407 let callback = { 408 onResult: (result, extraInfo) => { 409 LogUtil.info(`${this.TAG} update credential, result: ${result}`); 410 let retExtraInfo = {} 411 onResultCall(result, retExtraInfo); 412 } 413 }; 414 this.userIdentityManager.updateCredential(credentialInfo, callback); 415 } catch (e) { 416 LogUtil.debug(`${this.TAG}updateCredential failed:` + e); 417 } 418 LogUtil.debug(`${this.TAG}updateCredential out.`); 419 } 420 421 /** 422 * Delete all credential information 423 * 424 * @param token Password authentication token. 425 * @param onResultCallback Get results callback. 426 */ 427 delAllCredential(token: string, onResultCallback: (result: number, extraInfo: {}) => void): void { 428 LogUtil.info(`${this.TAG}delAllCredential in.`); 429 try{ 430 let callback = { 431 onResult:(result, extraInfo) => { 432 LogUtil.info(`${this.TAG} delete all credentials, result: ${result}`); 433 let retExtraInfo = {} 434 onResultCallback(result, retExtraInfo); 435 } 436 }; 437 let data = this.strToU8A(token); 438 this.userIdentityManager.delUser(data, callback); 439 } catch (e) { 440 LogUtil.debug(`${this.TAG}updateCredential failed:` + e); 441 } 442 LogUtil.debug(`${this.TAG}delAllCredential out.`); 443 } 444 445 /** 446 * Check if has pin password 447 * 448 * @param callback Get results callback. 449 */ 450 hasPinPassword(callback: (havePassword: boolean) => void): void { 451 LogUtil.debug(`${this.TAG}hasPinPassword in.`); 452 this.getPinAuthInfo((data) => { 453 let passwordHasSet = false; 454 if(data?.length && data.length > 0){ 455 passwordHasSet = true; 456 } 457 callback(passwordHasSet) 458 }); 459 LogUtil.debug(`${this.TAG}hasPinPassword out.`); 460 } 461 462 /** 463 * Get AuthInfo 464 * 465 * @param authType Credential type. 466 * @returns Returns all registered credential information of this type for the current user 467 */ 468 getPinAuthInfo(callback: (data: Array<{ 469 authType: number; 470 authSubType: number; 471 }>) => void): void { 472 LogUtil.debug(`${this.TAG}getPinAuthInfo in.`); 473 try { 474 this.userIdentityManager.getAuthInfo(AuthType.PIN) 475 .then((data) => { 476 LogUtil.info(`${this.TAG} get pin auth info data.`); 477 let arrCredInfo = []; 478 try { 479 for(let i = 0; i < data.length; i++) { 480 let credInfo = { 481 'authType': data[i].authType, 482 'authSubType': data[i].authSubType 483 }; 484 485 if (credInfo.authType == AuthType.PIN) { 486 this.pinSubType = credInfo.authSubType; 487 } 488 arrCredInfo.push(credInfo); 489 } 490 } catch(e) { 491 LogUtil.info('faceDemo pin.getAuthInfo error = ' + e); 492 } 493 callback(arrCredInfo); 494 LogUtil.info(`${this.TAG} getAuthInfo success.`); 495 }) 496 .catch((err) => { 497 LogUtil.error(`${this.TAG} getAuthInfo failed.` + JSON.stringify(err)); 498 }) 499 } catch (e) { 500 LogUtil.error(`${this.TAG}getPinAuthInfo failed:` + e); 501 } 502 LogUtil.debug(`${this.TAG}getPinAuthInfo out.`); 503 } 504 505 /** 506 * Auth 507 * 508 * @param challenge pass in challenge value. 509 * @param password password 510 * @param onResult Return results through callback. 511 */ 512 authPin(challenge: string, password: string, onResult: (result: number, extraInfo: { 513 token?: string; 514 remainTimes?: number; 515 freezingTime?: number; 516 }) => void): void { 517 LogUtil.debug(`${this.TAG}authPin in.`); 518 this.password = password; 519 try { 520 LogUtil.info(`${this.TAG} before userAuth auth pin`); 521 this.userAuth.auth(this.strToU8A(challenge), AuthType.PIN, AuthTrustLevel.ATL4, { 522 onResult: (result, extraInfo) => { 523 try{ 524 if (result === ResultCode.SUCCESS) { 525 LogUtil.debug(`${this.TAG}userAuth.auth onResult: result = success`); 526 } else { 527 LogUtil.debug(`${this.TAG}userAuth.auth failed onResult: result = ${result}`); 528 } 529 let info = { 530 'token': this.u8AToStr(extraInfo?.token), 531 'remainTimes': extraInfo.remainTimes, 532 'freezingTime': extraInfo.freezingTime 533 } 534 onResult(result, info) 535 } 536 catch(e) { 537 LogUtil.debug(`${this.TAG}userAuth.auth onResult error = ${JSON.stringify(e)}`); 538 } 539 }, 540 541 onAcquireInfo: (acquireModule, acquire, extraInfo) => { 542 try{ 543 LogUtil.debug(this.TAG + 'faceDemo pin.auth onAcquireInfo acquireModule = ' + acquireModule); 544 LogUtil.debug(this.TAG + 'faceDemo pin.auth onAcquireInfo acquire = ' + acquire); 545 } 546 catch(e) { 547 LogUtil.error(this.TAG + 'faceDemo pin.auth onAcquireInfo error = ' + e); 548 } 549 } 550 }) 551 552 } catch (e) { 553 LogUtil.error(`${this.TAG}AuthPin failed:` + e); 554 } 555 LogUtil.debug(`${this.TAG}authPin out.`); 556 } 557 558 /** 559 * getProperty 560 * 561 * @param callback Return results through callback. 562 */ 563 getAuthProperty(callback: (data: { 564 result: number; 565 authSubType: number; 566 remainTimes ?: number; 567 freezingTime ?: number; 568 }) => void): void { 569 LogUtil.info(`${this.TAG} getAuthProperty in.`); 570 try { 571 let request = { 572 'authType': AuthType.PIN, 573 'keys': [GetPropertyType.AUTH_SUB_TYPE, GetPropertyType.REMAIN_TIMES, GetPropertyType.FREEZING_TIME] 574 } 575 576 this.userAuth.getProperty(request) 577 .then((data)=> { 578 let i = JSON.stringify(data); 579 callback(data); 580 }) 581 .catch(e =>{ 582 LogUtil.debug(`${this.TAG}getAuthProperty->getProperty failed:` + e); 583 }); 584 } catch (e) { 585 LogUtil.debug(`${this.TAG}getAuthProperty failed:` + e); 586 } 587 LogUtil.debug(`${this.TAG}getAuthProperty out.`); 588 }; 589} 590 591let passwordModel = new PasswordModel(); 592export default passwordModel as PasswordModel; 593