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