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