1 /*
2 * Copyright (c) 2021-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 #include "napi_app_account_common.h"
16 #include "account_error_no.h"
17 #include "account_log_wrapper.h"
18 #include "app_account_constants.h"
19 #include "app_account_manager.h"
20 #include "napi_common.h"
21
22 namespace OHOS {
23 namespace AccountJsKit {
24 using namespace OHOS::AccountSA;
25 static const std::int32_t SUBSCRIBE_MAX_PARA = 3;
26 static const std::int32_t UNSUBSCRIBE_MAX_PARA = 2;
27
28 static const std::string ErrMsgList[] = {
29 "Parameter error. The type of \"name\" must be string", // index equals to PropertyType::NAME value
30 "Parameter error. The type of \"owner\" must be string", // index equals to PropertyType::OWNER value
31 "Parameter error. The type of \"authType\" must be string", // index equals to PropertyType::AUTH_TYPE value
32 "Parameter error. The type of \"bundleName\" must be string", // index equals to PropertyType::BUNDLE_NAME value
33 "Parameter error. The type of \"sessionId\" must be string", // index equals to PropertyType::SESSION_ID value
34 "Parameter error. The type of \"isVisible\" must be bool", // index equals to PropertyType::IS_VISIBLE value
35 "Parameter error. The type of \"token\" must be string", // index equals to PropertyType::TOKEN value
36 "Parameter error. The type of \"extraInfo\" must be string", // index equals to PropertyType::EXTRA_INFO value
37 "Parameter error. The type of \"credentialType\" must be string", // index equals to PropertyType::CREDENTIAL_TYPE
38 // value
39 "Parameter error. The type of \"credential\" must be string", // index equals to PropertyType::CREDENTIAL value
40 "Parameter error. The type of \"key\" must be string", // index equals to PropertyType::KEY value
41 "Parameter error. The type of \"value\" must be string", // index equals to PropertyType::VALUE value
42 "Parameter error. The type of \"isAccessible\" must be bool", // index equals to PropertyType::IS_ACCESSIBLE
43 // value
44 "Parameter error. The type of \"isEnable\" must be bool", // index equals to PropertyType::IS_ENABLE value
45 };
46
47 std::mutex g_lockForAppAccountSubscribers;
48 std::map<AppAccountManager *, std::vector<AsyncContextForSubscribe *>> g_AppAccountSubscribers;
49
SubscriberPtr(const AppAccountSubscribeInfo & subscribeInfo)50 SubscriberPtr::SubscriberPtr(const AppAccountSubscribeInfo &subscribeInfo) : AppAccountSubscriber(subscribeInfo)
51 {}
52
OnAppAccountsChangedWork(const std::shared_ptr<SubscriberAccountsWorker> & data)53 static std::function<void()> OnAppAccountsChangedWork(const std::shared_ptr<SubscriberAccountsWorker> &data)
54 {
55 return [data = data] {
56 ACCOUNT_LOGI("Enter OnAppAccountsChangedWork");
57 napi_handle_scope scope = nullptr;
58 napi_open_handle_scope(data->env, &scope);
59 if (scope == nullptr) {
60 ACCOUNT_LOGE("Fail to open scope");
61 return;
62 }
63 bool isFound = false;
64 {
65 std::lock_guard<std::mutex> lock(g_lockForAppAccountSubscribers);
66 SubscriberPtr *subscriber = data->subscriber;
67 for (auto objectInfoTmp : g_AppAccountSubscribers) {
68 isFound = std::any_of(objectInfoTmp.second.begin(), objectInfoTmp.second.end(),
69 [subscriber](const AsyncContextForSubscribe *item) {
70 return item->subscriber.get() == subscriber;
71 });
72 if (isFound) {
73 ACCOUNT_LOGD("AppAccount subscriber has been found.");
74 break;
75 }
76 }
77 }
78 if (isFound) {
79 napi_value results[ARGS_SIZE_ONE] = { nullptr };
80 GetAppAccountInfoForResult(data->env, data->accounts, results[0]);
81 NapiCallVoidFunction(data->env, results, ARGS_SIZE_ONE, data->ref);
82 }
83 napi_close_handle_scope(data->env, scope);
84 };
85 }
86
OnAccountsChanged(const std::vector<AppAccountInfo> & accounts_)87 void SubscriberPtr::OnAccountsChanged(const std::vector<AppAccountInfo> &accounts_)
88 {
89 std::shared_ptr<SubscriberAccountsWorker> worker = std::make_shared<SubscriberAccountsWorker>(env_);
90 if (worker == nullptr) {
91 ACCOUNT_LOGE("SubscriberAccountsWorker is null");
92 return;
93 }
94
95 worker->accounts = accounts_;
96 worker->ref = ref_;
97 worker->subscriber = this;
98
99 if (napi_ok != napi_send_event(env_, OnAppAccountsChangedWork(worker), napi_eprio_vip)) {
100 ACCOUNT_LOGE("Post task failed");
101 return;
102 }
103 ACCOUNT_LOGI("Post task finish");
104 }
105
SetEnv(const napi_env & env)106 void SubscriberPtr::SetEnv(const napi_env &env)
107 {
108 env_ = env;
109 }
110
SetCallbackRef(const napi_ref & ref)111 void SubscriberPtr::SetCallbackRef(const napi_ref &ref)
112 {
113 ref_ = ref;
114 }
115
CheckAccountLabelsOnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> & param)116 std::function<void()> CheckAccountLabelsOnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> ¶m)
117 {
118 return [data = param] {
119 ACCOUNT_LOGI("Enter CheckAccountLabelsOnResultWork");
120 napi_handle_scope scope = nullptr;
121 napi_open_handle_scope(data->env, &scope);
122 if (scope == nullptr) {
123 ACCOUNT_LOGE("Fail to open scope");
124 return;
125 }
126 napi_env env = data->env;
127 napi_value checkResult[RESULT_COUNT] = { NapiGetNull(env) };
128 if (data->errCode == ERR_JS_SUCCESS) {
129 bool hasLabels = data->result.GetBoolParam(Constants::KEY_BOOLEAN_RESULT, false);
130 napi_get_boolean(env, hasLabels, &checkResult[PARAMONE]);
131 } else {
132 checkResult[PARAMZERO] = GetErrorCodeValue(env, data->errCode);
133 }
134 ProcessCallbackOrPromise(env, data.get(), checkResult[PARAMZERO], checkResult[PARAMONE]);
135 napi_close_handle_scope(env, scope);
136 };
137 }
138
CreateJSAppAccountInfo(napi_env env,const std::string & name,const std::string & owner)139 static napi_value CreateJSAppAccountInfo(napi_env env, const std::string &name, const std::string &owner)
140 {
141 napi_value object = nullptr;
142 NAPI_CALL(env, napi_create_object(env, &object));
143 napi_value value = nullptr;
144 NAPI_CALL(env, napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &value));
145 NAPI_CALL(env, napi_set_named_property(env, object, "name", value));
146 NAPI_CALL(env, napi_create_string_utf8(env, owner.c_str(), NAPI_AUTO_LENGTH, &value));
147 NAPI_CALL(env, napi_set_named_property(env, object, "owner", value));
148 return object;
149 }
150
SelectAccountsOnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> & param)151 std::function<void()> SelectAccountsOnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> ¶m)
152 {
153 return [param = param] {
154 ACCOUNT_LOGI("Enter SelectAccountsOnResultWork");
155 napi_handle_scope scope = nullptr;
156 napi_open_handle_scope(param->env, &scope);
157 if (scope == nullptr) {
158 ACCOUNT_LOGE("Fail to open scope");
159 return;
160 }
161 std::vector<std::string> names = param->result.GetStringArrayParam(Constants::KEY_ACCOUNT_NAMES);
162 std::vector<std::string> owners = param->result.GetStringArrayParam(Constants::KEY_ACCOUNT_OWNERS);
163 if (names.size() != owners.size()) {
164 param->errCode = ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION;
165 }
166 napi_env env = param->env;
167 napi_value selectResult[RESULT_COUNT] = { 0 };
168 if (param->errCode == ERR_JS_SUCCESS) {
169 napi_create_array(env, &selectResult[PARAMONE]);
170 for (size_t i = 0; i < names.size(); ++i) {
171 napi_value object = CreateJSAppAccountInfo(env, names[i], owners[i]);
172 napi_set_element(env, selectResult[PARAMONE], i, object);
173 }
174 } else {
175 selectResult[PARAMZERO] = GetErrorCodeValue(env, param->errCode);
176 }
177 ProcessCallbackOrPromise(env, param.get(), selectResult[PARAMZERO], selectResult[PARAMONE]);
178 napi_close_handle_scope(env, scope);
179 };
180 }
181
AuthenticatorAsyncCallback(napi_env env,std::shared_ptr<NapiCallbackRef> callback,napi_deferred deferred,std::function<std::function<void ()> (const std::shared_ptr<AuthenticatorCallbackParam> &)> workCb)182 AuthenticatorAsyncCallback::AuthenticatorAsyncCallback(
183 napi_env env, std::shared_ptr<NapiCallbackRef> callback, napi_deferred deferred,
184 std::function<std::function<void()>(const std::shared_ptr<AuthenticatorCallbackParam> &)> workCb)
185 : env_(env), callbackRef_(callback), deferred_(deferred), workCb_(workCb)
186 {}
187
~AuthenticatorAsyncCallback()188 AuthenticatorAsyncCallback::~AuthenticatorAsyncCallback()
189 {}
190
OnResult(int32_t resultCode,const AAFwk::Want & result)191 ErrCode AuthenticatorAsyncCallback::OnResult(int32_t resultCode, const AAFwk::Want &result)
192 {
193 {
194 std::lock_guard<std::mutex> lock(mutex_);
195 if (isDone) {
196 return ERR_OK;
197 }
198 isDone = true;
199 }
200 std::shared_ptr<AuthenticatorCallbackParam> param = std::make_shared<AuthenticatorCallbackParam>(callbackRef_);
201 param->env = env_;
202 param->deferred = deferred_;
203 param->errCode = resultCode;
204 param->result = result;
205 if (napi_ok == napi_send_event(env_, workCb_(param), napi_eprio_vip)) {
206 ACCOUNT_LOGI("Post task finish");
207 return ERR_OK;
208 }
209 ACCOUNT_LOGE("Post task failed");
210 return ERR_OK;
211 }
212
OnRequestRedirected(const AAFwk::Want & request)213 ErrCode AuthenticatorAsyncCallback::OnRequestRedirected(const AAFwk::Want &request)
214 {
215 return ERR_OK;
216 }
217
OnRequestContinued()218 ErrCode AuthenticatorAsyncCallback::OnRequestContinued()
219 {
220 return ERR_OK;
221 }
222
CallbackEnter(uint32_t code)223 ErrCode AuthenticatorAsyncCallback::CallbackEnter([[maybe_unused]] uint32_t code)
224 {
225 return ERR_OK;
226 }
227
CallbackExit(uint32_t code,int32_t result)228 ErrCode AuthenticatorAsyncCallback::CallbackExit([[maybe_unused]] uint32_t code, [[maybe_unused]] int32_t result)
229 {
230 switch (code) {
231 case static_cast<uint32_t>(IAppAccountAuthenticatorCallbackIpcCode::COMMAND_ON_RESULT): {
232 if (result == ERR_INVALID_DATA) {
233 AAFwk::Want resultWant;
234 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, resultWant);
235 return ERR_APPACCOUNT_SERVICE_OAUTH_INVALID_RESPONSE;
236 }
237 break;
238 }
239 case static_cast<uint32_t>(IAppAccountAuthenticatorCallbackIpcCode::COMMAND_ON_REQUEST_REDIRECTED): {
240 if (result == ERR_INVALID_DATA) {
241 AAFwk::Want request;
242 OnRequestRedirected(request);
243 return ERR_APPACCOUNT_SERVICE_OAUTH_INVALID_RESPONSE;
244 }
245 break;
246 }
247 default:
248 return ERR_NONE;
249 }
250 return ERR_NONE;
251 }
252
AppAccountManagerCallback(napi_env env,JSAuthCallback callback)253 AppAccountManagerCallback::AppAccountManagerCallback(napi_env env, JSAuthCallback callback)
254 : env_(env), callback_(callback)
255 {}
256
~AppAccountManagerCallback()257 AppAccountManagerCallback::~AppAccountManagerCallback()
258 {}
259
OnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> & param)260 static std::function<void()> OnResultWork(const std::shared_ptr<AuthenticatorCallbackParam> ¶m)
261 {
262 return [data = param] {
263 ACCOUNT_LOGI("Enter OnResultWork");
264 napi_handle_scope scope = nullptr;
265 napi_env env = data->authCallback.onResult->env;
266 napi_open_handle_scope(env, &scope);
267 if (scope == nullptr) {
268 ACCOUNT_LOGE("Fail to open scope");
269 return;
270 }
271 ProcessOnResultCallback(env, data->authCallback, data->resultCode, data->result.GetParams());
272 napi_close_handle_scope(env, scope);
273 };
274 }
275
OnRequestRedirectedWork(const std::shared_ptr<AuthenticatorCallbackParam> & param)276 static std::function<void()> OnRequestRedirectedWork(const std::shared_ptr<AuthenticatorCallbackParam> ¶m)
277 {
278 return [data = param] {
279 ACCOUNT_LOGI("Enter OnRequestRedirectedWork");
280 napi_handle_scope scope = nullptr;
281 napi_env env = data->authCallback.onRequestRedirected->env;
282 napi_open_handle_scope(env, &scope);
283 if (scope == nullptr) {
284 ACCOUNT_LOGE("Fail to open scope");
285 return;
286 }
287 napi_value results[ARGS_SIZE_ONE] = { AppExecFwk::WrapWant(env, data->request) };
288 NapiCallVoidFunction(env, results, ARGS_SIZE_ONE, data->authCallback.onRequestRedirected->callbackRef);
289 napi_close_handle_scope(env, scope);
290 };
291 }
292
OnRequestContinuedWork(const std::shared_ptr<AuthenticatorCallbackParam> & param)293 static std::function<void()> OnRequestContinuedWork(const std::shared_ptr<AuthenticatorCallbackParam> ¶m)
294 {
295 return [data = param] {
296 ACCOUNT_LOGI("Enter OnRequestContinuedWork");
297 napi_handle_scope scope = nullptr;
298 napi_env env = data->authCallback.onRequestContinued->env;
299 napi_open_handle_scope(env, &scope);
300 if (scope == nullptr) {
301 ACCOUNT_LOGE("Fail to open scope");
302 return;
303 }
304 NapiCallVoidFunction(env, nullptr, 0, data->authCallback.onRequestContinued->callbackRef);
305 napi_close_handle_scope(env, scope);
306 };
307 }
308
OnResult(int32_t resultCode,const AAFwk::Want & result)309 ErrCode AppAccountManagerCallback::OnResult(int32_t resultCode, const AAFwk::Want &result)
310 {
311 {
312 std::lock_guard<std::mutex> lock(mutex_);
313 if (isDone) {
314 return ERR_OK;
315 }
316 isDone = true;
317 }
318 if (callback_.onResult == nullptr) {
319 ACCOUNT_LOGE("onResult is null");
320 return ERR_OK;
321 }
322 std::shared_ptr<AuthenticatorCallbackParam> param = std::make_shared<AuthenticatorCallbackParam>(callback_);
323 param->resultCode = resultCode;
324 param->result = result;
325 if (napi_ok != napi_send_event(env_, OnResultWork(param), napi_eprio_vip)) {
326 ACCOUNT_LOGE("Post task failed");
327 return ERR_OK;
328 }
329 ACCOUNT_LOGI("Post task finish");
330 return ERR_OK;
331 }
332
OnRequestRedirected(const AAFwk::Want & request)333 ErrCode AppAccountManagerCallback::OnRequestRedirected(const AAFwk::Want &request)
334 {
335 if (callback_.onRequestRedirected == nullptr) {
336 ACCOUNT_LOGE("onRequestRedirected is null");
337 return ERR_OK;
338 }
339 std::shared_ptr<AuthenticatorCallbackParam> param = std::make_shared<AuthenticatorCallbackParam>(callback_);
340 param->request = request;
341 if (napi_ok != napi_send_event(env_, OnRequestRedirectedWork(param), napi_eprio_vip)) {
342 ACCOUNT_LOGE("Post task failed");
343 return ERR_OK;
344 }
345 ACCOUNT_LOGI("Post task finish");
346 return ERR_OK;
347 }
348
OnRequestContinued()349 ErrCode AppAccountManagerCallback::OnRequestContinued()
350 {
351 if (callback_.onRequestContinued == nullptr) {
352 ACCOUNT_LOGE("OnRequestContinued is null");
353 return ERR_OK;
354 }
355 std::shared_ptr<AuthenticatorCallbackParam> param = std::make_shared<AuthenticatorCallbackParam>(callback_);
356 if (napi_ok != napi_send_event(env_, OnRequestContinuedWork(param), napi_eprio_vip)) {
357 ACCOUNT_LOGE("Post task failed");
358 return ERR_OK;
359 }
360 ACCOUNT_LOGI("Post task finish");
361 return ERR_OK;
362 }
363
CallbackEnter(uint32_t code)364 ErrCode AppAccountManagerCallback::CallbackEnter([[maybe_unused]] uint32_t code)
365 {
366 return ERR_OK;
367 }
368
CallbackExit(uint32_t code,int32_t result)369 ErrCode AppAccountManagerCallback::CallbackExit([[maybe_unused]] uint32_t code, [[maybe_unused]] int32_t result)
370 {
371 switch (code) {
372 case static_cast<uint32_t>(IAppAccountAuthenticatorCallbackIpcCode::COMMAND_ON_RESULT): {
373 if (result == ERR_INVALID_DATA) {
374 AAFwk::Want resultWant;
375 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, resultWant);
376 return ERR_APPACCOUNT_SERVICE_OAUTH_INVALID_RESPONSE;
377 }
378 break;
379 }
380 case static_cast<uint32_t>(IAppAccountAuthenticatorCallbackIpcCode::COMMAND_ON_REQUEST_REDIRECTED): {
381 if (result == ERR_INVALID_DATA) {
382 AAFwk::Want request;
383 OnRequestRedirected(request);
384 return ERR_APPACCOUNT_SERVICE_OAUTH_INVALID_RESPONSE;
385 }
386 break;
387 }
388 default:
389 return ERR_NONE;
390 }
391 return ERR_NONE;
392 }
393
NapiGetNull(napi_env env)394 napi_value NapiGetNull(napi_env env)
395 {
396 napi_value result = nullptr;
397 napi_get_null(env, &result);
398
399 return result;
400 }
401
GetNamedProperty(napi_env env,napi_value obj)402 std::string GetNamedProperty(napi_env env, napi_value obj)
403 {
404 char propValue[MAX_VALUE_LEN] = {0};
405 size_t propLen;
406 if (napi_get_value_string_utf8(env, obj, propValue, MAX_VALUE_LEN, &propLen) != napi_ok) {
407 ACCOUNT_LOGE("Can not get string param from argv");
408 }
409
410 return std::string(propValue);
411 }
412
SetNamedProperty(napi_env env,napi_value dstObj,const char * objName,const char * propName)413 void SetNamedProperty(napi_env env, napi_value dstObj, const char *objName, const char *propName)
414 {
415 napi_value prop = nullptr;
416 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, objName, NAPI_AUTO_LENGTH, &prop));
417 napi_set_named_property(env, dstObj, propName, prop);
418 }
419
SetNamedProperty(napi_env env,napi_value dstObj,const int32_t objValue,const char * propName)420 void SetNamedProperty(napi_env env, napi_value dstObj, const int32_t objValue, const char *propName)
421 {
422 napi_value prop = nullptr;
423 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, objValue, &prop));
424 napi_set_named_property(env, dstObj, propName, prop);
425 }
426
GetErrorCodeValue(napi_env env,int errCode)427 napi_value GetErrorCodeValue(napi_env env, int errCode)
428 {
429 napi_value jsObject = nullptr;
430 napi_value jsValue = nullptr;
431 NAPI_CALL(env, napi_create_int32(env, errCode, &jsValue));
432 NAPI_CALL(env, napi_create_object(env, &jsObject));
433 NAPI_CALL(env, napi_set_named_property(env, jsObject, "code", jsValue));
434 return jsObject;
435 }
436
GetAppAccountInfoForResult(napi_env env,const std::vector<AppAccountInfo> & info,napi_value & result)437 void GetAppAccountInfoForResult(napi_env env, const std::vector<AppAccountInfo> &info, napi_value &result)
438 {
439 NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &result));
440 uint32_t index = 0;
441 for (auto item : info) {
442 std::string name;
443 item.GetName(name);
444 std::string owner;
445 item.GetOwner(owner);
446 napi_value objAppAccountInfo = CreateJSAppAccountInfo(env, name, owner);
447 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index++, objAppAccountInfo));
448 }
449 }
450
GetAuthenticatorInfoForResult(napi_env env,const AuthenticatorInfo & info,napi_value & result)451 void GetAuthenticatorInfoForResult(napi_env env, const AuthenticatorInfo &info, napi_value &result)
452 {
453 napi_value nOwner = nullptr;
454 napi_create_string_utf8(env, info.owner.c_str(), NAPI_AUTO_LENGTH, &nOwner);
455 napi_set_named_property(env, result, "owner", nOwner);
456
457 napi_value nIconId = nullptr;
458 napi_create_uint32(env, info.iconId, &nIconId);
459 napi_set_named_property(env, result, "iconId", nIconId);
460
461 napi_value nLabelId = nullptr;
462 napi_create_uint32(env, info.labelId, &nLabelId);
463 napi_set_named_property(env, result, "labelId", nLabelId);
464 }
465
GetOAuthTokenInfoForResult(napi_env env,const std::vector<OAuthTokenInfo> & info,napi_value result)466 void GetOAuthTokenInfoForResult(napi_env env, const std::vector<OAuthTokenInfo> &info, napi_value result)
467 {
468 int32_t index = 0;
469 for (auto item : info) {
470 napi_value objOAuthTokenInfo = nullptr;
471 napi_create_object(env, &objOAuthTokenInfo);
472
473 napi_value nToken = nullptr;
474 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, item.token.c_str(), NAPI_AUTO_LENGTH, &nToken));
475 napi_set_named_property(env, objOAuthTokenInfo, "token", nToken);
476
477 napi_value nAuthType = nullptr;
478 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, item.authType.c_str(), NAPI_AUTO_LENGTH, &nAuthType));
479 napi_set_named_property(env, objOAuthTokenInfo, "authType", nAuthType);
480
481 napi_set_element(env, result, index, objOAuthTokenInfo);
482 index++;
483 }
484 }
485
GetOAuthListForResult(napi_env env,const std::set<std::string> & info,napi_value result)486 void GetOAuthListForResult(napi_env env, const std::set<std::string> &info, napi_value result)
487 {
488 int32_t index = 0;
489 for (auto item : info) {
490 napi_value nBundleName = nullptr;
491 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, item.c_str(), NAPI_AUTO_LENGTH, &nBundleName));
492 napi_set_element(env, result, index, nBundleName);
493 index++;
494 }
495 }
496
GetAuthenticatorCallbackForResult(napi_env env,sptr<IRemoteObject> callback,napi_value * result)497 void GetAuthenticatorCallbackForResult(napi_env env, sptr<IRemoteObject> callback, napi_value *result)
498 {
499 if (callback == nullptr) {
500 napi_get_undefined(env, result);
501 return;
502 }
503 napi_value remote;
504 napi_create_int64(env, reinterpret_cast<int64_t>(callback.GetRefPtr()), &remote);
505 napi_value global = nullptr;
506 napi_get_global(env, &global);
507 if (global == nullptr) {
508 ACCOUNT_LOGE("get napi global failed");
509 return;
510 }
511 napi_value jsAuthCallbackConstructor = nullptr;
512 napi_get_named_property(env, global, "AuthCallbackConstructor_", &jsAuthCallbackConstructor);
513 if (jsAuthCallbackConstructor == nullptr) {
514 ACCOUNT_LOGE("jsAuthCallbackConstructor is null");
515 return;
516 }
517 size_t argc = ARGS_SIZE_ONE;
518 napi_value argv[ARGS_SIZE_ONE] = { remote };
519 napi_new_instance(env, jsAuthCallbackConstructor, argc, argv, result);
520 }
521
ParseContextWithExInfo(napi_env env,napi_callback_info cbInfo,AppAccountAsyncContext * asyncContext)522 bool ParseContextWithExInfo(napi_env env, napi_callback_info cbInfo, AppAccountAsyncContext *asyncContext)
523 {
524 size_t argc = ARGS_SIZE_THREE;
525 napi_value argv[ARGS_SIZE_THREE] = {0};
526 napi_valuetype valueType = napi_undefined;
527 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
528 if (argc < ARGS_SIZE_ONE) {
529 asyncContext->errMsg = "the number of parameters should be at least 1";
530 return false;
531 }
532 if (!GetStringProperty(env, argv[0], asyncContext->name)) {
533 ACCOUNT_LOGE("the name is not a string");
534 asyncContext->errMsg = "the name is not a string";
535 return false;
536 }
537 if (argc > PARAMTWO) {
538 if (!GetCallbackProperty(env, argv[PARAMTWO], asyncContext->callbackRef, 1)) {
539 ACCOUNT_LOGE("Get callbackRef failed");
540 return false;
541 }
542 }
543 if (argc > ARGS_SIZE_ONE) {
544 napi_typeof(env, argv[1], &valueType);
545 if (valueType == napi_string) {
546 if (!GetStringProperty(env, argv[1], asyncContext->extraInfo)) {
547 asyncContext->errMsg = "the extraInfo is not a string";
548 return false;
549 }
550 } else if (valueType == napi_function) {
551 if (!GetCallbackProperty(env, argv[1], asyncContext->callbackRef, 1)) {
552 ACCOUNT_LOGE("Get callbackRef failed");
553 return false;
554 }
555 return true;
556 } else {
557 ACCOUNT_LOGE("Type matching failed");
558 asyncContext->errMsg = "the type of param 2 is incorrect";
559 return false;
560 }
561 }
562 return true;
563 }
564
ParseArguments(napi_env env,napi_value * argv,const napi_valuetype * valueTypes,size_t argc)565 bool ParseArguments(napi_env env, napi_value *argv, const napi_valuetype *valueTypes, size_t argc)
566 {
567 napi_valuetype valuetype = napi_undefined;
568 for (size_t i = 0; i < argc; ++i) {
569 napi_typeof(env, argv[i], &valuetype);
570 if (valuetype != valueTypes[i]) {
571 argv[i] = nullptr;
572 return false;
573 }
574 }
575 return true;
576 }
577
ParseContextForAuth(napi_env env,napi_callback_info cbInfo,OAuthAsyncContext * context)578 bool ParseContextForAuth(napi_env env, napi_callback_info cbInfo, OAuthAsyncContext *context)
579 {
580 size_t argc = ARGS_SIZE_FIVE;
581 napi_value argv[ARGS_SIZE_FIVE] = {0};
582 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
583 if (argc < ARGS_SIZE_FOUR) {
584 context->errMsg = "the number of parameters should be at least 4";
585 return false;
586 }
587 if (!GetStringProperty(env, argv[0], context->name)) {
588 context->errMsg = "Parameter error. The type of \"name\" must be string";
589 return false;
590 }
591 if (!GetStringProperty(env, argv[1], context->owner)) {
592 context->errMsg = "Parameter error. The type of \"owner\" must be string";
593 return false;
594 }
595 if (!GetStringProperty(env, argv[PARAMTWO], context->authType)) {
596 context->errMsg = "Parameter error. The type of \"authType\" must be string";
597 return false;
598 }
599 AAFwk::WantParams params;
600 if (argc == ARGS_SIZE_FIVE) {
601 napi_valuetype valueType = napi_undefined;
602 napi_typeof(env, argv[PARAMTHREE], &valueType);
603 if ((valueType == napi_undefined) || (valueType == napi_null)) {
604 ACCOUNT_LOGI("the options is undefined or null");
605 } else {
606 if (!AppExecFwk::UnwrapWantParams(env, argv[PARAMTHREE], params)) {
607 ACCOUNT_LOGE("UnwrapWantParams failed");
608 context->errMsg = "Parameter error. The type of \"options\" must be Record";
609 return false;
610 }
611 }
612 }
613 context->options.SetParams(params);
614 JSAuthCallback callback;
615 if (!ParseJSAuthCallback(env, argv[argc - 1], callback)) {
616 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
617 return false;
618 }
619 context->appAccountMgrCb = new (std::nothrow) AppAccountManagerCallback(env, callback);
620 return true;
621 }
622
ParseContextForAuthenticate(napi_env env,napi_callback_info cbInfo,OAuthAsyncContext * asyncContext,size_t argc)623 void ParseContextForAuthenticate(napi_env env, napi_callback_info cbInfo, OAuthAsyncContext *asyncContext, size_t argc)
624 {
625 napi_value argv[ARGS_SIZE_FIVE] = {0};
626 napi_value thisVar;
627 napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr);
628 napi_valuetype valueTypes[ARGS_SIZE_FIVE] = {napi_string, napi_string, napi_string, napi_object, napi_object};
629 size_t index = 0;
630 if (argc == ARGS_SIZE_FIVE) {
631 ParseArguments(env, argv, valueTypes, argc);
632 asyncContext->name = GetNamedProperty(env, argv[index++]);
633 } else {
634 argc = ARGS_SIZE_FOUR;
635 ParseArguments(env, argv, &valueTypes[1], argc);
636 }
637 asyncContext->owner = GetNamedProperty(env, argv[index++]);
638 asyncContext->authType = GetNamedProperty(env, argv[index++]);
639 AAFwk::WantParams params;
640 if (!AppExecFwk::UnwrapWantParams(env, argv[index++], params)) {
641 ACCOUNT_LOGE("UnwrapWantParams failed");
642 }
643 asyncContext->options.SetParams(params);
644 JSAuthCallback callback;
645 ParseJSAuthCallback(env, argv[index], callback);
646 asyncContext->appAccountMgrCb = new (std::nothrow) AppAccountManagerCallback(env, callback);
647 }
648
ParseContextOAuthProperty(napi_env env,napi_value & argv,PropertyType type,OAuthAsyncContext * asyncContext)649 bool ParseContextOAuthProperty(napi_env env, napi_value &argv, PropertyType type, OAuthAsyncContext *asyncContext)
650 {
651 bool result = false;
652 switch (type) {
653 case PropertyType::NAME :
654 result = GetStringProperty(env, argv, asyncContext->name);
655 break;
656 case PropertyType::OWNER :
657 result = GetStringProperty(env, argv, asyncContext->owner);
658 break;
659 case PropertyType::AUTH_TYPE :
660 result = GetStringProperty(env, argv, asyncContext->authType);
661 break;
662 case PropertyType::BUNDLE_NAME :
663 result = GetStringProperty(env, argv, asyncContext->bundleName);
664 break;
665 case PropertyType::SESSION_ID :
666 result = GetStringProperty(env, argv, asyncContext->sessionId);
667 break;
668 case PropertyType::IS_VISIBLE :
669 result = napi_get_value_bool(env, argv, &asyncContext->isVisible) == napi_ok;
670 break;
671 case PropertyType::TOKEN :
672 result = GetStringProperty(env, argv, asyncContext->token);
673 break;
674 // when new PropertyType is added, new error message need to be added in ErrMsgList.
675 default:
676 break;
677 }
678 if (!result) {
679 asyncContext->errMsg = ErrMsgList[type];
680 }
681 return result;
682 }
683
ParseContextForOAuth(napi_env env,napi_callback_info cbInfo,OAuthAsyncContext * asyncContext,const std::vector<PropertyType> & propertyList,napi_value * result)684 bool ParseContextForOAuth(napi_env env, napi_callback_info cbInfo,
685 OAuthAsyncContext *asyncContext, const std::vector<PropertyType> &propertyList, napi_value *result)
686 {
687 // the inner caller promise posInfo.argcSize to be at least 1
688 size_t argcSize = propertyList.size() + 1;
689 size_t argc = argcSize;
690 napi_value argv[ARGS_SIZE_MAX] = {0};
691 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
692 if (argc < argcSize - 1) {
693 asyncContext->errMsg = "the number of parameter should be at least " + std::to_string(argcSize - 1);
694 return false;
695 }
696 if ((argc == argcSize) && (!GetCallbackProperty(env, argv[argcSize - 1], asyncContext->callbackRef, 1))) {
697 asyncContext->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
698 return false;
699 }
700 for (uint32_t i = 0; i < propertyList.size(); i++) {
701 if (!ParseContextOAuthProperty(env, argv[i], propertyList[i], asyncContext)) {
702 return false;
703 }
704 }
705 if (asyncContext->callbackRef == nullptr) {
706 napi_create_promise(env, &asyncContext->deferred, result);
707 } else {
708 napi_get_undefined(env, result);
709 }
710 return true;
711 }
712
ParseAppAccountProperty(napi_env env,napi_value & argv,PropertyType type,AppAccountAsyncContext * asyncContext)713 bool ParseAppAccountProperty(napi_env env, napi_value &argv, PropertyType type, AppAccountAsyncContext *asyncContext)
714 {
715 bool result = false;
716 switch (type) {
717 case PropertyType::NAME :
718 result = GetStringProperty(env, argv, asyncContext->name);
719 break;
720 case PropertyType::OWNER :
721 result = GetStringProperty(env, argv, asyncContext->owner);
722 break;
723 case PropertyType::EXTRA_INFO :
724 result = GetStringProperty(env, argv, asyncContext->extraInfo);
725 break;
726 case PropertyType::BUNDLE_NAME :
727 result = GetStringProperty(env, argv, asyncContext->bundleName);
728 break;
729 case PropertyType::CREDENTIAL_TYPE :
730 result = GetStringProperty(env, argv, asyncContext->credentialType);
731 break;
732 case PropertyType::CREDENTIAL :
733 result = GetStringProperty(env, argv, asyncContext->credential);
734 break;
735 case PropertyType::KEY :
736 result = GetStringProperty(env, argv, asyncContext->key);
737 break;
738 case PropertyType::VALUE :
739 result = GetStringProperty(env, argv, asyncContext->value);
740 break;
741 case PropertyType::IS_ACCESSIBLE :
742 result = napi_get_value_bool(env, argv, &asyncContext->isAccessible) == napi_ok;
743 break;
744 case PropertyType::IS_ENABLE :
745 result = napi_get_value_bool(env, argv, &asyncContext->isEnable) == napi_ok;
746 break;
747 default:
748 break;
749 }
750 return result;
751 }
752
ParseContextForAppAccount(napi_env env,napi_callback_info cbInfo,AppAccountAsyncContext * context,const std::vector<PropertyType> & propertyList,napi_value * result)753 bool ParseContextForAppAccount(napi_env env, napi_callback_info cbInfo,
754 AppAccountAsyncContext *context, const std::vector<PropertyType> &propertyList, napi_value *result)
755 {
756 size_t argcSize = propertyList.size() + 1;
757 size_t argc = argcSize;
758 napi_value argv[ARGS_SIZE_MAX] = {0};
759 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
760 if (argc < (argcSize - 1)) {
761 context->errMsg =
762 "Parameter error. The number of parameter should be at least " + std::to_string(argcSize - 1);
763 return false;
764 }
765 if ((argc == argcSize) && (!GetCallbackProperty(env, argv[argcSize - 1], context->callbackRef, 1))) {
766 context->errMsg = "Parameter error. The type of \"callback\" must be function";
767 return false;
768 }
769 for (size_t i = 0; i < propertyList.size(); i++) {
770 if (!ParseAppAccountProperty(env, argv[i], propertyList[i], context)) {
771 context->errMsg = ErrMsgList[propertyList[i]];
772 return false;
773 }
774 }
775 if (context->callbackRef == nullptr) {
776 napi_create_promise(env, &context->deferred, result);
777 } else {
778 napi_get_undefined(env, result);
779 }
780 return true;
781 }
782
ParseContextCBArray(napi_env env,napi_callback_info cbInfo,GetAccountsAsyncContext * asyncContext)783 bool ParseContextCBArray(napi_env env, napi_callback_info cbInfo, GetAccountsAsyncContext *asyncContext)
784 {
785 size_t argc = ARGS_SIZE_ONE;
786 napi_value argv[ARGS_SIZE_ONE] = {0};
787 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
788 if ((argc == ARGS_SIZE_ONE) && (!GetCallbackProperty(env, argv[0], asyncContext->callbackRef, 1))) {
789 asyncContext->errMsg = "Parameter error. The type of \"callback\" must be function";
790 return false;
791 }
792 return true;
793 }
794
ParseContextWithStrCBArray(napi_env env,napi_callback_info cbInfo,GetAccountsAsyncContext * asyncContext)795 bool ParseContextWithStrCBArray(napi_env env, napi_callback_info cbInfo, GetAccountsAsyncContext *asyncContext)
796 {
797 size_t argc = ARGS_SIZE_TWO;
798 napi_value argv[ARGS_SIZE_TWO] = {0};
799 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
800 if (argc < ARGS_SIZE_ONE) {
801 asyncContext->errMsg = "Parameter error. The number of parameter should be at least 2";
802 return false;
803 }
804 if ((argc == ARGS_SIZE_TWO) && (!GetCallbackProperty(env, argv[1], asyncContext->callbackRef, 1))) {
805 asyncContext->errMsg = "Parameter error. The type of \"callback\" must be function";
806 return false;
807 }
808 if (!GetStringProperty(env, argv[0], asyncContext->owner)) {
809 asyncContext->errMsg = "Parameter error. The type of \"owner\" must be string";
810 return false;
811 }
812 return true;
813 }
814
GetArrayProperty(const napi_env & env,napi_value * argv,AsyncContextForSubscribe * context)815 bool GetArrayProperty(const napi_env &env, napi_value *argv, AsyncContextForSubscribe *context)
816 {
817 bool isArray = false;
818 napi_is_array(env, argv[1], &isArray);
819 if (!isArray) {
820 context->errMsg = "Parameter error. The type of \"owners\" must be string array";
821 return false;
822 }
823 uint32_t length = 0;
824 napi_get_array_length(env, argv[1], &length);
825 if (length == 0) {
826 context->errMsg = "the owers should not be empty";
827 context->errCode = ERR_JS_INVALID_PARAMETER;
828 return false;
829 }
830 for (size_t i = 0; i < length; i++) {
831 napi_value ownerStr = nullptr;
832 napi_get_element(env, argv[1], i, &ownerStr);
833 std::string owner;
834 if (!GetStringProperty(env, ownerStr, owner)) {
835 context->errMsg = "Parameter error. The type of \"owners\" must be string array";
836 return false;
837 }
838 context->owners.emplace_back(owner);
839 }
840 return true;
841 }
842
ParseParametersBySubscribe(const napi_env & env,napi_callback_info cbInfo,AsyncContextForSubscribe * context)843 bool ParseParametersBySubscribe(const napi_env &env, napi_callback_info cbInfo, AsyncContextForSubscribe *context)
844 {
845 size_t argc = SUBSCRIBE_MAX_PARA;
846 napi_value argv[SUBSCRIBE_MAX_PARA] = {nullptr};
847 napi_value thisVar = nullptr;
848 napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr);
849 context->errCode = ERR_JS_PARAMETER_ERROR;
850 if (argc != SUBSCRIBE_MAX_PARA) {
851 context->errMsg = "Parameter error. The number of parameters should be 3";
852 return false;
853 }
854 if (!GetStringProperty(env, argv[0], context->type)) {
855 context->errMsg = "Parameter error. The type of \"type\" must be string";
856 return false;
857 }
858 if ((context->type != "change") && (context->type != "accountChange")) {
859 context->errMsg = "Parameter error. The content of \"type\" must be \"change|accountChange\"";
860 context->errCode = ERR_JS_INVALID_PARAMETER;
861 return false;
862 }
863 if (!GetArrayProperty(env, argv, context)) {
864 context->errMsg = "Parameter error. The type of \"owners\" must be array";
865 return false;
866 }
867 if (!GetCallbackProperty(env, argv[PARAMTWO], context->callbackRef, 1)) {
868 context->errMsg = "Parameter error. The type of \"callback\" must be function";
869 return false;
870 }
871 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&context->appAccountManager));
872 return true;
873 }
874
GetSubscriberByUnsubscribe(const napi_env & env,std::vector<std::shared_ptr<SubscriberPtr>> & subscribers,AsyncContextForUnsubscribe * asyncContextForOff,bool & isFind)875 napi_value GetSubscriberByUnsubscribe(const napi_env &env, std::vector<std::shared_ptr<SubscriberPtr>> &subscribers,
876 AsyncContextForUnsubscribe *asyncContextForOff, bool &isFind)
877 {
878 napi_value result;
879
880 {
881 std::lock_guard<std::mutex> lock(g_lockForAppAccountSubscribers);
882
883 for (auto subscriberInstance : g_AppAccountSubscribers) {
884 if (subscriberInstance.first == asyncContextForOff->appAccountManager) {
885 for (auto item : subscriberInstance.second) {
886 subscribers.emplace_back(item->subscriber);
887 }
888 isFind = true;
889 break;
890 }
891 }
892 }
893
894 NAPI_CALL(env, napi_get_boolean(env, isFind, &result));
895 return result;
896 }
897
ParseParametersByUnsubscribe(const napi_env & env,napi_callback_info cbInfo,AsyncContextForUnsubscribe * context)898 bool ParseParametersByUnsubscribe(
899 const napi_env &env, napi_callback_info cbInfo, AsyncContextForUnsubscribe *context)
900 {
901 size_t argc = UNSUBSCRIBE_MAX_PARA;
902 napi_value argv[UNSUBSCRIBE_MAX_PARA] = {nullptr};
903 napi_value thisVar = nullptr;
904 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, NULL), false);
905 if (argc < 1) {
906 context->errMsg = "Parameter error. The number of parameters should be at least 1";
907 context->errCode = ERR_JS_PARAMETER_ERROR;
908 return false;
909 }
910 if (!GetStringProperty(env, argv[0], context->type)) {
911 context->errMsg = "Parameter error. The type of \"type\" must be string";
912 context->errCode = ERR_JS_PARAMETER_ERROR;
913 return false;
914 }
915 if ((context->type != "change") && (context->type != "accountChange")) {
916 context->errMsg = "Parameter error. The content of \"type\" must be \"change|accountChange\"";
917 context->errCode = ERR_JS_INVALID_PARAMETER;
918 return false;
919 }
920 if ((argc == UNSUBSCRIBE_MAX_PARA) && (!GetCallbackProperty(env, argv[1], context->callbackRef, 1))) {
921 context->errMsg = "Parameter error. The type of \"callback\" must be function";
922 context->errCode = ERR_JS_PARAMETER_ERROR;
923 return false;
924 }
925 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&context->appAccountManager));
926 if (context->appAccountManager == nullptr) {
927 ACCOUNT_LOGE("appAccountManager is nullptr");
928 return false;
929 }
930 context->argc = argc;
931 return true;
932 }
933
UnsubscribeExecuteCB(napi_env env,void * data)934 void UnsubscribeExecuteCB(napi_env env, void *data)
935 {
936 AsyncContextForUnsubscribe *asyncContextForOff = reinterpret_cast<AsyncContextForUnsubscribe *>(data);
937 for (auto offSubscriber : asyncContextForOff->subscribers) {
938 int errCode = AppAccountManager::UnsubscribeAppAccount(offSubscriber);
939 ACCOUNT_LOGD("Unsubscribe errcode parameter is %{public}d", errCode);
940 }
941 }
942
UnsubscribeCallbackCompletedCB(napi_env env,napi_status status,void * data)943 void UnsubscribeCallbackCompletedCB(napi_env env, napi_status status, void *data)
944 {
945 AsyncContextForUnsubscribe *asyncContextForOff = reinterpret_cast<AsyncContextForUnsubscribe *>(data);
946 if (asyncContextForOff == nullptr) {
947 return;
948 }
949
950 if (asyncContextForOff->argc >= UNSUBSCRIBE_MAX_PARA) {
951 napi_value result = nullptr;
952 napi_get_null(env, &result);
953 napi_value results[ARGS_SIZE_ONE] = {result};
954 NapiCallVoidFunction(env, results, ARGS_SIZE_ONE, asyncContextForOff->callbackRef);
955 }
956
957 {
958 std::lock_guard<std::mutex> lock(g_lockForAppAccountSubscribers);
959 ACCOUNT_LOGD("Erase before g_AppAccountSubscribers.size = %{public}zu", g_AppAccountSubscribers.size());
960 // erase the info from map
961 auto subscribe = g_AppAccountSubscribers.find(asyncContextForOff->appAccountManager);
962 if (subscribe != g_AppAccountSubscribers.end()) {
963 for (auto offCBInfo : subscribe->second) {
964 delete offCBInfo;
965 }
966 g_AppAccountSubscribers.erase(subscribe);
967 }
968 ACCOUNT_LOGD("Erase end g_AppAccountSubscribers.size = %{public}zu", g_AppAccountSubscribers.size());
969 }
970 delete asyncContextForOff;
971 }
972
ParseVerifyCredentialOptions(napi_env env,napi_value object,VerifyCredentialOptions & options)973 bool ParseVerifyCredentialOptions(napi_env env, napi_value object, VerifyCredentialOptions &options)
974 {
975 napi_valuetype valueType = napi_undefined;
976 napi_typeof(env, object, &valueType);
977 if ((valueType == napi_undefined) || (valueType == napi_null)) {
978 ACCOUNT_LOGI("the VerifyCredentialOptions is undefined or null");
979 return true;
980 }
981 if (valueType != napi_object) {
982 ACCOUNT_LOGE("the type of object is not napi_object");
983 return false;
984 }
985 if (!GetOptionalStringPropertyByKey(env, object, "credential", options.credential)) {
986 ACCOUNT_LOGE("failed to get options's credential property");
987 return false;
988 }
989 if (!GetOptionalStringPropertyByKey(env, object, "credentialType", options.credentialType)) {
990 ACCOUNT_LOGE("failed to get options's credentialType property");
991 return false;
992 }
993 napi_value value = nullptr;
994 bool hasProp = false;
995 napi_has_named_property(env, object, "parameters", &hasProp);
996 if (hasProp) {
997 napi_get_named_property(env, object, "parameters", &value);
998 valueType = napi_undefined;
999 napi_typeof(env, value, &valueType);
1000 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1001 ACCOUNT_LOGI("the parameters is undefined or null");
1002 } else {
1003 if (!AppExecFwk::UnwrapWantParams(env, value, options.parameters)) {
1004 return false;
1005 }
1006 }
1007 }
1008 return true;
1009 }
1010
ParseOptionalStringVectorByKey(napi_env env,napi_value object,const char * key,bool & result,std::vector<std::string> & array)1011 static bool ParseOptionalStringVectorByKey(
1012 napi_env env, napi_value object, const char* key, bool &result, std::vector<std::string> &array)
1013 {
1014 napi_has_named_property(env, object, key, &result);
1015 if (result) {
1016 napi_value value = nullptr;
1017 napi_get_named_property(env, object, key, &value);
1018 napi_valuetype valueType = napi_undefined;
1019 napi_typeof(env, value, &valueType);
1020 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1021 result = false;
1022 ACCOUNT_LOGI("the %{public}s is undefined or null", key);
1023 return true;
1024 }
1025 if (!ParseStringVector(env, value, array)) {
1026 return false;
1027 }
1028 }
1029 return true;
1030 }
1031
ParseSelectAccountsOptions(napi_env env,napi_value object,SelectAccountsOptions & options)1032 bool ParseSelectAccountsOptions(napi_env env, napi_value object, SelectAccountsOptions &options)
1033 {
1034 napi_valuetype valueType = napi_undefined;
1035 napi_typeof(env, object, &valueType);
1036 if (valueType != napi_object) {
1037 return false;
1038 }
1039 napi_value value = nullptr;
1040 napi_has_named_property(env, object, "allowedAccounts", &options.hasAccounts);
1041 if (options.hasAccounts) {
1042 napi_get_named_property(env, object, "allowedAccounts", &value);
1043 valueType = napi_undefined;
1044 napi_typeof(env, value, &valueType);
1045 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1046 options.hasAccounts = false;
1047 ACCOUNT_LOGI("the allowedAccounts is undefined or null");
1048 } else {
1049 if (!ParseAccountVector(env, value, options.allowedAccounts)) {
1050 return false;
1051 }
1052 }
1053 }
1054 if (!ParseOptionalStringVectorByKey(env, object, "allowedOwners", options.hasOwners, options.allowedOwners)) {
1055 return false;
1056 }
1057 if (!ParseOptionalStringVectorByKey(env, object, "requiredLabels", options.hasLabels, options.requiredLabels)) {
1058 return false;
1059 }
1060 return true;
1061 }
1062
ParseSetPropertiesOptions(napi_env env,napi_value object,SetPropertiesOptions & options)1063 bool ParseSetPropertiesOptions(napi_env env, napi_value object, SetPropertiesOptions &options)
1064 {
1065 napi_valuetype valueType = napi_undefined;
1066 napi_typeof(env, object, &valueType);
1067 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1068 ACCOUNT_LOGI("the SetPropertiesOptions is undefined or null");
1069 return true;
1070 }
1071 if (valueType != napi_object) {
1072 return false;
1073 }
1074 napi_value value = nullptr;
1075 bool hasProp = false;
1076 napi_has_named_property(env, object, "properties", &hasProp);
1077 if (hasProp) {
1078 napi_get_named_property(env, object, "properties", &value);
1079 valueType = napi_undefined;
1080 napi_typeof(env, value, &valueType);
1081 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1082 ACCOUNT_LOGI("the properties is undefined or null");
1083 } else {
1084 if (!AppExecFwk::UnwrapWantParams(env, value, options.properties)) {
1085 return false;
1086 }
1087 }
1088 }
1089 hasProp = false;
1090 napi_has_named_property(env, object, "parameters", &hasProp);
1091 if (hasProp) {
1092 napi_get_named_property(env, object, "parameters", &value);
1093 valueType = napi_undefined;
1094 napi_typeof(env, value, &valueType);
1095 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1096 ACCOUNT_LOGI("the parameters is undefined or null");
1097 } else {
1098 if (!AppExecFwk::UnwrapWantParams(env, value, options.parameters)) {
1099 return false;
1100 }
1101 }
1102 }
1103 return true;
1104 }
1105
GetNamedFunction(napi_env env,napi_value object,const std::string & name,napi_ref & funcRef)1106 bool GetNamedFunction(napi_env env, napi_value object, const std::string &name, napi_ref &funcRef)
1107 {
1108 napi_value value = nullptr;
1109 napi_get_named_property(env, object, name.c_str(), &value);
1110 return GetCallbackProperty(env, value, funcRef, 1);
1111 }
1112
ParseJSAuthCallback(napi_env env,napi_value object,JSAuthCallback & callback)1113 bool ParseJSAuthCallback(napi_env env, napi_value object, JSAuthCallback &callback)
1114 {
1115 napi_valuetype valueType = napi_undefined;
1116 napi_typeof(env, object, &valueType);
1117 if (valueType != napi_object) {
1118 ACCOUNT_LOGE("the type of callback is invalid");
1119 return false;
1120 }
1121 bool hasProp = false;
1122 napi_has_named_property(env, object, "onRequestContinued", &hasProp);
1123 if (hasProp) {
1124 napi_value value = nullptr;
1125 napi_get_named_property(env, object, "onRequestContinued", &value);
1126 valueType = napi_undefined;
1127 napi_typeof(env, value, &valueType);
1128 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1129 ACCOUNT_LOGI("the parameters is undefined or null");
1130 } else {
1131 napi_ref ref = nullptr;
1132 if (!GetNamedFunction(env, object, "onRequestContinued", ref)) {
1133 ACCOUNT_LOGE("the onRequestContinued is invalid");
1134 return false;
1135 }
1136 callback.onRequestContinued = std::make_shared<NapiCallbackRef>(env, ref);
1137 }
1138 }
1139 napi_ref onResultRef = nullptr;
1140 bool onResultParse = GetNamedFunction(env, object, "onResult", onResultRef);
1141 if (onResultParse && onResultRef != nullptr) {
1142 callback.onResult = std::make_shared<NapiCallbackRef>(env, onResultRef);
1143 }
1144 napi_ref onRequestRedirectedRef = nullptr;
1145 bool onRequestRedirectedParse = GetNamedFunction(env, object, "onRequestRedirected", onRequestRedirectedRef);
1146 if (onRequestRedirectedParse && onRequestRedirectedRef != nullptr) {
1147 callback.onRequestRedirected = std::make_shared<NapiCallbackRef>(env, onRequestRedirectedRef);
1148 }
1149 return onResultParse && onRequestRedirectedParse;
1150 }
1151
ParseContextForVerifyCredential(napi_env env,napi_callback_info info,VerifyCredentialContext * context)1152 bool ParseContextForVerifyCredential(napi_env env, napi_callback_info info, VerifyCredentialContext *context)
1153 {
1154 size_t argc = ARGS_SIZE_FOUR;
1155 napi_value argv[ARGS_SIZE_FOUR] = {0};
1156 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1157 if (argc < ARGS_SIZE_THREE) {
1158 context->errMsg = "the number of parameter shoulde be at least 3";
1159 return false;
1160 }
1161 int32_t index = 0;
1162 if (!GetStringProperty(env, argv[index++], context->name)) {
1163 context->errMsg = "Parameter error. The type of \"name\" must be string";
1164 return false;
1165 }
1166 if (!GetStringProperty(env, argv[index++], context->owner)) {
1167 context->errMsg = "Parameter error. The type of \"owner\" must be string";
1168 return false;
1169 }
1170 if ((argc == ARGS_SIZE_FOUR) && (!ParseVerifyCredentialOptions(env, argv[index++], context->options))) {
1171 context->errMsg = "Parameter error. The type of \"options\" must be VerifyCredentialOptions";
1172 return false;
1173 }
1174 if (!ParseJSAuthCallback(env, argv[index], context->callback)) {
1175 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
1176 return false;
1177 }
1178 return true;
1179 }
1180
ParseContextForSetProperties(napi_env env,napi_callback_info info,SetPropertiesContext * context)1181 bool ParseContextForSetProperties(napi_env env, napi_callback_info info, SetPropertiesContext *context)
1182 {
1183 size_t argc = ARGS_SIZE_THREE;
1184 napi_value argv[ARGS_SIZE_THREE] = {0};
1185 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1186 if (argc < ARGS_SIZE_TWO) {
1187 context->errMsg = "Parameter error. The number of parameters should be 2";
1188 return false;
1189 }
1190 int32_t index = 0;
1191 if (!GetStringProperty(env, argv[index++], context->owner)) {
1192 context->errMsg = "Parameter error. The type of \"owner\" must be string";
1193 return false;
1194 }
1195 if (argc == ARGS_SIZE_THREE) {
1196 if (!ParseSetPropertiesOptions(env, argv[index++], context->options)) {
1197 context->errMsg = "Parameter error. The type of \"options\" must be SetPropertiesOptions";
1198 return false;
1199 }
1200 }
1201 if (!ParseJSAuthCallback(env, argv[index], context->callback)) {
1202 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
1203 return false;
1204 }
1205 return true;
1206 }
1207
ParseContextForSelectAccount(napi_env env,napi_callback_info info,SelectAccountsContext * context)1208 bool ParseContextForSelectAccount(napi_env env, napi_callback_info info, SelectAccountsContext *context)
1209 {
1210 size_t argc = ARGS_SIZE_TWO;
1211 napi_value argv[ARGS_SIZE_TWO] = {0};
1212 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1213 if (argc < ARGS_SIZE_ONE) {
1214 context->errMsg = "Parameter error. The number of parameters should be 1";
1215 return false;
1216 }
1217 napi_ref callbackRef = nullptr;
1218 if ((argc == ARGS_SIZE_TWO) && (!GetCallbackProperty(env, argv[PARAMONE], callbackRef, 1))) {
1219 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
1220 return false;
1221 }
1222 if (callbackRef != nullptr) {
1223 context->callbackRef = std::make_shared<NapiCallbackRef>(env, callbackRef);
1224 }
1225 if (!ParseSelectAccountsOptions(env, argv[0], context->options)) {
1226 context->errMsg = "Parameter error. The type of \"options\" must be SelectAccountsOptions";
1227 return false;
1228 }
1229 return true;
1230 }
1231
GetArrayLength(napi_env env,napi_value value,uint32_t & length)1232 bool GetArrayLength(napi_env env, napi_value value, uint32_t &length)
1233 {
1234 bool isArray = false;
1235 napi_is_array(env, value, &isArray);
1236 if (!isArray) {
1237 ACCOUNT_LOGE("wrong argument type, array expected");
1238 return false;
1239 }
1240 napi_get_array_length(env, value, &length);
1241 return true;
1242 }
1243
ParseAccountVector(napi_env env,napi_value value,std::vector<std::pair<std::string,std::string>> & accountVec)1244 bool ParseAccountVector(napi_env env, napi_value value, std::vector<std::pair<std::string, std::string>> &accountVec)
1245 {
1246 uint32_t length = 0;
1247 if (!GetArrayLength(env, value, length)) {
1248 return false;
1249 }
1250 napi_valuetype valueType = napi_undefined;
1251 for (uint32_t i = 0; i < length; ++i) {
1252 napi_value item = nullptr;
1253 napi_get_element(env, value, i, &item);
1254 NAPI_CALL_BASE(env, napi_typeof(env, item, &valueType), false);
1255 if (valueType != napi_object) {
1256 ACCOUNT_LOGD("Wrong argument type, Object expected");
1257 return false;
1258 }
1259 std::string name;
1260 if (!GetStringPropertyByKey(env, item, "name", name)) {
1261 return false;
1262 }
1263 std::string owner;
1264 if (!GetStringPropertyByKey(env, item, "owner", owner)) {
1265 return false;
1266 }
1267 accountVec.push_back(std::make_pair(owner, name));
1268 }
1269 return true;
1270 }
1271
ParseStringVector(napi_env env,napi_value value,std::vector<std::string> & strVec)1272 bool ParseStringVector(napi_env env, napi_value value, std::vector<std::string> &strVec)
1273 {
1274 uint32_t length = 0;
1275 if (!GetArrayLength(env, value, length)) {
1276 return false;
1277 }
1278 for (uint32_t i = 0; i < length; ++i) {
1279 napi_value item = nullptr;
1280 napi_get_element(env, value, i, &item);
1281 std::string str;
1282 if (!GetStringProperty(env, item, str)) {
1283 return false;
1284 }
1285 strVec.push_back(str);
1286 }
1287 return true;
1288 }
1289
ParseContextForCheckAccountLabels(napi_env env,napi_callback_info info,CheckAccountLabelsContext * context)1290 bool ParseContextForCheckAccountLabels(napi_env env, napi_callback_info info, CheckAccountLabelsContext *context)
1291 {
1292 size_t argc = ARGS_SIZE_FOUR;
1293 napi_value argv[ARGS_SIZE_FOUR] = {0};
1294 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1295 if (argc < ARGS_SIZE_THREE) {
1296 context->errMsg = "Parameter error. The number of parameters should be 3";
1297 return false;
1298 }
1299 napi_ref callbackRef = nullptr;
1300 if ((argc == ARGS_SIZE_FOUR) && (!GetCallbackProperty(env, argv[PARAMTHREE], callbackRef, 1))) {
1301 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
1302 return false;
1303 }
1304 if (callbackRef != nullptr) {
1305 context->callbackRef = std::make_shared<NapiCallbackRef>(env, callbackRef);
1306 }
1307 if (!GetStringProperty(env, argv[0], context->name)) {
1308 context->errMsg = "Parameter error. The type of \"name\" must be string";
1309 return false;
1310 }
1311 if (!GetStringProperty(env, argv[PARAMONE], context->owner)) {
1312 context->errMsg = "Parameter error. The type of \"owner\" must be string";
1313 return false;
1314 }
1315 if (!ParseStringVector(env, argv[PARAMTWO], context->labels)) {
1316 context->errMsg = "Parameter error. The type of \"labels\" must be string vector";
1317 return false;
1318 }
1319 return true;
1320 }
1321
VerifyCredCompleteCB(napi_env env,napi_status status,void * data)1322 void VerifyCredCompleteCB(napi_env env, napi_status status, void *data)
1323 {
1324 (void) status;
1325 auto context = reinterpret_cast<VerifyCredentialContext *>(data);
1326 if ((context->errCode != ERR_JS_SUCCESS) && (context->appAccountMgrCb != nullptr)) {
1327 AAFwk::Want errResult;
1328 context->appAccountMgrCb->OnResult(context->errCode, errResult);
1329 }
1330 delete context;
1331 }
1332
ProcessOnResultCallback(napi_env env,JSAuthCallback & callback,int32_t resultCode,const AAFwk::WantParams & result)1333 void ProcessOnResultCallback(
1334 napi_env env, JSAuthCallback &callback, int32_t resultCode, const AAFwk::WantParams &result)
1335 {
1336 napi_value results[ARGS_SIZE_TWO] = {nullptr};
1337 napi_create_int32(env, resultCode, &results[0]);
1338 results[ARGS_SIZE_ONE] = AppExecFwk::WrapWantParams(env, result);
1339 NapiCallVoidFunction(env, results, ARGS_SIZE_TWO, callback.onResult->callbackRef);
1340 }
1341
ParseCreateAccountOptions(napi_env env,napi_value object,CreateAccountOptions & options)1342 bool ParseCreateAccountOptions(napi_env env, napi_value object, CreateAccountOptions &options)
1343 {
1344 bool hasCustomData = false;
1345 napi_has_named_property(env, object, "customData", &hasCustomData);
1346 if (!hasCustomData) {
1347 return true;
1348 }
1349 napi_value customDataValue = nullptr;
1350 napi_get_named_property(env, object, "customData", &customDataValue);
1351 napi_valuetype valueType = napi_undefined;
1352 napi_typeof(env, customDataValue, &valueType);
1353 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1354 ACCOUNT_LOGI("the customData of CreateAccountOptions is undefined or null");
1355 return true;
1356 }
1357 if (valueType != napi_object) {
1358 ACCOUNT_LOGE("customData type is not object");
1359 return false;
1360 }
1361 napi_value keyArr = nullptr;
1362 napi_get_property_names(env, customDataValue, &keyArr);
1363 uint32_t keyNum = 0;
1364 napi_get_array_length(env, keyArr, &keyNum);
1365 for (uint32_t i = 0; i < keyNum; ++i) {
1366 napi_value item = nullptr;
1367 napi_get_element(env, keyArr, i, &item);
1368 std::string keyStr;
1369 if (!GetStringProperty(env, item, keyStr)) {
1370 ACCOUNT_LOGE("fail to get string");
1371 return false;
1372 }
1373 napi_value val = nullptr;
1374 napi_get_named_property(env, customDataValue, keyStr.c_str(), &val);
1375 std::string valStr;
1376 if (!GetStringProperty(env, val, valStr)) {
1377 ACCOUNT_LOGE("fail to get string");
1378 return false;
1379 }
1380 options.customData.emplace(keyStr, valStr);
1381 }
1382 return true;
1383 }
1384
ParseCreateAccountImplicitlyOptions(napi_env env,napi_value object,CreateAccountImplicitlyOptions & options)1385 bool ParseCreateAccountImplicitlyOptions(napi_env env, napi_value object, CreateAccountImplicitlyOptions &options)
1386 {
1387 napi_valuetype valueType = napi_undefined;
1388 napi_typeof(env, object, &valueType);
1389 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1390 ACCOUNT_LOGI("the CreateAccountImplicitlyOptions is undefined or null");
1391 return true;
1392 }
1393 if (valueType != napi_object) {
1394 return false;
1395 }
1396 napi_value value = nullptr;
1397 napi_has_named_property(env, object, "requiredLabels", &options.hasRequiredLabels);
1398 if (options.hasRequiredLabels) {
1399 napi_get_named_property(env, object, "requiredLabels", &value);
1400 valueType = napi_undefined;
1401 napi_typeof(env, value, &valueType);
1402 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1403 options.hasRequiredLabels = false;
1404 ACCOUNT_LOGI("the requiredLabels is undefined or null");
1405 } else {
1406 if (!ParseStringVector(env, value, options.requiredLabels)) {
1407 return false;
1408 }
1409 }
1410 }
1411 if (!GetOptionalStringPropertyByKey(env, object, "authType", options.authType)) {
1412 ACCOUNT_LOGE("failed to get options's authType property");
1413 return false;
1414 }
1415 bool hasParam = false;
1416 napi_has_named_property(env, object, "parameters", &hasParam);
1417 AAFwk::WantParams params;
1418 if (hasParam) {
1419 napi_get_named_property(env, object, "parameters", &value);
1420 valueType = napi_undefined;
1421 napi_typeof(env, value, &valueType);
1422 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1423 ACCOUNT_LOGI("the authType is undefined or null");
1424 } else {
1425 if (!AppExecFwk::UnwrapWantParams(env, value, params)) {
1426 return false;
1427 }
1428 }
1429 }
1430 options.parameters.SetParams(params);
1431 return true;
1432 }
1433
ParseContextForCreateAccount(napi_env env,napi_callback_info cbInfo,CreateAccountContext * context)1434 bool ParseContextForCreateAccount(napi_env env, napi_callback_info cbInfo, CreateAccountContext *context)
1435 {
1436 size_t argc = ARGS_SIZE_THREE;
1437 napi_value argv[ARGS_SIZE_THREE] = {0};
1438 napi_valuetype valueType = napi_undefined;
1439 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
1440 if (argc < ARGS_SIZE_ONE) {
1441 context->errMsg = "Parameter error. The number of parameters should be at least 1";
1442 return false;
1443 }
1444 if (!GetStringProperty(env, argv[0], context->name)) {
1445 ACCOUNT_LOGE("the name is not a string");
1446 context->errMsg = "Parameter error. The type of \"name\" must be string";
1447 return false;
1448 }
1449 if (argc > PARAMTWO) {
1450 if (!GetCallbackProperty(env, argv[PARAMTWO], context->callbackRef, 1)) {
1451 ACCOUNT_LOGE("Get callbackRef failed");
1452 return false;
1453 }
1454 }
1455 if (argc > ARGS_SIZE_ONE) {
1456 napi_typeof(env, argv[1], &valueType);
1457 if (valueType == napi_object) {
1458 if (!ParseCreateAccountOptions(env, argv[1], context->options)) {
1459 ACCOUNT_LOGE("the type of param 1 is incorrect");
1460 context->errMsg = "Parameter error. The type of \"options\" must be CreateAccountOptions";
1461 return false;
1462 }
1463 } else if (valueType == napi_function) {
1464 if (!GetCallbackProperty(env, argv[1], context->callbackRef, 1)) {
1465 ACCOUNT_LOGE("Get callbackRef failed");
1466 context->errMsg = "Parameter error. The type of \"callback\" must be napi_function";
1467 return false;
1468 }
1469 return true;
1470 } else if ((valueType == napi_undefined) || (valueType == napi_null)) {
1471 ACCOUNT_LOGI("the param'1 is undefined or null");
1472 return true;
1473 } else {
1474 ACCOUNT_LOGE("Type matching failed");
1475 context->errMsg = "Parameter error. The type of param 2 is incorrect";
1476 return false;
1477 }
1478 }
1479 return true;
1480 }
1481
ParseContextForCreateAccountImplicitly(napi_env env,napi_callback_info cbInfo,CreateAccountImplicitlyContext * context)1482 bool ParseContextForCreateAccountImplicitly(
1483 napi_env env, napi_callback_info cbInfo, CreateAccountImplicitlyContext *context)
1484 {
1485 size_t argc = ARGS_SIZE_THREE;
1486 napi_value argv[ARGS_SIZE_THREE] = {0};
1487 napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
1488 if (argc < ARGS_SIZE_TWO) {
1489 context->errMsg = "Parameter error. The number of parameters should be at least 2";
1490 return false;
1491 }
1492 if (!GetStringProperty(env, argv[0], context->owner)) {
1493 context->errMsg = "Parameter error. The type of \"owner\" must be string";
1494 return false;
1495 }
1496 if (argc == ARGS_SIZE_THREE) {
1497 napi_valuetype valueType = napi_undefined;
1498 napi_typeof(env, argv[1], &valueType);
1499 if ((valueType == napi_undefined) || (valueType == napi_null)) {
1500 ACCOUNT_LOGI("the authType is undefined or null");
1501 } else {
1502 if (!ParseCreateAccountImplicitlyOptions(env, argv[1], context->options)) {
1503 context->errMsg = "Parameter error. The type of \"options\" must be CreateAccountImplicitlyOptions";
1504 return false;
1505 }
1506 }
1507 }
1508 if (!ParseJSAuthCallback(env, argv[argc - 1], context->callback)) {
1509 context->errMsg = "Parameter error. The type of \"callback\" must be AuthCallback";
1510 return false;
1511 }
1512 return true;
1513 }
1514 } // namespace AccountJsKit
1515 } // namespace OHOS
1516