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