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