1 /*
2  * Copyright (c) 2023-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 "user_auth_instance_v10.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 #include <string>
21 
22 #include "iam_logger.h"
23 #include "iam_ptr.h"
24 
25 #include "user_auth_client_impl.h"
26 #include "user_auth_napi_helper.h"
27 #include "user_auth_common_defines.h"
28 
29 #define LOG_TAG "USER_AUTH_NAPI"
30 
31 namespace OHOS {
32 namespace UserIam {
33 namespace UserAuth {
34 const std::string AUTH_EVENT_RESULT = "result";
35 const std::string AUTH_PARAM_CHALLENGE = "challenge";
36 const std::string AUTH_PARAM_AUTHTYPE = "authType";
37 const std::string AUTH_PARAM_AUTHTRUSTLEVEL = "authTrustLevel";
38 const std::string AUTH_PARAM_REUSEUNLOCKRESULT = "reuseUnlockResult";
39 const std::string WIDGET_PARAM_TITLE = "title";
40 const std::string WIDGET_PARAM_NAVIBTNTEXT = "navigationButtonText";
41 const std::string WIDGET_PARAM_WINDOWMODE = "windowMode";
42 const std::string NOTICETYPE = "noticeType";
43 const std::string REUSEMODE = "reuseMode";
44 const std::string REUSEDURATION = "reuseDuration";
45 
46 namespace WidgetType {
47     constexpr int32_t TITLE_MAX = 500;
48     constexpr int32_t BUTTON_MAX = 60;
49 }
GetEnrolledState(napi_env env,napi_callback_info info)50 napi_value UserAuthInstanceV10::GetEnrolledState(napi_env env, napi_callback_info info)
51 {
52     napi_value argv[ARGS_ONE] = {nullptr};
53     size_t argc = ARGS_ONE;
54     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
55     if (argc != ARGS_ONE) {
56         IAM_LOGE("parms error");
57         std::string msgStr = "Parameter error. The number of parameters should be 1.";
58         napi_throw(env, UserAuthNapiHelper::GenerateErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr));
59         return nullptr;
60     }
61     int32_t type;
62     if (UserAuthNapiHelper::GetInt32Value(env, argv[PARAM0], type) != napi_ok) {
63         IAM_LOGE("napi_get_value_int32 fail");
64         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env, UserAuthResultCode::GENERAL_ERROR));
65         return nullptr;
66     }
67     if (!UserAuthNapiHelper::CheckUserAuthType(type)) {
68         IAM_LOGE("CheckUserAuthType fail");
69         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env, UserAuthResultCode::TYPE_NOT_SUPPORT));
70         return nullptr;
71     }
72     AuthType authType = AuthType(type);
73     EnrolledState enrolledState = {};
74     int32_t code = UserAuthClientImpl::Instance().GetEnrolledState(API_VERSION_12, authType, enrolledState);
75     if (code != SUCCESS) {
76         IAM_LOGE("failed to get enrolled state %{public}d", code);
77         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env,
78             UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV10(code))));
79         return nullptr;
80     }
81     return DoGetEnrolledStateResult(env, enrolledState);
82 }
83 
DoGetEnrolledStateResult(napi_env env,EnrolledState enrolledState)84 napi_value UserAuthInstanceV10::DoGetEnrolledStateResult(napi_env env, EnrolledState enrolledState)
85 {
86     IAM_LOGI("start");
87     napi_value eventInfo;
88     napi_status ret = napi_create_object(env, &eventInfo);
89     if (ret != napi_ok) {
90         IAM_LOGE("napi_create_object failed %{public}d", ret);
91         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env, UserAuthResultCode::GENERAL_ERROR));
92         return nullptr;
93     }
94     int32_t credentialDigest = static_cast<int32_t>(enrolledState.credentialDigest);
95     int32_t credentialCount = static_cast<int32_t>(enrolledState.credentialCount);
96     IAM_LOGI("get enrolled state success, credentialDigest = %{public}d, credentialCount = %{public}d",
97         credentialDigest, credentialCount);
98     ret = UserAuthNapiHelper::SetInt32Property(env, eventInfo, "credentialDigest", credentialDigest);
99     if (ret != napi_ok) {
100         IAM_LOGE("napi_create_int32 failed %{public}d", ret);
101         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env, UserAuthResultCode::GENERAL_ERROR));
102         return nullptr;
103     }
104     ret = UserAuthNapiHelper::SetInt32Property(env, eventInfo, "credentialCount", credentialCount);
105     if (ret != napi_ok) {
106         IAM_LOGE("napi_create_int32 failed %{public}d", ret);
107         napi_throw(env, UserAuthNapiHelper::GenerateBusinessErrorV9(env, UserAuthResultCode::GENERAL_ERROR));
108         return nullptr;
109     }
110     IAM_LOGI("get enrolled state end");
111     return eventInfo;
112 }
113 
UserAuthInstanceV10(napi_env env)114 UserAuthInstanceV10::UserAuthInstanceV10(napi_env env) : callback_(Common::MakeShared<UserAuthCallbackV10>(env))
115 {
116     if (callback_ == nullptr) {
117         IAM_LOGE("get null callback");
118     }
119     authParam_.authTrustLevel = AuthTrustLevel::ATL1;
120     widgetParam_.navigationButtonText = "";
121     widgetParam_.title = "";
122     widgetParam_.windowMode = WindowModeType::UNKNOWN_WINDOW_MODE;
123 }
124 
InitChallenge(napi_env env,napi_value value)125 UserAuthResultCode UserAuthInstanceV10::InitChallenge(napi_env env, napi_value value)
126 {
127     authParam_.challenge.clear();
128     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
129     if (ret == napi_ok) {
130         IAM_LOGI("challenge is null");
131         std::string msgStr = "Parameter error. The type of \"challenge\" must be Uint8Array.";
132         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
133     }
134     ret = UserAuthNapiHelper::GetUint8ArrayValue(env, value, MAX_CHALLENG_LEN, authParam_.challenge);
135     if (ret != napi_ok) {
136         IAM_LOGE("GetUint8ArrayValue fail:%{public}d", ret);
137         std::string msgStr = "Parameter error. The length of \"challenge\" connot exceed 32.";
138         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
139     }
140     IAM_LOGI("challenge size:%{public}zu", authParam_.challenge.size());
141     return UserAuthResultCode::SUCCESS;
142 }
143 
InitAuthType(napi_env env,napi_value value)144 UserAuthResultCode UserAuthInstanceV10::InitAuthType(napi_env env, napi_value value)
145 {
146     bool isArray = false;
147     napi_is_array(env, value, &isArray);
148     if (!isArray) {
149         IAM_LOGI("authType is not array");
150         std::string msgStr = "Parameter error. The type of \"authType\" must be array.";
151         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
152     }
153     uint32_t length = 0;
154     napi_get_array_length(env, value, &length);
155     for (uint32_t i = 0; i < length; ++i) {
156         napi_value jsValue = nullptr;
157         napi_handle_scope scope = nullptr;
158         napi_open_handle_scope(env, &scope);
159         napi_get_element(env, value, i, &jsValue);
160         if (jsValue == nullptr) {
161             napi_close_handle_scope(env, scope);
162             continue;
163         }
164         int32_t value = 0;
165         napi_status ret = UserAuthNapiHelper::GetInt32Value(env, jsValue, value);
166         napi_close_handle_scope(env, scope);
167         if (ret != napi_ok) {
168             IAM_LOGE("napi authType GetUint32Value fail:%{public}d", ret);
169             std::string msgStr = "Parameter error. The type of \"authType\" must be number.";
170             return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
171         }
172         IAM_LOGI("napi get authType:%{public}d", value);
173         if (!UserAuthNapiHelper::CheckUserAuthType(value)) {
174             IAM_LOGE("authType is illegal, %{public}d", value);
175             return UserAuthResultCode::TYPE_NOT_SUPPORT;
176         }
177         auto iter = std::find(authParam_.authTypes.begin(), authParam_.authTypes.end(), static_cast<AuthType>(value));
178         if (iter != authParam_.authTypes.end()) {
179             IAM_LOGE("napi authType:%{public}d exist", value);
180             std::string msgStr = "Parameter error. The type of \"authType\" must be AuthType.";
181             return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
182         }
183         authParam_.authTypes.push_back(static_cast<AuthType>(value));
184     }
185 
186     IAM_LOGI("authType size:%{public}zu", authParam_.authTypes.size());
187     return UserAuthResultCode::SUCCESS;
188 }
189 
InitAuthTrustLevel(napi_env env,napi_value value)190 UserAuthResultCode UserAuthInstanceV10::InitAuthTrustLevel(napi_env env, napi_value value)
191 {
192     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
193     if (ret == napi_ok) {
194         IAM_LOGI("authTrustLevel is null");
195         std::string msgStr = "Parameter error. The type of \"authTrustLevel\" must be number.";
196         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
197     }
198     uint32_t authTrustLevel;
199     ret = UserAuthNapiHelper::GetUint32Value(env, value, authTrustLevel);
200     if (ret != napi_ok) {
201         IAM_LOGE("GetUint32Value fail:%{public}d", ret);
202         std::string msgStr = "Parameter error. The type of \"authTrustLevel\" must be number.";
203         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
204     }
205     if (!UserAuthNapiHelper::CheckAuthTrustLevel(authTrustLevel)) {
206         IAM_LOGE("AuthTrustLevel fail:%{public}u", authTrustLevel);
207         return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
208     }
209     authParam_.authTrustLevel = AuthTrustLevel(authTrustLevel);
210     IAM_LOGI("authTrustLevel:%{public}u", authParam_.authTrustLevel);
211     return UserAuthResultCode::SUCCESS;
212 }
213 
InitReuseUnlockResult(napi_env env,napi_value value)214 UserAuthResultCode UserAuthInstanceV10::InitReuseUnlockResult(napi_env env, napi_value value)
215 {
216     uint32_t reuseMode;
217     uint32_t reuseDuration;
218     if (!UserAuthNapiHelper::HasNamedProperty(env, value, REUSEMODE)) {
219         IAM_LOGE("propertyName: %{public}s not exists.", REUSEMODE.c_str());
220         std::string msgStr = "Parameter error. \"reuseMode\" is a mandatory parameter and is left unspecified.";
221         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
222     }
223     napi_value napi_reuseMode = UserAuthNapiHelper::GetNamedProperty(env, value, REUSEMODE);
224     napi_status ret = UserAuthNapiHelper::GetUint32Value(env, napi_reuseMode, reuseMode);
225     if (ret != napi_ok) {
226         IAM_LOGE("GetUint32Value fail:%{public}d", ret);
227         std::string msgStr = "Parameter error. The type of \"reuseMode\" must be number.";
228         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
229     }
230     authParam_.reuseUnlockResult.reuseMode = ReuseMode(reuseMode);
231     if (!UserAuthNapiHelper::HasNamedProperty(env, value, REUSEDURATION)) {
232         IAM_LOGE("propertyName: %{public}s not exists.", REUSEDURATION.c_str());
233         std::string msgStr = "Parameter error. \"reuseDuration\" is a mandatory parameter and is left unspecified.";
234         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
235     }
236     napi_value napi_reuseDuration = UserAuthNapiHelper::GetNamedProperty(env, value, REUSEDURATION);
237     ret = UserAuthNapiHelper::GetUint32Value(env, napi_reuseDuration, reuseDuration);
238     if (ret != napi_ok) {
239         IAM_LOGE("GetUint32Value fail:%{public}d", ret);
240         std::string msgStr = "Parameter error. The type of \"reuseDuration\" must be number.";
241         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
242     }
243     authParam_.reuseUnlockResult.reuseDuration = reuseDuration;
244     if (!UserAuthNapiHelper::CheckReuseUnlockResult(authParam_.reuseUnlockResult)) {
245         IAM_LOGE("ReuseUnlockResult fail");
246         std::string msgStr = "Parameter error. The type of \"reuseUnlockResult\" must be ReuseUnlockResult.";
247         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
248     }
249     authParam_.reuseUnlockResult.isReuse = true;
250     IAM_LOGI("reuseMode: %{public}u, reuseDuration: %{public}" PRIu64, authParam_.reuseUnlockResult.reuseMode,
251         authParam_.reuseUnlockResult.reuseDuration);
252     return UserAuthResultCode::SUCCESS;
253 }
254 
InitAuthParam(napi_env env,napi_value value)255 UserAuthResultCode UserAuthInstanceV10::InitAuthParam(napi_env env, napi_value value)
256 {
257     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
258     if (ret == napi_ok) {
259         IAM_LOGI("authParam is null");
260         std::string msgStr = "Parameter error. \"authParam\" is a mandatory parameter and is left unspecified.";
261         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
262     }
263 
264     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_CHALLENGE)) {
265         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_CHALLENGE.c_str());
266         std::string msgStr = "Parameter error. \"challenge\" is a mandatory parameter and is left unspecified.";
267         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
268     }
269     napi_value napi_challenge = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_CHALLENGE);
270     UserAuthResultCode errorCode = InitChallenge(env, napi_challenge);
271     if (errorCode != UserAuthResultCode::SUCCESS) {
272         IAM_LOGE("InitChallenge fail:%{public}d", errorCode);
273         return UserAuthResultCode::OHOS_INVALID_PARAM;
274     }
275 
276     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_AUTHTYPE)) {
277         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_AUTHTYPE.c_str());
278         std::string msgStr = "Parameter error. \"authType\" is a mandatory parameter and is left unspecified.";
279         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
280     }
281     napi_value napi_authType = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_AUTHTYPE);
282     errorCode = InitAuthType(env, napi_authType);
283     if (errorCode != UserAuthResultCode::SUCCESS) {
284         IAM_LOGE("InitAuthType fail:%{public}d", errorCode);
285         return errorCode;
286     }
287 
288     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_AUTHTRUSTLEVEL)) {
289         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_AUTHTRUSTLEVEL.c_str());
290         std::string msgStr = "Parameter error. \"authTrustLevel\" is a mandatory parameter and is left unspecified.";
291         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
292     }
293     napi_value napi_authTrustLevel = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_AUTHTRUSTLEVEL);
294     errorCode = InitAuthTrustLevel(env, napi_authTrustLevel);
295     if (errorCode != UserAuthResultCode::SUCCESS) {
296         IAM_LOGE("InitAuthTrustLevel fail:%{public}d", errorCode);
297         return errorCode;
298     }
299     errorCode = ProcessReuseUnlockResult(env, value);
300     if (errorCode != UserAuthResultCode::SUCCESS) {
301         return errorCode;
302     }
303     return UserAuthResultCode::SUCCESS;
304 }
305 
ProcessReuseUnlockResult(napi_env env,napi_value value)306 UserAuthResultCode UserAuthInstanceV10::ProcessReuseUnlockResult(napi_env env, napi_value value)
307 {
308     if (UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_REUSEUNLOCKRESULT)) {
309         napi_value napi_reuseUnlockResult = UserAuthNapiHelper::GetNamedProperty(env, value,
310             AUTH_PARAM_REUSEUNLOCKRESULT);
311         UserAuthResultCode errorCode = InitReuseUnlockResult(env, napi_reuseUnlockResult);
312         if (errorCode != UserAuthResultCode::SUCCESS) {
313             IAM_LOGE("InitReuseUnlockResult fail:%{public}d", errorCode);
314             return errorCode;
315         }
316     } else {
317         authParam_.reuseUnlockResult.isReuse = false;
318     }
319     return UserAuthResultCode::SUCCESS;
320 }
321 
InitWidgetParam(napi_env env,napi_value value)322 UserAuthResultCode UserAuthInstanceV10::InitWidgetParam(napi_env env, napi_value value)
323 {
324     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
325     if (ret == napi_ok) {
326         IAM_LOGE("widgetParam is null");
327         std::string msgStr = "Parameter error. \"widgetParam\" is a mandatory parameter and is left unspecified.";
328         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
329     }
330 
331     if (!UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_TITLE)) {
332         IAM_LOGE("propertyName: %{public}s not exists.", WIDGET_PARAM_TITLE.c_str());
333         std::string msgStr = "Parameter error. \"title\" is a mandatory parameter and is left unspecified.";
334         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
335     }
336     std::string title = UserAuthNapiHelper::GetStringPropertyUtf8(env, value, WIDGET_PARAM_TITLE);
337     if (title == "" || title.length() > WidgetType::TITLE_MAX) {
338         IAM_LOGE("title is invalid. size: %{public}zu", title.length());
339         std::string msgStr = "Parameter error. The length of \"title\" connot exceed 500.";
340         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
341     }
342     widgetParam_.title = title;
343 
344     if (UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_NAVIBTNTEXT)) {
345         std::string naviBtnTxt = UserAuthNapiHelper::GetStringPropertyUtf8(env, value, WIDGET_PARAM_NAVIBTNTEXT);
346         if (naviBtnTxt == "" || naviBtnTxt.length() > WidgetType::BUTTON_MAX) {
347             IAM_LOGE("navigation button text is invalid, size: %{public}zu", naviBtnTxt.length());
348             std::string msgStr = "Parameter error. The length of \"navigationButtonText\" connot exceed 60.";
349             return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
350         }
351         widgetParam_.navigationButtonText = naviBtnTxt;
352     }
353 
354     UserAuthResultCode errorCode = ProcessWindowMode(env, value);
355     if (errorCode != UserAuthResultCode::SUCCESS) {
356         return errorCode;
357     }
358     return UserAuthResultCode::SUCCESS;
359 }
360 
ProcessWindowMode(napi_env env,napi_value value)361 UserAuthResultCode UserAuthInstanceV10::ProcessWindowMode(napi_env env, napi_value value)
362 {
363     if (UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_WINDOWMODE)) {
364         napi_value napi_windowModeType = UserAuthNapiHelper::GetNamedProperty(env, value, WIDGET_PARAM_WINDOWMODE);
365         uint32_t windowMode;
366         napi_status ret = UserAuthNapiHelper::GetUint32Value(env, napi_windowModeType, windowMode);
367         if (ret != napi_ok) {
368             IAM_LOGE("napi authType GetUint32Value fail:%{public}d", ret);
369             std::string msgStr = "Parameter error. The type of \"windowMode\" must be number.";
370             return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
371         }
372         switch (windowMode) {
373             case WindowModeType::DIALOG_BOX:
374             case WindowModeType::FULLSCREEN:
375                 widgetParam_.windowMode = static_cast<WindowModeType>(windowMode);
376                 break;
377             default:
378                 IAM_LOGE("windowMode type not support.");
379                 std::string msgStr = "Parameter error. The type of \"windowMode\" must be WindowModeType.";
380                 return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
381         }
382     }
383 
384     IAM_LOGI("widgetParam title:%{public}s, navBtnText:%{public}s, winMode:%{public}u",
385         widgetParam_.title.c_str(), widgetParam_.navigationButtonText.c_str(),
386         static_cast<uint32_t>(widgetParam_.windowMode));
387     return UserAuthResultCode::SUCCESS;
388 }
389 
Init(napi_env env,napi_callback_info info)390 UserAuthResultCode UserAuthInstanceV10::Init(napi_env env, napi_callback_info info)
391 {
392     if (callback_ == nullptr) {
393         IAM_LOGE("callback is null");
394         return UserAuthResultCode::GENERAL_ERROR;
395     }
396     napi_value argv[ARGS_TWO];
397     size_t argc = ARGS_TWO;
398     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
399     if (ret != napi_ok) {
400         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
401         return UserAuthResultCode::GENERAL_ERROR;
402     }
403     if (argc != ARGS_TWO) {
404         IAM_LOGE("invalid param, argc:%{public}zu", argc);
405         std::string msgStr = "Invalid authentication parameters. The number of parameters should be 2";
406         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
407     }
408 
409     UserAuthResultCode errCode = InitAuthParam(env, argv[PARAM0]);
410     if (errCode != UserAuthResultCode::SUCCESS) {
411         IAM_LOGE("AuthParamInner type error, errorCode: %{public}d", errCode);
412         return errCode;
413     }
414 
415     errCode = InitWidgetParam(env, argv[PARAM1]);
416     if (errCode != UserAuthResultCode::SUCCESS) {
417         IAM_LOGE("WidgetParam type error, errorCode: %{public}d", errCode);
418         return errCode;
419     }
420 
421     IAM_LOGE("Init SUCCESS");
422     return UserAuthResultCode::SUCCESS;
423 }
424 
GetCallback(napi_env env,napi_value value)425 std::shared_ptr<JsRefHolder> UserAuthInstanceV10::GetCallback(napi_env env, napi_value value)
426 {
427     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_object);
428     if (ret != napi_ok) {
429         IAM_LOGE("CheckNapiType fail:%{public}d", ret);
430         return nullptr;
431     }
432     napi_value callbackValue;
433     ret = napi_get_named_property(env, value, "onResult", &callbackValue);
434     if (ret != napi_ok) {
435         IAM_LOGE("napi_get_named_property fail:%{public}d", ret);
436         return nullptr;
437     }
438     return Common::MakeShared<JsRefHolder>(env, callbackValue);
439 }
440 
On(napi_env env,napi_callback_info info)441 UserAuthResultCode UserAuthInstanceV10::On(napi_env env, napi_callback_info info)
442 {
443     if (callback_ == nullptr) {
444         IAM_LOGE("getAuthInstance on callback is null");
445         return UserAuthResultCode::GENERAL_ERROR;
446     }
447     napi_value argv[ARGS_TWO];
448     size_t argc = ARGS_TWO;
449     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
450     if (ret != napi_ok) {
451         IAM_LOGE("getAuthInstance on napi_get_cb_info fail:%{public}d", ret);
452         return UserAuthResultCode::GENERAL_ERROR;
453     }
454     if (argc != ARGS_TWO) {
455         IAM_LOGE("getAuthInstance on invalid param, argc:%{public}zu", argc);
456         std::string msgStr = "Parameter error. The number of parameters should be 2";
457         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
458     }
459     static const size_t maxLen = 10;
460     char str[maxLen] = {0};
461     size_t len = maxLen;
462     ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
463     if (ret != napi_ok) {
464         IAM_LOGE("getAuthInstance on GetStrValue fail:%{public}d", ret);
465         std::string msgStr = "Parameter error. The type of \"type\" must be string.";
466         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
467     }
468     auto callbackRef = GetCallback(env, argv[PARAM1]);
469     if (callbackRef == nullptr || !callbackRef->IsValid()) {
470         IAM_LOGE("getAuthInstance on GetCallback fail");
471         std::string msgStr = "Parameter error. The type of \"callback\" must be IAuthCallback.";
472         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
473     }
474     if (str == AUTH_EVENT_RESULT) {
475         IAM_LOGI("getAuthInstance on SetResultCallback");
476         if (callback_->HasResultCallback()) {
477             IAM_LOGE("callback has been registerred");
478             return UserAuthResultCode::GENERAL_ERROR;
479         }
480         callback_->SetResultCallback(callbackRef);
481         return UserAuthResultCode::SUCCESS;
482     } else {
483         IAM_LOGE("getAuthInstance on invalid event:%{public}s", str);
484         std::string msgStr = "Parameter error. The value of \"type\" must be \"result\".";
485         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
486     }
487 }
488 
Off(napi_env env,napi_callback_info info)489 UserAuthResultCode UserAuthInstanceV10::Off(napi_env env, napi_callback_info info)
490 {
491     if (callback_ == nullptr) {
492         IAM_LOGE("userAuthInstance off callback is null");
493         return UserAuthResultCode::GENERAL_ERROR;
494     }
495     napi_value argv[ARGS_TWO];
496     size_t argc = ARGS_TWO;
497     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
498     if (ret != napi_ok) {
499         IAM_LOGE("userAuthInstance off napi_get_cb_info fail:%{public}d", ret);
500         return UserAuthResultCode::GENERAL_ERROR;
501     }
502     if (argc != ARGS_TWO && argc != ARGS_ONE) {
503         IAM_LOGE("userAuthInstance off invalid param, argc:%{public}zu", argc);
504         std::string msgStr = "Parameter error. The number of parameters should be 1 or 2";
505         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
506     }
507     static const size_t maxLen = 10;
508     char str[maxLen] = {0};
509     size_t len = maxLen;
510     ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
511     if (ret != napi_ok) {
512         IAM_LOGE("UserAuthResultCode off GetStrValue fail:%{public}d", ret);
513         std::string msgStr = "Parameter error. The type of \"type\" must be string.";
514         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
515     }
516 
517     if (argc == ARGS_TWO) {
518         auto callbackRef = GetCallback(env, argv[PARAM1]);
519         if (callbackRef == nullptr || !callbackRef->IsValid()) {
520             IAM_LOGE("GetCallback fail");
521             std::string msgStr = "Parameter error. The type of \"callback\" must be IAuthCallback.";
522             return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
523         }
524     }
525 
526     if (str == AUTH_EVENT_RESULT) {
527         if (!callback_->HasResultCallback()) {
528             IAM_LOGE("no callback registerred yet");
529             return UserAuthResultCode::GENERAL_ERROR;
530         }
531         callback_->ClearResultCallback();
532         IAM_LOGI("UserAuthResultCode off clear result callback");
533         return UserAuthResultCode::SUCCESS;
534     } else {
535         IAM_LOGE("invalid event:%{public}s", str);
536         std::string msgStr = "Parameter error. The value of \"type\" must be \"result\".";
537         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
538     }
539 }
540 
Start(napi_env env,napi_callback_info info)541 UserAuthResultCode UserAuthInstanceV10::Start(napi_env env, napi_callback_info info)
542 {
543     if (callback_ == nullptr) {
544         IAM_LOGE("callback is null");
545         return UserAuthResultCode::GENERAL_ERROR;
546     }
547     napi_value argv[ARGS_ONE];
548     size_t argc = ARGS_ONE;
549     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
550     if (ret != napi_ok) {
551         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
552         return UserAuthResultCode::GENERAL_ERROR;
553     }
554     if (argc != ARGS_ZERO) {
555         IAM_LOGE("invalid param, argc:%{public}zu", argc);
556         std::string msgStr = "Parameter error. The number of parameters should be 0";
557         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
558     }
559     std::lock_guard<std::mutex> guard(mutex_);
560     if (isAuthStarted_) {
561         IAM_LOGE("auth already started");
562         return UserAuthResultCode::GENERAL_ERROR;
563     }
564     contextId_ = UserAuthClientImpl::Instance().BeginWidgetAuth(API_VERSION_10,
565         authParam_, widgetParam_, callback_);
566     isAuthStarted_ = true;
567     return UserAuthResultCode::SUCCESS;
568 }
569 
Cancel(napi_env env,napi_callback_info info)570 UserAuthResultCode UserAuthInstanceV10::Cancel(napi_env env, napi_callback_info info)
571 {
572     if (callback_ == nullptr) {
573         IAM_LOGE("callback is null");
574         return UserAuthResultCode::GENERAL_ERROR;
575     }
576     napi_value argv[ARGS_ONE];
577     size_t argc = ARGS_ONE;
578     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
579     if (ret != napi_ok) {
580         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
581         return UserAuthResultCode::GENERAL_ERROR;
582     }
583     if (argc != ARGS_ZERO) {
584         IAM_LOGE("invalid param, argc:%{public}zu", argc);
585         std::string msgStr = "Parameter error. The number of parameters should be 0";
586         return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
587     }
588     std::lock_guard<std::mutex> guard(mutex_);
589     if (!isAuthStarted_) {
590         IAM_LOGE("auth not started");
591         return UserAuthResultCode::GENERAL_ERROR;
592     }
593     int32_t result = UserAuthClient::GetInstance().CancelAuthentication(contextId_);
594     if (result != ResultCode::SUCCESS) {
595         IAM_LOGE("CancelAuthentication fail:%{public}d", result);
596         return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV10(result));
597     }
598     isAuthStarted_ = false;
599     return UserAuthResultCode::SUCCESS;
600 }
601 } // namespace UserAuth
602 } // namespace UserIam
603 } // namespace OHOS
604