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 *>(¶m->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 *>(¶m->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 ¶m)
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