• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 
16 #include "napi_account_iam_common.h"
17 
18 #include <map>
19 
20 #include <uv.h>
21 #include "account_error_no.h"
22 #include "account_iam_info.h"
23 #include "account_log_wrapper.h"
24 #include "napi_account_error.h"
25 #include "napi_account_common.h"
26 #include "napi_account_iam_constant.h"
27 #include "securec.h"
28 
29 namespace OHOS {
30 namespace AccountJsKit {
31 using namespace OHOS::AccountSA;
32 
AccountIAMConvertOtherToJSErrCode(int32_t errCode)33 static int32_t AccountIAMConvertOtherToJSErrCode(int32_t errCode)
34 {
35     switch (errCode) {
36         case ERR_IAM_SUCCESS:
37             return ERR_JS_SUCCESS;
38         case ERR_IAM_FAIL:
39         case ERR_IAM_TOKEN_TIMEOUT:
40         case ERR_IAM_TOKEN_AUTH_FAILED:
41             return ERR_JS_AUTH_CREDENTIAL_WRONG_ERROR;
42         case ERR_IAM_TRUST_LEVEL_NOT_SUPPORT:
43             return ERR_JS_TRUST_LEVEL_NOT_SUPPORTED;
44         case ERR_IAM_TYPE_NOT_SUPPORT:
45             return ERR_JS_AUTH_TYPE_NOT_SUPPORTED;
46         case ERR_IAM_TIMEOUT:
47             return ERR_JS_AUTH_TIMEOUT;
48         case ERR_IAM_CANCELED:
49             return ERR_JS_AUTH_CANCELLED;
50         case ERR_IAM_BUSY:
51             return ERR_JS_AUTH_SERVICE_BUSY;
52         case ERR_IAM_LOCKED:
53             return ERR_JS_AUTH_SERVICE_LOCKED;
54         case ERR_IAM_NOT_ENROLLED:
55             return ERR_JS_CREDENTIAL_NOT_EXIST;
56         case ERR_IAM_PIN_IS_EXPIRED:
57             return ERR_JS_PIN_IS_EXPIRED;
58         case ERR_IAM_COMPLEXITY_CHECK_FAILED:
59             return ERR_JS_COMPLEXITY_CHECK_FAILED;
60         case ERR_IAM_INVALID_CONTEXT_ID:
61             return ERR_JS_INVALID_CONTEXT_ID;
62         case ERR_ACCOUNT_COMMON_INVALID_PARAMETER:
63         case ERR_IAM_INVALID_PARAMETERS:
64             return ERR_JS_INVALID_PARAMETER;
65         case ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED:
66             return ERR_JS_CREDENTIAL_INPUTER_ALREADY_EXIST;
67         case ERR_ACCOUNT_IAM_KIT_INPUTER_NOT_REGISTERED:
68             return ERR_JS_CREDENTIAL_INPUTER_NOT_EXIST;
69         case ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE:
70         case ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT:
71         case ERR_DOMAIN_ACCOUNT_NOT_SUPPORT_BACKGROUND_ACCOUNT_REQUEST:
72             return ERR_JS_AUTH_TYPE_NOT_SUPPORTED;
73         case ERR_IAM_CREDENTIAL_NUMBER_REACH_LIMIT:
74             return ERR_JS_CREDENTIAL_NUMBER_REACH_LIMIT;
75         case ERR_IAM_SESSION_TIMEOUT:
76             return ERR_JS_SESSION_TIMEOUT;
77         default:
78             return ERR_JS_SYSTEM_SERVICE_EXCEPTION;
79     }
80 }
81 
AccountIAMConvertToJSErrCode(int32_t errCode)82 int32_t AccountIAMConvertToJSErrCode(int32_t errCode)
83 {
84     if (CheckJsErrorCode(errCode)) {
85         return errCode;
86     }
87     if (errCode == ERR_ACCOUNT_COMMON_NOT_SYSTEM_APP_ERROR) {
88         return ERR_JS_IS_NOT_SYSTEM_APP;
89     } else if (errCode == ERR_ACCOUNT_COMMON_PERMISSION_DENIED || errCode == ERR_IAM_CHECK_PERMISSION_FAILED) {
90         return ERR_JS_PERMISSION_DENIED;
91     } else if (errCode == ERR_ACCOUNT_COMMON_INVALID_PARAMETER) {
92         return ERR_JS_INVALID_PARAMETER;
93     } else if (errCode == ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR) {
94         return ERR_JS_ACCOUNT_NOT_FOUND;
95     } else if (errCode == ERR_ACCOUNT_COMMON_ACCOUNT_IS_RESTRICTED) {
96         return ERR_JS_ACCOUNT_RESTRICTED;
97     }
98     return AccountIAMConvertOtherToJSErrCode(errCode);
99 }
100 
101 #ifdef HAS_USER_AUTH_PART
NapiIDMCallback(napi_env env,const std::shared_ptr<JsIAMCallback> & callback)102 NapiIDMCallback::NapiIDMCallback(napi_env env, const std::shared_ptr<JsIAMCallback> &callback)
103     : env_(env), callback_(callback)
104 {}
105 
~NapiIDMCallback()106 NapiIDMCallback::~NapiIDMCallback()
107 {}
108 
OnResult(int32_t result,const Attributes & extraInfo)109 void NapiIDMCallback::OnResult(int32_t result, const Attributes &extraInfo)
110 {
111     std::lock_guard<std::mutex> lock(mutex_);
112     if (callback_->onResultCalled) {
113         ACCOUNT_LOGE("Call twice is not allowed");
114         return;
115     }
116     callback_->onResultCalled = true;
117     std::shared_ptr<IDMCallbackParam> param = std::make_shared<IDMCallbackParam>(env_);
118     if (param == nullptr) {
119         ACCOUNT_LOGE("Failed for nullptr");
120         return;
121     }
122     param->result = result;
123     extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_CREDENTIAL_ID, param->credentialId);
124     param->callback = callback_;
125     auto task = [param]() {
126         ACCOUNT_LOGI("Enter NapiIDMCallback::OnResult task");
127         napi_handle_scope scope = nullptr;
128         napi_open_handle_scope(param->env, &scope);
129         if (scope == nullptr) {
130             ACCOUNT_LOGE("Failed to open scope");
131             return;
132         }
133         napi_value argv[ARG_SIZE_TWO] = {0};
134         napi_create_int32(param->env, AccountIAMConvertToJSErrCode(param->result), &argv[PARAM_ZERO]);
135         napi_create_object(param->env, &argv[PARAM_ONE]);
136         napi_value credentialId =
137             CreateUint8Array(param->env, reinterpret_cast<uint8_t *>(&param->credentialId), sizeof(uint64_t));
138         napi_set_named_property(param->env, argv[PARAM_ONE], "credentialId", credentialId);
139         NapiCallVoidFunction(param->env, argv, ARG_SIZE_TWO, param->callback->onResult);
140         napi_close_handle_scope(param->env, scope);
141         return;
142     };
143     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
144         ACCOUNT_LOGE("Failed to send event for auth");
145         return;
146     }
147     ACCOUNT_LOGI("Post OnResult task finish");
148 }
149 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)150 void NapiIDMCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
151 {
152     std::lock_guard<std::mutex> lock(mutex_);
153     if (!callback_->hasOnAcquireInfo) {
154         ACCOUNT_LOGE("No 'OnAcquireInfo' callback need return");
155         return;
156     }
157     if (callback_->onResultCalled) {
158         ACCOUNT_LOGE("Call after OnResult is not allowed");
159         return;
160     }
161     std::shared_ptr<IDMCallbackParam> param = std::make_shared<IDMCallbackParam>(env_);
162     if (param == nullptr) {
163         ACCOUNT_LOGE("Failed for nullptr");
164         return;
165     }
166     param->callback = callback_;
167     param->module = module;
168     param->acquire = acquireInfo;
169     extraInfo.GetUint8ArrayValue(Attributes::AttributeKey::ATTR_EXTRA_INFO, param->extraInfo);
170     auto task = [param]() {
171         ACCOUNT_LOGI("Enter NapiIDMCallback::OnAcquireInfo task");
172         napi_handle_scope scope = nullptr;
173         napi_open_handle_scope(param->env, &scope);
174         if (scope == nullptr) {
175             ACCOUNT_LOGE("Fail to open scope");
176             return;
177         }
178         napi_value argv[ARG_SIZE_THREE] = {0};
179         napi_env env = param->env;
180         napi_create_int32(env, param->module, &argv[PARAM_ZERO]);
181         napi_create_int32(env, param->acquire, &argv[PARAM_ONE]);
182         argv[PARAM_TWO] = CreateUint8Array(env, param->extraInfo.data(), param->extraInfo.size());
183         NapiCallVoidFunction(env, argv, ARG_SIZE_THREE, param->callback->onAcquireInfo);
184         napi_close_handle_scope(param->env, scope);
185         return;
186     };
187     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
188         ACCOUNT_LOGE("Failed to send event for auth");
189         return;
190     }
191     ACCOUNT_LOGI("Post OnAcquireInfo task finish");
192 }
193 
ParseAddCredInfo(napi_env env,napi_value value,IDMContext & context)194 napi_status ParseAddCredInfo(napi_env env, napi_value value, IDMContext &context)
195 {
196     napi_valuetype valueType = napi_undefined;
197     napi_typeof(env, value, &valueType);
198     if (valueType != napi_object) {
199         ACCOUNT_LOGE("value is not an object");
200         return napi_invalid_arg;
201     }
202     napi_value result = nullptr;
203     napi_get_named_property(env, value, "credType", &result);
204     int32_t credType = -1;
205     NAPI_CALL_BASE(env, napi_get_value_int32(env, result, &credType), napi_invalid_arg);
206     context.addCredInfo.authType = static_cast<AuthType>(credType);
207     napi_get_named_property(env, value, "credSubType", &result);
208     int32_t credSubType = -1;
209     NAPI_CALL_BASE(env, napi_get_value_int32(env, result, &credSubType), napi_invalid_arg);
210     context.addCredInfo.pinType = static_cast<PinSubType>(credSubType);
211     napi_get_named_property(env, value, "token", &result);
212     if (ParseUint8TypedArrayToVector(env, result, context.addCredInfo.token) != napi_ok) {
213         ACCOUNT_LOGE("Get Uint8Array data failed");
214         return napi_invalid_arg;
215     }
216     if (!GetOptionalNumberPropertyByKey(env, value, "accountId", context.accountId, context.parseHasAccountId)) {
217         ACCOUNT_LOGE("Get accountId data failed");
218         return napi_invalid_arg;
219     }
220     return napi_ok;
221 }
222 
ParseIAMCallback(napi_env env,napi_value object,std::shared_ptr<JsIAMCallback> & callback)223 napi_status ParseIAMCallback(napi_env env, napi_value object, std::shared_ptr<JsIAMCallback> &callback)
224 {
225     napi_valuetype valueType = napi_undefined;
226     napi_typeof(env, object, &valueType);
227     if (valueType != napi_object) {
228         ACCOUNT_LOGE("invalid object");
229         return napi_invalid_arg;
230     }
231     napi_value result = nullptr;
232     napi_get_named_property(env, object, "onResult", &result);
233     napi_typeof(env, result, &valueType);
234     if (valueType == napi_function) {
235         NAPI_CALL_BASE(env, napi_create_reference(env, result, 1, &callback->onResult), napi_generic_failure);
236     } else {
237         ACCOUNT_LOGE("onResult is not a function");
238         return napi_invalid_arg;
239     }
240     napi_has_named_property(env, object, "onAcquireInfo", &callback->hasOnAcquireInfo);
241     if (!callback->hasOnAcquireInfo) {
242         return napi_ok;
243     }
244     napi_get_named_property(env, object, "onAcquireInfo", &result);
245     napi_typeof(env, result, &valueType);
246     if (valueType == napi_function) {
247         NAPI_CALL_BASE(env, napi_create_reference(env, result, 1, &callback->onAcquireInfo), napi_generic_failure);
248     } else if ((valueType == napi_undefined) || (valueType == napi_null)) {
249         ACCOUNT_LOGI("onAcquireInfo is undefined or null");
250     } else {
251         ACCOUNT_LOGE("onAcquireInfo is not a function");
252         return napi_invalid_arg;
253     }
254     return napi_ok;
255 }
256 
CreateCredInfoArray(napi_env env,const std::vector<CredentialInfo> & info)257 napi_value CreateCredInfoArray(napi_env env, const std::vector<CredentialInfo> &info)
258 {
259     napi_value arr = nullptr;
260     napi_create_array_with_length(env, info.size(), &arr);
261     uint32_t index = 0;
262     for (auto item : info) {
263         napi_value obj;
264         NAPI_CALL(env, napi_create_object(env, &obj));
265         napi_value credentialId = CreateUint8Array(
266             env, reinterpret_cast<uint8_t *>(&item.credentialId), sizeof(uint64_t));
267         napi_value authType;
268         NAPI_CALL(env, napi_create_uint32(env, item.authType, &authType));
269         napi_value napiPinType;
270         PinSubType pinType = item.pinType.value_or(PinSubType::PIN_MAX);
271         NAPI_CALL(env, napi_create_uint32(env, pinType, &napiPinType));
272         napi_value templateId = CreateUint8Array(
273             env, reinterpret_cast<uint8_t *>(&item.templateId), sizeof(uint64_t));
274         NAPI_CALL(env, napi_set_named_property(env, obj, "credentialId", credentialId));
275         NAPI_CALL(env, napi_set_named_property(env, obj, "authType", authType));
276         NAPI_CALL(env, napi_set_named_property(env, obj, "authSubType", napiPinType));
277         NAPI_CALL(env, napi_set_named_property(env, obj, "templateId", templateId));
278         NAPI_CALL(env, napi_set_element(env, arr, index, obj));
279         index++;
280     }
281     return arr;
282 }
283 
ConvertGetPropertyTypeToAttributeKey(GetPropertyType in,Attributes::AttributeKey & out)284 napi_status ConvertGetPropertyTypeToAttributeKey(GetPropertyType in,
285     Attributes::AttributeKey &out)
286 {
287     static const std::map<GetPropertyType, Attributes::AttributeKey> type2Key = {
288         { AUTH_SUB_TYPE, Attributes::AttributeKey::ATTR_PIN_SUB_TYPE },
289         { REMAIN_TIMES, Attributes::AttributeKey::ATTR_REMAIN_TIMES },
290         { FREEZING_TIME, Attributes::AttributeKey::ATTR_FREEZING_TIME },
291         { ENROLLMENT_PROGRESS, Attributes::AttributeKey::ATTR_ENROLL_PROGRESS },
292         { SENSOR_INFO, Attributes::AttributeKey::ATTR_SENSOR_INFO },
293         { NEXT_PHASE_FREEZING_TIME, Attributes::AttributeKey::ATTR_NEXT_FAIL_LOCKOUT_DURATION },
294     };
295 
296     auto iter = type2Key.find(in);
297     if (iter == type2Key.end()) {
298         ACCOUNT_LOGE("GetPropertyType %{public}d is invalid", in);
299         return napi_invalid_arg;
300     } else {
301         out = iter->second;
302     }
303     return napi_ok;
304 }
305 
ParseGetPropKeys(napi_env env,napi_value napiKeys,std::vector<Attributes::AttributeKey> & keys)306 napi_status ParseGetPropKeys(napi_env env, napi_value napiKeys, std::vector<Attributes::AttributeKey> &keys)
307 {
308     std::vector<uint32_t> tempKeys;
309     if (ParseUInt32Array(env, napiKeys, tempKeys) != napi_ok) {
310         ACCOUNT_LOGE("Parameter error. The type of \"keys\" must be GetPropertyType's array");
311         return napi_invalid_arg;
312     }
313     for (const auto &item : tempKeys) {
314         Attributes::AttributeKey key;
315         napi_status status = ConvertGetPropertyTypeToAttributeKey(static_cast<GetPropertyType>(item), key);
316         if (status != napi_ok) {
317             ACCOUNT_LOGE("Parameter error. The type of \"key\" must be 'GetPropertyType'");
318             return napi_invalid_arg;
319         }
320         keys.push_back(key);
321     }
322     return napi_ok;
323 }
324 
ParseGetPropRequest(napi_env env,napi_value object,GetPropertyContext & context)325 napi_status ParseGetPropRequest(napi_env env, napi_value object, GetPropertyContext &context)
326 {
327     napi_valuetype valueType = napi_undefined;
328     napi_typeof(env, object, &valueType);
329     if (valueType != napi_object) {
330         ACCOUNT_LOGE("invalid object");
331         return napi_invalid_arg;
332     }
333     napi_value napiAuthType = nullptr;
334     napi_get_named_property(env, object, "authType", &napiAuthType);
335     int32_t authType = -1;
336     napi_get_value_int32(env, napiAuthType, &authType);
337     context.request.authType = static_cast<AuthType>(authType);
338     napi_value napiKeys = nullptr;
339     NAPI_CALL_BASE(env, napi_get_named_property(env, object, "keys", &napiKeys), napi_generic_failure);
340     if (ParseGetPropKeys(env, napiKeys, context.request.keys) != napi_ok) {
341         ACCOUNT_LOGE("Get getPropRequest's keys failed");
342         return napi_invalid_arg;
343     }
344     if (!GetOptionalNumberPropertyByKey(env, object, "accountId", context.accountId, context.parseHasAccountId)) {
345         ACCOUNT_LOGE("Get getPropRequest's accountId failed");
346         return napi_invalid_arg;
347     }
348     return napi_ok;
349 }
350 
ParseSetPropRequest(napi_env env,napi_value object,SetPropertyRequest & request)351 napi_status ParseSetPropRequest(napi_env env, napi_value object, SetPropertyRequest &request)
352 {
353     napi_valuetype valueType = napi_undefined;
354     napi_typeof(env, object, &valueType);
355     if (valueType != napi_object) {
356         ACCOUNT_LOGE("invalid object");
357         return napi_invalid_arg;
358     }
359     napi_value napiKey = nullptr;
360     napi_get_named_property(env, object, "key", &napiKey);
361     int32_t key = -1;
362     napi_get_value_int32(env, napiKey, &key);
363     request.mode = static_cast<PropertyMode>(key);
364     napi_value napiAuthType = nullptr;
365     napi_get_named_property(env, object, "authType", &napiAuthType);
366     int32_t authType = -1;
367     napi_get_value_int32(env, napiAuthType, &authType);
368     request.authType = static_cast<AuthType>(authType);
369     napi_value napiSetInfo = nullptr;
370     napi_get_named_property(env, object, "setInfo", &napiSetInfo);
371     std::vector<uint8_t> setInfo;
372     ParseUint8TypedArrayToVector(env, napiSetInfo, setInfo);
373     request.attrs.SetUint8ArrayValue(Attributes::AttributeKey(key), setInfo);
374     return napi_ok;
375 }
376 
GeneratePropertyJs(napi_env env,const GetPropertyCommonContext & context,napi_value & dataJs)377 static void GeneratePropertyJs(napi_env env, const GetPropertyCommonContext &context, napi_value &dataJs)
378 {
379     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &dataJs));
380     napi_value napiResult = nullptr;
381     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, context.propertyInfo.result, &napiResult));
382     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, dataJs, "result", napiResult));
383     for (const auto &key : context.keys) {
384         switch (key) {
385             case Attributes::AttributeKey::ATTR_PIN_SUB_TYPE: {
386                 SetInt32ToJsProperty(env, context.propertyInfo.authSubType, "authSubType", dataJs);
387                 break;
388             }
389             case Attributes::AttributeKey::ATTR_REMAIN_TIMES: {
390                 SetInt32ToJsProperty(env, context.propertyInfo.remainTimes, "remainTimes", dataJs);
391                 break;
392             }
393             case Attributes::AttributeKey::ATTR_FREEZING_TIME: {
394                 SetInt32ToJsProperty(env, context.propertyInfo.freezingTime, "freezingTime", dataJs);
395                 break;
396             }
397             case Attributes::AttributeKey::ATTR_ENROLL_PROGRESS: {
398                 napi_value napiEnrollmentProgress = nullptr;
399                 napi_create_string_utf8(
400                     env, context.propertyInfo.enrollmentProgress.c_str(), NAPI_AUTO_LENGTH, &napiEnrollmentProgress);
401                 napi_set_named_property(env, dataJs, "enrollmentProgress", napiEnrollmentProgress);
402                 break;
403             }
404             case Attributes::AttributeKey::ATTR_SENSOR_INFO: {
405                 napi_value napiSensorInfo = nullptr;
406                 napi_create_string_utf8(env,
407                     context.propertyInfo.sensorInfo.c_str(), NAPI_AUTO_LENGTH, &napiSensorInfo);
408                 napi_set_named_property(env, dataJs, "sensorInfo", napiSensorInfo);
409                 break;
410             }
411             case Attributes::AttributeKey::ATTR_NEXT_FAIL_LOCKOUT_DURATION: {
412                 SetInt32ToJsProperty(env, context.propertyInfo.nextPhaseFreezingTime, "nextPhaseFreezingTime", dataJs);
413                 break;
414             }
415             default:
416                 break;
417         }
418     }
419 }
420 
CreateExecutorProperty(napi_env env,GetPropertyCommonContext & context,napi_value & errJs,napi_value & dataJs)421 static void CreateExecutorProperty(
422     napi_env env, GetPropertyCommonContext &context, napi_value &errJs, napi_value &dataJs)
423 {
424     context.errCode = context.propertyInfo.result;
425     if (!context.isGetById && context.errCode == ERR_IAM_NOT_ENROLLED) {
426         context.errCode = ERR_OK;
427     }
428     if (context.errCode != ERR_OK) {
429         int32_t jsErrCode = AccountIAMConvertToJSErrCode(context.propertyInfo.result);
430         errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
431         napi_get_null(env, &dataJs);
432         return;
433     }
434     context.errCode = ERR_OK;
435     napi_get_null(env, &errJs);
436     GeneratePropertyJs(env, context, dataJs);
437 }
438 
GenerateAuthResult(napi_env env,AuthCallbackParam * param)439 static napi_value GenerateAuthResult(napi_env env, AuthCallbackParam *param)
440 {
441     napi_value object = CreateAuthResult(param->env, param->token, param->remainTimes, param->freezingTime);
442     if (param->hasNextPhaseFreezingTime) {
443         SetInt32ToJsProperty(env, param->nextPhaseFreezingTime, "nextPhaseFreezingTime", object);
444     }
445     if (param->hasCredentialId) {
446         napi_value napiCredentialId =
447             CreateUint8Array(env, reinterpret_cast<uint8_t *>(&param->credentialId), sizeof(uint64_t));
448         NAPI_CALL(env, napi_set_named_property(env, object, "credentialId", napiCredentialId));
449     }
450     if (param->hasAccountId) {
451         SetInt32ToJsProperty(env, param->accountId, "accountId", object);
452     }
453     if (param->hasPinValidityPeriod) {
454         napi_value napiPinValidityPeriod = nullptr;
455         NAPI_CALL(env, napi_create_int64(env, param->pinValidityPeriod, &napiPinValidityPeriod));
456         NAPI_CALL(env, napi_set_named_property(env, object, "pinValidityPeriod", napiPinValidityPeriod));
457     }
458     return object;
459 }
460 
NapiUserAuthCallback(napi_env env,const std::shared_ptr<JsIAMCallback> & callback)461 NapiUserAuthCallback::NapiUserAuthCallback(napi_env env, const std::shared_ptr<JsIAMCallback> &callback)
462     : env_(env), callback_(callback)
463 {}
464 
~NapiUserAuthCallback()465 NapiUserAuthCallback::~NapiUserAuthCallback()
466 {}
467 
PrepareAuthResult(int32_t result,const Attributes & extraInfo,AuthCallbackParam & param)468 void NapiUserAuthCallback::PrepareAuthResult(int32_t result, const Attributes &extraInfo, AuthCallbackParam &param)
469 {
470     param.resultCode = result;
471     extraInfo.GetUint8ArrayValue(Attributes::AttributeKey::ATTR_SIGNATURE, param.token);
472     extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_REMAIN_TIMES, param.remainTimes);
473     extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_FREEZING_TIME, param.freezingTime);
474     if (extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_NEXT_FAIL_LOCKOUT_DURATION,
475                                 param.nextPhaseFreezingTime)) {
476         param.hasNextPhaseFreezingTime = true;
477     }
478     if (extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_CREDENTIAL_ID, param.credentialId)) {
479         param.hasCredentialId = true;
480     }
481     if (extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_USER_ID, param.accountId)) {
482         param.hasAccountId = true;
483     }
484     if (extraInfo.GetInt64Value(Attributes::AttributeKey::ATTR_PIN_EXPIRED_INFO, param.pinValidityPeriod)) {
485         param.hasPinValidityPeriod = true;
486     }
487     param.callback = callback_;
488 }
489 
OnResult(int32_t result,const Attributes & extraInfo)490 void NapiUserAuthCallback::OnResult(int32_t result, const Attributes &extraInfo)
491 {
492     std::lock_guard<std::mutex> lock(mutex_);
493     if (callback_->onResultCalled) {
494         ACCOUNT_LOGE("call twice is not allowed");
495         return;
496     }
497     callback_->onResultCalled = true;
498     AuthCallbackParam *param = new (std::nothrow) AuthCallbackParam(env_);
499     if (param == nullptr) {
500         ACCOUNT_LOGE("fail for nullptr");
501         return;
502     }
503     PrepareAuthResult(result, extraInfo, *param);
504     auto task = [param = std::move(param)]() {
505         ACCOUNT_LOGI("Enter NapiUserAuthCallback::OnResult task");
506         napi_handle_scope scope = nullptr;
507         napi_open_handle_scope(param->env, &scope);
508         if (scope == nullptr) {
509             ACCOUNT_LOGE("Fail to open scope");
510             delete param;
511             return;
512         }
513         napi_value argv[ARG_SIZE_TWO] = {nullptr};
514         napi_create_int32(param->env, AccountIAMConvertToJSErrCode(param->resultCode), &argv[PARAM_ZERO]);
515         argv[PARAM_ONE] = GenerateAuthResult(param->env, param);
516         NapiCallVoidFunction(param->env, argv, ARG_SIZE_TWO, param->callback->onResult);
517         napi_close_handle_scope(param->env, scope);
518         delete param;
519         return;
520     };
521     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
522         delete param;
523         return;
524     }
525     ACCOUNT_LOGI("Post NapiUserAuthCallback::OnResult task finish");
526 }
527 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)528 void NapiUserAuthCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
529 {
530     std::lock_guard<std::mutex> lock(mutex_);
531     if (!callback_->hasOnAcquireInfo) {
532         ACCOUNT_LOGE("no 'OnAcquireInfo' callback need return");
533         return;
534     }
535     if (callback_->onResultCalled) {
536         ACCOUNT_LOGE("call after OnResult is not allowed");
537         return;
538     }
539     AuthCallbackParam *param = new (std::nothrow) AuthCallbackParam(env_);
540     if (param == nullptr) {
541         ACCOUNT_LOGE("Failed for nullptr");
542         return;
543     }
544     param->module = module;
545     param->acquireInfo = acquireInfo;
546     extraInfo.GetUint8ArrayValue(Attributes::AttributeKey::ATTR_EXTRA_INFO, param->extraInfo);
547     param->callback = callback_;
548     auto task = [param = std::move(param)]() {
549         ACCOUNT_LOGI("Enter NapiUserAuthCallback::OnAcquireInfo task");
550         napi_handle_scope scope = nullptr;
551         napi_open_handle_scope(param->env, &scope);
552         if (scope == nullptr) {
553             ACCOUNT_LOGE("Fail to open scope");
554             delete param;
555             return;
556         }
557         napi_value argv[ARG_SIZE_THREE] = {nullptr};
558         napi_create_int32(param->env, param->module, &argv[PARAM_ZERO]);
559         napi_create_uint32(param->env, param->acquireInfo, &argv[PARAM_ONE]);
560         argv[PARAM_TWO] = CreateUint8Array(param->env, param->extraInfo.data(), param->extraInfo.size());
561         NapiCallVoidFunction(param->env, argv, ARG_SIZE_THREE, param->callback->onAcquireInfo);
562         napi_close_handle_scope(param->env, scope);
563         delete param;
564         return;
565     };
566     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
567         ACCOUNT_LOGE("Failed to send event for auth");
568         delete param;
569         return;
570     }
571     ACCOUNT_LOGI("Post NapiUserAuthCallback::OnAcquireInfo task finish");
572 }
573 
NapiGetInfoCallback(napi_env env,napi_ref callbackRef,napi_deferred deferred)574 NapiGetInfoCallback::NapiGetInfoCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
575     : env_(env), deferred_(deferred)
576 {
577     callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
578 }
579 
~NapiGetInfoCallback()580 NapiGetInfoCallback::~NapiGetInfoCallback()
581 {}
582 
OnCredentialInfo(int32_t result,const std::vector<AccountSA::CredentialInfo> & infoList)583 void NapiGetInfoCallback::OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList)
584 {
585     ACCOUNT_LOGI("Get gredential info result = %{public}d", result);
586     std::lock_guard<std::mutex> lock(mutex_);
587     if (onResultCalled_) {
588         ACCOUNT_LOGE("Call twice is not allowed");
589         return;
590     }
591     onResultCalled_ = true;
592     std::shared_ptr<GetAuthInfoContext> context = std::make_shared<GetAuthInfoContext>(env_);
593     if (context == nullptr) {
594         ACCOUNT_LOGE("Failed for nullptr");
595         return;
596     }
597     context->callback = callback_;
598     context->deferred = deferred_;
599     context->errCode = result;
600     context->credInfo = infoList;
601     auto task = [context = std::move(context)]() {
602         ACCOUNT_LOGI("Enter NapiGetInfoCallback::OnCredentialInfo task");
603         napi_handle_scope scope = nullptr;
604         napi_open_handle_scope(context->env, &scope);
605         if (scope == nullptr) {
606             ACCOUNT_LOGE("Failed to open scope");
607             return;
608         }
609         napi_env env = context->env;
610         CommonCallbackInfo callbackInfo(env);
611         callbackInfo.callbackRef = context->callback->callbackRef;
612         callbackInfo.deferred = context->deferred;
613         callbackInfo.errCode = context->errCode;
614         if (context->errCode != ERR_OK) {
615             int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->errCode);
616             callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
617             napi_get_null(env, &callbackInfo.dataJs);
618         } else {
619             napi_get_null(env, &callbackInfo.errJs);
620             callbackInfo.dataJs = CreateCredInfoArray(env, context->credInfo);
621         }
622         CallbackAsyncOrPromise(callbackInfo);
623         napi_close_handle_scope(context->env, scope);
624         return;
625     };
626     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
627         ACCOUNT_LOGE("Failed to send event for auth");
628         return;
629     }
630     ACCOUNT_LOGI("Post OnCredentialInfo task finish");
631 }
632 
NapiGetEnrolledIdCallback(napi_env env,napi_deferred deferred)633 NapiGetEnrolledIdCallback::NapiGetEnrolledIdCallback(napi_env env, napi_deferred deferred)
634     : env_(env), deferred_(deferred)
635 {}
636 
~NapiGetEnrolledIdCallback()637 NapiGetEnrolledIdCallback::~NapiGetEnrolledIdCallback()
638 {}
639 
OnEnrolledId(int32_t result,uint64_t enrolledId)640 void NapiGetEnrolledIdCallback::OnEnrolledId(int32_t result, uint64_t enrolledId)
641 {
642     std::shared_ptr<GetEnrolledIdContext> context = std::make_shared<GetEnrolledIdContext>(env_);
643     if (context == nullptr) {
644         ACCOUNT_LOGE("Failed for nullptr");
645         return;
646     }
647     context->deferred = deferred_;
648     context->errCode = result;
649     context->enrolledId = enrolledId;
650     auto task = [context]() {
651         ACCOUNT_LOGI("Enter NapiGetEnrolledIdCallback::OnEnrolledId task");
652         napi_handle_scope scope = nullptr;
653         napi_open_handle_scope(context->env, &scope);
654         if (scope == nullptr) {
655             ACCOUNT_LOGE("Failed to open scope");
656             return;
657         }
658         napi_env env = context->env;
659         napi_value errJs = nullptr;
660         napi_value dataJs = nullptr;
661         if (context->errCode != ERR_OK) {
662             int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->errCode);
663             errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
664             napi_get_null(env, &dataJs);
665         } else {
666             napi_get_null(env, &errJs);
667             dataJs = CreateUint8Array(env, reinterpret_cast<uint8_t *>(&context->enrolledId), sizeof(uint64_t));
668         }
669         CallbackAsyncOrPromise(env, context.get(), errJs, dataJs);
670         napi_close_handle_scope(env, scope);
671         return;
672     };
673     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
674         ACCOUNT_LOGE("Failed to send event for auth");
675         return;
676     }
677     ACCOUNT_LOGI("Post OnEnrolledId task finish");
678 }
679 
NapiGetPropCallback(napi_env env,napi_ref callbackRef,napi_deferred deferred,const std::vector<Attributes::AttributeKey> & keys)680 NapiGetPropCallback::NapiGetPropCallback(
681     napi_env env, napi_ref callbackRef, napi_deferred deferred, const std::vector<Attributes::AttributeKey> &keys)
682     : env_(env), deferred_(deferred), keys_(keys)
683 {
684     callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
685 }
686 
~NapiGetPropCallback()687 NapiGetPropCallback::~NapiGetPropCallback()
688 {}
689 
GetExecutorPropertys(const UserIam::UserAuth::Attributes & extraInfo,ExecutorProperty & propertyInfo)690 void NapiGetPropCallback::GetExecutorPropertys(
691     const UserIam::UserAuth::Attributes &extraInfo, ExecutorProperty &propertyInfo)
692 {
693     for (const auto &key : keys_) {
694         switch (key) {
695             case Attributes::AttributeKey::ATTR_PIN_SUB_TYPE: {
696                 if (!extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_PIN_SUB_TYPE, propertyInfo.authSubType)) {
697                     ACCOUNT_LOGE("get authSubType failed");
698                 }
699                 break;
700             }
701             case Attributes::AttributeKey::ATTR_REMAIN_TIMES: {
702                 if (!extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_REMAIN_TIMES, propertyInfo.remainTimes)) {
703                     ACCOUNT_LOGE("get remainTimes failed");
704                 }
705                 break;
706             }
707             case Attributes::AttributeKey::ATTR_FREEZING_TIME: {
708                 if (!extraInfo.GetInt32Value(
709                     Attributes::AttributeKey::ATTR_FREEZING_TIME, propertyInfo.freezingTime)) {
710                     ACCOUNT_LOGE("get freezingTime failed");
711                 }
712                 break;
713             }
714             case Attributes::AttributeKey::ATTR_ENROLL_PROGRESS: {
715                 if (!extraInfo.GetStringValue(
716                     Attributes::AttributeKey::ATTR_ENROLL_PROGRESS, propertyInfo.enrollmentProgress)) {
717                     ACCOUNT_LOGE("get enrollmentProgress failed");
718                 }
719                 break;
720             }
721             case Attributes::AttributeKey::ATTR_SENSOR_INFO: {
722                 if (!extraInfo.GetStringValue(Attributes::AttributeKey::ATTR_SENSOR_INFO, propertyInfo.sensorInfo)) {
723                     ACCOUNT_LOGE("get sensorInfo failed");
724                 }
725                 break;
726             }
727             case Attributes::AttributeKey::ATTR_NEXT_FAIL_LOCKOUT_DURATION: {
728                 if (!extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_NEXT_FAIL_LOCKOUT_DURATION,
729                     propertyInfo.nextPhaseFreezingTime)) {
730                     ACCOUNT_LOGE("get nextPhaseFreezingTime failed");
731                 }
732                 break;
733             }
734             default:
735                 ACCOUNT_LOGE("get invalid key");
736                 break;
737         }
738     }
739     return;
740 }
741 
OnResult(int32_t result,const UserIam::UserAuth::Attributes & extraInfo)742 void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo)
743 {
744     std::lock_guard<std::mutex> lock(mutex_);
745     if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
746         ACCOUNT_LOGE("Return for nullptr");
747         return;
748     }
749     if (onResultCalled_) {
750         ACCOUNT_LOGE("Call twice is not allowed");
751         return;
752     }
753     onResultCalled_ = true;
754     std::shared_ptr<GetPropertyCommonContext> context = std::make_shared<GetPropertyCommonContext>(env_);
755     if (context == nullptr) {
756         ACCOUNT_LOGE("Failed for nullptr");
757         return;
758     }
759     // create context data
760     GetExecutorPropertys(extraInfo, context->propertyInfo);
761     context->isGetById = isGetById_;
762     context->callback = callback_;
763     context->deferred = deferred_;
764     context->errCode = ERR_OK;
765     context->propertyInfo.result = result;
766     context->keys = keys_;
767     auto task = [context = std::move(context)]() {
768         ACCOUNT_LOGI("Enter NapiGetPropCallback::OnResult task");
769         napi_handle_scope scope = nullptr;
770         napi_open_handle_scope(context->env, &scope);
771         if (scope == nullptr) {
772             ACCOUNT_LOGE("Failed to open scope");
773             return;
774         }
775         CommonCallbackInfo callbackInfo(context->env);
776         callbackInfo.callbackRef = context->callback->callbackRef;
777         callbackInfo.deferred = context->deferred;
778         CreateExecutorProperty(context->env, *context, callbackInfo.errJs, callbackInfo.dataJs);
779         callbackInfo.errCode = context->errCode;
780         CallbackAsyncOrPromise(callbackInfo);
781         napi_close_handle_scope(context->env, scope);
782         return;
783     };
784     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
785         ACCOUNT_LOGE("Failed to send event for auth");
786         return;
787     }
788     ACCOUNT_LOGI("Post OnResult task finish");
789 }
790 
NapiSetPropCallback(napi_env env,napi_ref callbackRef,napi_deferred deferred)791 NapiSetPropCallback::NapiSetPropCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
792     : env_(env), deferred_(deferred)
793 {
794     callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
795 }
796 
~NapiSetPropCallback()797 NapiSetPropCallback::~NapiSetPropCallback()
798 {}
799 
NapiPrepareRemoteAuthCallback(napi_env env,napi_ref callbackRef,napi_deferred deferred)800 NapiPrepareRemoteAuthCallback::NapiPrepareRemoteAuthCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
801     : env_(env), callbackRef_(callbackRef), deferred_(deferred)
802 {}
803 
~NapiPrepareRemoteAuthCallback()804 NapiPrepareRemoteAuthCallback::~NapiPrepareRemoteAuthCallback()
805 {
806     if (callbackRef_ != nullptr) {
807         ReleaseNapiRefAsync(env_, callbackRef_);
808         callbackRef_ = nullptr;
809     }
810     deferred_ = nullptr;
811 }
812 
OnResult(int32_t result)813 void NapiPrepareRemoteAuthCallback::OnResult(int32_t result)
814 {
815     std::lock_guard<std::mutex> lock(mutex_);
816     if ((callbackRef_ == nullptr) && (deferred_ == nullptr)) {
817         return;
818     }
819     std::shared_ptr<PrepareRemoteAuthContext> context = std::make_shared<PrepareRemoteAuthContext>(env_);
820     if (context == nullptr) {
821         ACCOUNT_LOGE("Nullptr fail.");
822         return;
823     }
824     context->deferred = deferred_;
825     context->errCode = ERR_OK;
826     context->result = result;
827     auto task = [context]() {
828         ACCOUNT_LOGI("Enter NapiPrepareRemoteAuthCallback::OnResult task");
829         napi_handle_scope scope = nullptr;
830         napi_open_handle_scope(context->env, &scope);
831         if (scope == nullptr) {
832             ACCOUNT_LOGE("Failed to open scope");
833             return;
834         }
835         napi_env env = context->env;
836         napi_value errJs = nullptr;
837         napi_value dataJs = nullptr;
838         context->errCode = context->result;
839         if (context->result != ERR_OK) {
840             int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->result);
841             errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
842             napi_get_null(env, &dataJs);
843         } else {
844             napi_get_null(env, &errJs);
845             napi_get_null(env, &dataJs);
846         }
847         CallbackAsyncOrPromise(env, context.get(), errJs, dataJs);
848         napi_close_handle_scope(context->env, scope);
849         return;
850     };
851     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
852         ACCOUNT_LOGE("Failed to send event for auth");
853         return;
854     }
855     ACCOUNT_LOGI("Post OnResult task finish");
856 }
857 
OnResult(int32_t result,const UserIam::UserAuth::Attributes & extraInfo)858 void NapiSetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo)
859 {
860     std::lock_guard<std::mutex> lock(mutex_);
861     if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
862         return;
863     }
864     if (onResultCalled_) {
865         ACCOUNT_LOGE("Call twice is not allowed");
866         return;
867     }
868     onResultCalled_ = true;
869     std::shared_ptr<SetPropertyContext> context = std::make_shared<SetPropertyContext>(env_);
870     if (context == nullptr) {
871         ACCOUNT_LOGE("Failed for nullptr");
872         return;
873     }
874     context->callback = callback_;
875     context->deferred = deferred_;
876     context->errCode = ERR_OK;
877     context->result = result;
878     auto task = [context = std::move(context)]() {
879         ACCOUNT_LOGI("Enter NapiSetPropCallback::OnResult task");
880         napi_handle_scope scope = nullptr;
881         napi_open_handle_scope(context->env, &scope);
882         if (scope == nullptr) {
883             ACCOUNT_LOGE("Failed to open scope");
884             return;
885         }
886         napi_env env = context->env;
887         CommonCallbackInfo callbackInfo(env);
888         callbackInfo.callbackRef = context->callback->callbackRef;
889         callbackInfo.deferred = context->deferred;
890         callbackInfo.errCode = context->result;
891         if (context->result != ERR_OK) {
892             int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->result);
893             callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
894             napi_get_null(env, &callbackInfo.dataJs);
895         } else {
896             napi_get_null(env, &callbackInfo.errJs);
897             napi_get_null(env, &callbackInfo.dataJs);
898         }
899         CallbackAsyncOrPromise(callbackInfo);
900         napi_close_handle_scope(env, scope);
901         return;
902     };
903     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
904         ACCOUNT_LOGE("Failed to send event for auth");
905         return;
906     }
907     ACCOUNT_LOGI("Post OnResult task finish");
908 }
909 #endif  // HAS_USER_AUTH_PART
910 
911 #ifdef HAS_PIN_AUTH_PART
InputDataConstructor(napi_env env,napi_callback_info info)912 napi_value InputDataConstructor(napi_env env, napi_callback_info info)
913 {
914     napi_value thisVar;
915     void *data;
916     size_t argc = ARG_SIZE_ONE;
917     napi_value argv[ARG_SIZE_ONE] = {nullptr};
918     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
919     InputerContext *context = static_cast<InputerContext *>(data);
920     if (thisVar == nullptr) {
921         ACCOUNT_LOGE("thisVar is nullptr");
922         return nullptr;
923     }
924     if (context == nullptr) {
925         ACCOUNT_LOGE("inputerData is nullptr");
926         return nullptr;
927     }
928     NAPI_CALL(env, napi_wrap(env, thisVar, context,
929         [](napi_env env, void *data, void *hint) {
930             InputerContext *context = static_cast<InputerContext *>(data);
931             if (context != nullptr) {
932                 delete context;
933             }
934         },
935         nullptr, nullptr));
936     return thisVar;
937 }
938 
OnSetData(napi_env env,napi_callback_info info)939 napi_value OnSetData(napi_env env, napi_callback_info info)
940 {
941     if (!IsSystemApp(env)) {
942         return nullptr;
943     }
944     size_t argc = ARG_SIZE_TWO;
945     napi_value thisVar = nullptr;
946     napi_value argv[ARG_SIZE_TWO] = {nullptr};
947     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
948     if (argc != ARG_SIZE_TWO) {
949         ACCOUNT_LOGE("failed to parse parameters, expect three parameters, but got %{public}zu", argc);
950         std::string errMsg = "Parameter error. The number of parameters should be 2";
951         AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, true);
952         return nullptr;
953     }
954     InputerContext *context = nullptr;
955     NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&context));
956     if (context == nullptr || context->inputerData == nullptr) {
957         ACCOUNT_LOGE("context or inputerData is nullptr");
958         return nullptr;
959     }
960     int32_t authSubType;
961     if (!GetIntProperty(env, argv[PARAM_ZERO], authSubType)) {
962         ACCOUNT_LOGE("Get authSubType failed");
963         std::string errMsg = "Parameter error. The type of \"authSubType\" must be AuthSubType";
964         AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, true);
965         return nullptr;
966     }
967     std::vector<uint8_t> data;
968     if (ParseUint8TypedArrayToVector(env, argv[PARAM_ONE], data) != napi_ok) {
969         ACCOUNT_LOGE("Get data failed");
970         std::string errMsg = "Parameter error. The type of \"data\" must be Uint8Array";
971         AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, true);
972         return nullptr;
973     }
974     ACCOUNT_LOGI("Call OnSetData, authSubType: %{public}d", authSubType);
975     context->inputerData->OnSetData(authSubType, data);
976     context->inputerData = nullptr;
977     return nullptr;
978 }
979 
GetCtorIInputerData(napi_env env,const std::shared_ptr<AccountSA::IInputerData> & inputerData)980 napi_value GetCtorIInputerData(napi_env env, const std::shared_ptr<AccountSA::IInputerData> &inputerData)
981 {
982     if (inputerData == nullptr) {
983         ACCOUNT_LOGE("inputerData nullptr");
984         return nullptr;
985     }
986     InputerContext *context = new (std::nothrow) InputerContext();
987     if (context == nullptr) {
988         ACCOUNT_LOGE("inputer context is nullptr");
989         return nullptr;
990     }
991     napi_property_descriptor clzDes[] = {
992         DECLARE_NAPI_FUNCTION("onSetData", OnSetData),
993     };
994     context->inputerData = inputerData;
995     napi_value cons;
996     NAPI_CALL(env, napi_define_class(env, "InputerData", NAPI_AUTO_LENGTH,
997         InputDataConstructor, reinterpret_cast<void *>(context),
998         sizeof(clzDes) / sizeof(napi_property_descriptor), clzDes, &cons));
999     return cons;
1000 }
1001 
GetInputerInstance(InputerContext * context,napi_value * inputerDataVarCtor)1002 static napi_status GetInputerInstance(InputerContext *context, napi_value *inputerDataVarCtor)
1003 {
1004     napi_value cons = GetCtorIInputerData(context->env, context->inputerData);
1005     if (cons == nullptr) {
1006         ACCOUNT_LOGD("failed to GetCtorIInputerData");
1007         return napi_generic_failure;
1008     }
1009     return napi_new_instance(context->env, cons, 0, nullptr, inputerDataVarCtor);
1010 }
1011 
NapiGetDataCallback(napi_env env,const std::shared_ptr<NapiCallbackRef> & callback)1012 NapiGetDataCallback::NapiGetDataCallback(napi_env env, const std::shared_ptr<NapiCallbackRef> &callback)
1013     : env_(env), callback_(callback)
1014 {}
1015 
~NapiGetDataCallback()1016 NapiGetDataCallback::~NapiGetDataCallback()
1017 {}
1018 
OnGetData(int32_t authSubType,std::vector<uint8_t> challenge,const std::shared_ptr<AccountSA::IInputerData> inputerData)1019 void NapiGetDataCallback::OnGetData(int32_t authSubType, std::vector<uint8_t> challenge,
1020     const std::shared_ptr<AccountSA::IInputerData> inputerData)
1021 {
1022     if (callback_ == nullptr) {
1023         ACCOUNT_LOGE("The onGetData function is undefined");
1024         return;
1025     }
1026     std::shared_ptr<InputerContext> context = std::make_shared<InputerContext>();
1027     if (context == nullptr) {
1028         ACCOUNT_LOGE("Failed for nullptr");
1029         return;
1030     }
1031     context->env = env_;
1032     context->callback = callback_;
1033     context->authSubType = authSubType;
1034     context->challenge = challenge;
1035     context->inputerData = inputerData;
1036     auto task = [context]() {
1037         ACCOUNT_LOGI("Enter NapiGetDataCallback::OnGetData task");
1038         napi_env env = context->env;
1039         napi_handle_scope scope = nullptr;
1040         napi_open_handle_scope(env, &scope);
1041         if (scope == nullptr) {
1042             ACCOUNT_LOGE("Failed to open scope");
1043             return;
1044         }
1045         napi_value argv[ARG_SIZE_THREE] = {0};
1046         napi_create_int32(env, context->authSubType, &argv[PARAM_ZERO]);
1047         GetInputerInstance(context.get(), &argv[PARAM_ONE]);
1048         napi_create_object(env, &argv[PARAM_TWO]);
1049         if (!(context->challenge.empty())) {
1050             napi_value dataJs = nullptr;
1051             dataJs = CreateUint8Array(env, context->challenge.data(), context->challenge.size());
1052             napi_set_named_property(env, argv[PARAM_TWO], "challenge", dataJs);
1053         }
1054         NapiCallVoidFunction(env, argv, ARG_SIZE_THREE, context->callback->callbackRef);
1055         napi_close_handle_scope(env, scope);
1056         return;
1057     };
1058     if (napi_status::napi_ok !=  napi_send_event(env_, task, napi_eprio_vip)) {
1059         ACCOUNT_LOGE("Failed to send event for auth");
1060         return;
1061     }
1062     ACCOUNT_LOGI("Post OnGetData task finish");
1063 }
1064 #endif  // HAS_PIN_AUTH_PART
1065 
CallbackAsyncOrPromise(const CommonCallbackInfo & callbackInfo)1066 void CallbackAsyncOrPromise(const CommonCallbackInfo &callbackInfo)
1067 {
1068     if (callbackInfo.callbackRef) {
1069         napi_value argv[ARG_SIZE_TWO] = {callbackInfo.errJs, callbackInfo.dataJs};
1070         ACCOUNT_LOGI("call js function");
1071         NapiCallVoidFunction(callbackInfo.env, argv, ARG_SIZE_TWO, callbackInfo.callbackRef);
1072     } else {
1073         if (callbackInfo.errCode == ERR_OK) {
1074             napi_resolve_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.dataJs);
1075         } else {
1076             napi_reject_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.errJs);
1077         }
1078     }
1079 }
1080 
CallbackAsyncOrPromise(napi_env env,CommonAsyncContext * context,napi_value errJs,napi_value dataJs)1081 void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs)
1082 {
1083     CommonCallbackInfo callbackInfo(env);
1084     callbackInfo.callbackRef = context->callbackRef;
1085     callbackInfo.deferred = context->deferred;
1086     callbackInfo.errJs = errJs;
1087     callbackInfo.dataJs = dataJs;
1088     callbackInfo.errCode = context->errCode;
1089     CallbackAsyncOrPromise(callbackInfo);
1090 }
1091 
ParseUInt32Array(napi_env env,napi_value value,std::vector<uint32_t> & data)1092 napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data)
1093 {
1094     data.clear();
1095     bool isArray = false;
1096     napi_is_array(env, value, &isArray);
1097     if (!isArray) {
1098         ACCOUNT_LOGE("value is not an array");
1099         return napi_invalid_arg;
1100     }
1101     uint32_t arrLen = 0;
1102     napi_get_array_length(env, value, &arrLen);
1103     for (uint32_t i = 0; i < arrLen; ++i) {
1104         napi_value item = nullptr;
1105         napi_get_element(env, value, i, &item);
1106         uint32_t num = 0;
1107         if (napi_get_value_uint32(env, item, &num) != napi_ok) {
1108             data.clear();
1109             return napi_number_expected;
1110         }
1111         data.push_back(num);
1112     }
1113     return napi_ok;
1114 }
1115 
CreateErrorObject(napi_env env,int32_t code)1116 napi_value CreateErrorObject(napi_env env, int32_t code)
1117 {
1118     napi_value errObj = nullptr;
1119     NAPI_CALL(env, napi_create_object(env, &errObj));
1120     napi_value number = 0;
1121     NAPI_CALL(env, napi_create_int32(env, code, &number));
1122     NAPI_CALL(env, napi_set_named_property(env, errObj, "code", number));
1123     return errObj;
1124 }
1125 
IsAccountIdValid(int32_t accountId)1126 bool IsAccountIdValid(int32_t accountId)
1127 {
1128     if (accountId < 0) {
1129         ACCOUNT_LOGI("The account id is invalid");
1130         return false;
1131     }
1132     return true;
1133 }
1134 }  // namespace AccountJsKit
1135 }  // namespace OHOS
1136