• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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