1/*
2 * Copyright (c) 2022-2023 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 Log from '../utils/log';
17import account_osAccount from '@ohos.account.osAccount';
18import CommonController from '../controller/commonController';
19
20class UserIdmModel {
21  protected readonly TAG: string = 'UserIdmModel';
22  protected userIdentityManager: account_osAccount.UserIdentityManager;
23  protected challenge: Uint8Array;
24  protected token: Uint8Array;
25  protected credentialId: Uint8Array;
26  protected faceNumber: number = 0;
27  protected onAcquireCallback : (number)=>{};
28
29  constructor() {
30    Log.info(this.TAG, 'constructor+');
31    this.userIdentityManager = new account_osAccount.UserIdentityManager();
32    Log.info(this.TAG, 'constructor-');
33  }
34
35  destroy(): void {
36    Log.info(this.TAG, 'destroy+');
37    this.userIdentityManager.closeSession();
38    Log.info(this.TAG, 'destroy-');
39  }
40
41  async getChallenge() : Promise<Uint8Array> {
42    return await this.userIdentityManager.openSession();
43  }
44
45  setToken(token: Uint8Array): void {
46    let tokenStr = CommonController.uin8Array2JsonString(token);
47    AppStorage.SetOrCreate<string>('UserIdm_Token', tokenStr);
48    Log.info(this.TAG, 'setToken ok, size ' + token.length);
49  }
50
51  getToken() : Uint8Array {
52    let tokenStr = AppStorage.Get<string>('UserIdm_Token');
53    let token = CommonController.jsonString2Uint8Array(tokenStr);
54    Log.info(this.TAG, 'getToken ok, size ' + token.length);
55    return token;
56  }
57
58  setCredentialId(credId: Uint8Array): void {
59    let credIdStr = CommonController.uin8Array2JsonString(credId);
60    AppStorage.SetOrCreate<string>('UserIdm_CredId', credIdStr);
61    Log.info(this.TAG, 'setCredentialId ok, size ' + credId.length);
62  }
63
64  getCredentialId() : Uint8Array {
65    let credIdStr = AppStorage.Get<string>('UserIdm_CredId');
66    let credId = CommonController.jsonString2Uint8Array(credIdStr);
67    Log.info(this.TAG, 'getCredentialId ok, size ' + credId.length);
68    return credId;
69  }
70
71  updateFaceInfo(): void {
72    const AUTH_TYPE_FACE = 2;
73    this.userIdentityManager.getAuthInfo(AUTH_TYPE_FACE).then((data) => {
74      Log.info(this.TAG, 'getAuthInfo length ' + data.length);
75      AppStorage.SetOrCreate<number>('UserIdm_FaceNum', data.length);
76      if (data.length > 0) {
77        this.setCredentialId(data[0].credentialId);
78      }
79    });
80  }
81
82  getFaceNum(): number {
83    return AppStorage.Get<number>('UserIdm_FaceNum');
84  }
85
86  setOnAcquireCallback(onAcquireCallback: (result: number) => {}): void {
87    this.onAcquireCallback = onAcquireCallback;
88  }
89
90  async enrollFace() : Promise<number> {
91    Log.info(this.TAG, 'enrollFace+');
92    let localToken = this.getToken();
93    return new Promise<number>((resolve)=> {
94      this.userIdentityManager.addCredential({
95        credType: 2,
96        credSubType: 10000,
97        token: localToken,
98      }, {
99        onResult: (result, extraInfo) => {
100          Log.info(this.TAG, 'enrollFace onResult+');
101          Log.info(this.TAG, 'FaceEnroll face.addCredential onResult ' + result);
102          if (result === 0) {
103            this.setCredentialId(extraInfo.credentialId);
104            this.updateFaceInfo();
105          }
106          Log.info(this.TAG, 'enrollFace onResult-');
107          resolve(result);
108        },
109        onAcquireInfo(moduleId, number, extraInfo) {
110          Log.info(this.TAG, 'onAcquireInfo+ ' + moduleId + ':' + number + ':' + JSON.stringify(extraInfo));
111          this.onAcquireCallback(number);
112          Log.info(this.TAG, 'onAcquireInfo-');
113        }
114      });
115    });
116  }
117
118  async deleteFace() : Promise<number> {
119    Log.info(this.TAG, 'deleteFace+');
120    if (this.credentialId === null) {
121      Log.error(this.TAG, 'no credential to delete');
122      return 0;
123    }
124
125    let localToken = this.getToken();
126    let credId = this.getCredentialId();
127    return new Promise<number>((resolve)=> {
128      this.userIdentityManager.delCred(credId, localToken, {
129        onResult: (result, extraInfo) => {
130          Log.info(this.TAG, 'FaceEnroll face.delete onResult result = ' + result);
131          this.updateFaceInfo();
132          resolve(result);
133        }
134      });
135    });
136  }
137}
138
139let userIdmModel = new UserIdmModel();
140export default userIdmModel as UserIdmModel;