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