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