• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "napi_app_account.h"
17 
18 #include <string>
19 #include <cstring>
20 #include <vector>
21 #include "account_log_wrapper.h"
22 #include "app_account_common.h"
23 #include "app_account_manager.h"
24 #include "napi/native_api.h"
25 #include "napi/native_node_api.h"
26 #include "napi_account_common.h"
27 #include "napi_account_error.h"
28 #include "napi_app_account_common.h"
29 
30 using namespace OHOS::AccountSA;
31 namespace OHOS {
32 namespace AccountJsKit {
CheckSpecialCharacters(const std::string & name)33 static bool CheckSpecialCharacters(const std::string &name)
34 {
35     for (const auto &specialCharacter : Constants::SPECIAL_CHARACTERS) {
36         std::size_t index = name.find(specialCharacter);
37         if (index != std::string::npos) {
38             ACCOUNT_LOGE("found a special character, specialCharacter = %{public}c", specialCharacter);
39             return false;
40         }
41     }
42     return true;
43 }
44 
Init(napi_env env,napi_value exports)45 napi_value NapiAppAccount::Init(napi_env env, napi_value exports)
46 {
47     napi_property_descriptor descriptor[] = {
48         DECLARE_NAPI_FUNCTION("createAppAccountManager", CreateAppAccountManager),
49     };
50     NAPI_CALL(
51         env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor));
52 
53     napi_property_descriptor properties[] = {
54         DECLARE_NAPI_FUNCTION("addAccount", AddAccount),
55         DECLARE_NAPI_FUNCTION("addAccountImplicitly", AddAccountImplicitly),
56         DECLARE_NAPI_FUNCTION("deleteAccount", DeleteAccount),
57         DECLARE_NAPI_FUNCTION("disableAppAccess", DisableAppAccess),
58         DECLARE_NAPI_FUNCTION("enableAppAccess", EnableAppAccess),
59         DECLARE_NAPI_FUNCTION("checkAppAccountSyncEnable", CheckAppAccountSyncEnable),
60         DECLARE_NAPI_FUNCTION("setAccountCredential", SetAccountCredential),
61         DECLARE_NAPI_FUNCTION("setAccountExtraInfo", SetAccountExtraInfo),
62         DECLARE_NAPI_FUNCTION("setAppAccountSyncEnable", SetAppAccountSyncEnable),
63         DECLARE_NAPI_FUNCTION("setAssociatedData", SetAssociatedData),
64         DECLARE_NAPI_FUNCTION("authenticate", Authenticate),
65         DECLARE_NAPI_FUNCTION("getAllAccessibleAccounts", GetAllAccessibleAccounts),
66         DECLARE_NAPI_FUNCTION("getAllAccounts", GetAllAccounts),
67         DECLARE_NAPI_FUNCTION("getAccountCredential", GetAccountCredential),
68         DECLARE_NAPI_FUNCTION("getAccountExtraInfo", GetAccountExtraInfo),
69         DECLARE_NAPI_FUNCTION("getAssociatedData", GetAssociatedData),
70         DECLARE_NAPI_FUNCTION("getAssociatedDataSync", GetAssociatedDataSync),
71         DECLARE_NAPI_FUNCTION("getOAuthToken", GetOAuthToken),
72         DECLARE_NAPI_FUNCTION("setOAuthToken", SetOAuthToken),
73         DECLARE_NAPI_FUNCTION("deleteOAuthToken", DeleteOAuthToken),
74         DECLARE_NAPI_FUNCTION("getAuthenticatorInfo", GetAuthenticatorInfo),
75         DECLARE_NAPI_FUNCTION("getAllOAuthTokens", GetAllOAuthTokens),
76         DECLARE_NAPI_FUNCTION("getOAuthList", GetOAuthList),
77         DECLARE_NAPI_FUNCTION("setOAuthTokenVisibility", SetOAuthTokenVisibility),
78         DECLARE_NAPI_FUNCTION("checkOAuthTokenVisibility", CheckOAuthTokenVisibility),
79         DECLARE_NAPI_FUNCTION("getAuthenticatorCallback", GetAuthenticatorCallback),
80         DECLARE_NAPI_FUNCTION("on", Subscribe),
81         DECLARE_NAPI_FUNCTION("off", Unsubscribe),
82         DECLARE_NAPI_FUNCTION("checkAppAccess", CheckAppAccess),
83         DECLARE_NAPI_FUNCTION("checkAccountLabels", CheckAccountLabels),
84         DECLARE_NAPI_FUNCTION("setAuthenticatorProperties", SetAuthenticatorProperties),
85         DECLARE_NAPI_FUNCTION("verifyCredential", VerifyCredential),
86         DECLARE_NAPI_FUNCTION("selectAccountsByOptions", SelectAccountsByOptions),
87         DECLARE_NAPI_FUNCTION("deleteAccountCredential", DeleteAccountCredential),
88         // new api
89         DECLARE_NAPI_FUNCTION("createAccount", CreateAccount),
90         DECLARE_NAPI_FUNCTION("createAccountImplicitly", CreateAccountImplicitly),
91         DECLARE_NAPI_FUNCTION("auth", Auth),
92         DECLARE_NAPI_FUNCTION("removeAccount", RemoveAccount),
93         DECLARE_NAPI_FUNCTION("setAppAccess", SetAppAccess),
94         DECLARE_NAPI_FUNCTION("setCredential", SetCredential),
95         DECLARE_NAPI_FUNCTION("getCredential", GetCredential),
96         DECLARE_NAPI_FUNCTION("deleteCredential", DeleteCredential),
97         DECLARE_NAPI_FUNCTION("setDataSyncEnabled", SetDataSyncEnabled),
98         DECLARE_NAPI_FUNCTION("checkDataSyncEnabled", CheckDataSyncEnabled),
99         DECLARE_NAPI_FUNCTION("setCustomData", SetCustomData),
100         DECLARE_NAPI_FUNCTION("getCustomData", GetCustomData),
101         DECLARE_NAPI_FUNCTION("getCustomDataSync", GetAssociatedDataSync),
102         DECLARE_NAPI_FUNCTION("getAccountsByOwner", GetAccountsByOwner),
103         DECLARE_NAPI_FUNCTION("getAuthToken", GetAuthToken),
104         DECLARE_NAPI_FUNCTION("setAuthToken", SetAuthToken),
105         DECLARE_NAPI_FUNCTION("deleteAuthToken", DeleteAuthToken),
106         DECLARE_NAPI_FUNCTION("getAllAuthTokens", GetAllAuthTokens),
107         DECLARE_NAPI_FUNCTION("getAuthList", GetAuthList),
108         DECLARE_NAPI_FUNCTION("setAuthTokenVisibility", SetAuthTokenVisibility),
109         DECLARE_NAPI_FUNCTION("checkAuthTokenVisibility", CheckAuthTokenVisibility),
110         DECLARE_NAPI_FUNCTION("getAuthCallback", GetAuthCallback),
111         DECLARE_NAPI_FUNCTION("queryAuthenticatorInfo", QueryAuthenticatorInfo)
112     };
113     napi_value cons = nullptr;
114     NAPI_CALL(env, napi_define_class(env, APP_ACCOUNT_CLASS_NAME.c_str(), APP_ACCOUNT_CLASS_NAME.size(),
115         JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons));
116     NAPI_CALL(env, napi_create_reference(env, cons, 1, &appAccountRef_));
117     NAPI_CALL(env, napi_set_named_property(env, exports, APP_ACCOUNT_CLASS_NAME.c_str(), cons));
118     return exports;
119 }
120 
JsConstructor(napi_env env,napi_callback_info cbinfo)121 napi_value NapiAppAccount::JsConstructor(napi_env env, napi_callback_info cbinfo)
122 {
123     napi_value thisVar = nullptr;
124     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr));
125     return thisVar;
126 }
127 
CreateAppAccountManager(napi_env env,napi_callback_info cbInfo)128 napi_value NapiAppAccount::CreateAppAccountManager(napi_env env, napi_callback_info cbInfo)
129 {
130     napi_value instance = nullptr;
131     napi_value cons = nullptr;
132     if (napi_get_reference_value(env, appAccountRef_, &cons) != napi_ok) {
133         return nullptr;
134     }
135 
136     if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) {
137         return nullptr;
138     }
139 
140     AppAccountManager *objectInfo = new (std::nothrow) AppAccountManager();
141     if (objectInfo == nullptr) {
142         ACCOUNT_LOGE("failed to create AppAccountManager for insufficient memory");
143         return nullptr;
144     }
145     napi_status status = napi_wrap(env, instance, objectInfo,
146         [](napi_env env, void *data, void *hint) {
147             ACCOUNT_LOGI("js AppAccountManager instance garbage collection");
148             delete reinterpret_cast<AppAccountManager *>(data);
149         }, nullptr, nullptr);
150     if (status != napi_ok) {
151         ACCOUNT_LOGE("failed to wrap js instance with native object");
152         delete objectInfo;
153         return nullptr;
154     }
155     return instance;
156 }
157 
AddAccount(napi_env env,napi_callback_info cbInfo)158 napi_value NapiAppAccount::AddAccount(napi_env env, napi_callback_info cbInfo)
159 {
160     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
161     if (asyncContext == nullptr) {
162         ACCOUNT_LOGE("insufficient memory for asyncContext!");
163         return NapiGetNull(env);
164     }
165     asyncContext->env = env;
166     ParseContextWithExInfo(env, cbInfo, asyncContext);
167     napi_value result = nullptr;
168     if (asyncContext->callbackRef == nullptr) {
169         napi_create_promise(env, &asyncContext->deferred, &result);
170     } else {
171         napi_get_undefined(env, &result);
172     }
173     napi_value resource = nullptr;
174     napi_create_string_utf8(env, "AddAccountInternal", NAPI_AUTO_LENGTH, &resource);
175     napi_create_async_work(env,
176         nullptr,
177         resource,
178         [](napi_env env, void *data) {
179             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
180             asyncContext->errCode = AppAccountManager::AddAccount(asyncContext->name, asyncContext->extraInfo);
181         },
182         [](napi_env env, napi_status status, void *data) {
183             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
184             ProcessCallbackOrPromise(env, asyncContext,
185                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode)), NapiGetNull(env));
186             napi_delete_async_work(env, asyncContext->work);
187             delete asyncContext;
188             asyncContext = nullptr;
189         },
190         reinterpret_cast<void *>(asyncContext),
191         &asyncContext->work);
192     napi_queue_async_work(env, asyncContext->work);
193     return result;
194 }
195 
CreateAccount(napi_env env,napi_callback_info cbInfo)196 napi_value NapiAppAccount::CreateAccount(napi_env env, napi_callback_info cbInfo)
197 {
198     auto *context = new (std::nothrow) CreateAccountContext(env);
199     if (context == nullptr) {
200         ACCOUNT_LOGE("insufficient memory for asyncContext!");
201         return NapiGetNull(env);
202     }
203     if (!ParseContextForCreateAccount(env, cbInfo, context)) {
204         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
205         delete context;
206         return NapiGetNull(env);
207     }
208     napi_value result = nullptr;
209     if (context->callbackRef == nullptr) {
210         napi_create_promise(env, &context->deferred, &result);
211     } else {
212         napi_get_undefined(env, &result);
213     }
214     napi_value resource = nullptr;
215     napi_create_string_utf8(env, "CreateAccount", NAPI_AUTO_LENGTH, &resource);
216     napi_create_async_work(env, nullptr, resource,
217         [](napi_env env, void *data) {
218             CreateAccountContext *context = reinterpret_cast<CreateAccountContext *>(data);
219             context->errCode = AppAccountManager::CreateAccount(context->name, context->options);
220         },
221         [](napi_env env, napi_status status, void *data) {
222             CreateAccountContext *context = reinterpret_cast<CreateAccountContext *>(data);
223             ProcessCallbackOrPromise(env, context,
224                 GenerateBusinessError(env, context->errCode), NapiGetNull(env));
225             napi_delete_async_work(env, context->work);
226             delete context;
227             context = nullptr;
228         }, reinterpret_cast<void *>(context), &context->work);
229     napi_queue_async_work(env, context->work);
230     return result;
231 }
232 
CreateAccountImplicitly(napi_env env,napi_callback_info cbInfo)233 napi_value NapiAppAccount::CreateAccountImplicitly(napi_env env, napi_callback_info cbInfo)
234 {
235     auto *context = new (std::nothrow) CreateAccountImplicitlyContext(env);
236     if (context == nullptr) {
237         ACCOUNT_LOGE("insufficient memory for context!");
238         return NapiGetNull(env);
239     }
240     if (!ParseContextForCreateAccountImplicitly(env, cbInfo, context)) {
241         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
242         delete context;
243         return NapiGetNull(env);
244     }
245     context->appAccountMgrCb = new (std::nothrow) AppAccountManagerCallback(env, context->callback);
246     if (context->appAccountMgrCb == nullptr) {
247         ACCOUNT_LOGE("insufficient memory for AppAccountManagerCallback!");
248         delete context;
249         return NapiGetNull(env);
250     }
251     napi_value resourceName = nullptr;
252     napi_create_string_latin1(env, "CreateAccountImplicitly", NAPI_AUTO_LENGTH, &resourceName);
253     napi_create_async_work(env, nullptr, resourceName,
254         [](napi_env env, void *data) {
255             auto context = reinterpret_cast<CreateAccountImplicitlyContext *>(data);
256             ErrCode errCode = AppAccountManager::CreateAccountImplicitly(context->owner,
257                 context->options, context->appAccountMgrCb);
258             context->errCode = ConvertToJSErrCode(errCode);
259         },
260         [](napi_env env, napi_status status, void *data) {
261             auto context = reinterpret_cast<CreateAccountImplicitlyContext *>(data);
262             AAFwk::Want errResult;
263             if ((context->errCode != 0) && (context->appAccountMgrCb != nullptr)) {
264                 context->appAccountMgrCb->OnResult(context->errCode, errResult);
265             }
266             napi_delete_async_work(env, context->work);
267             delete context;
268             context = nullptr;
269         }, reinterpret_cast<void *>(context), &context->work);
270     napi_queue_async_work(env, context->work);
271     return NapiGetNull(env);
272 }
273 
AddAccountImplicitly(napi_env env,napi_callback_info cbInfo)274 napi_value NapiAppAccount::AddAccountImplicitly(napi_env env, napi_callback_info cbInfo)
275 {
276     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
277     if (asyncContext == nullptr) {
278         ACCOUNT_LOGE("insufficient memory for asyncContext!");
279         return NapiGetNull(env);
280     }
281     asyncContext->env = env;
282     ParseContextForAuthenticate(env, cbInfo, asyncContext, ARGS_SIZE_FOUR);
283     if (asyncContext->appAccountMgrCb == nullptr) {
284         ACCOUNT_LOGE("insufficient memory for AppAccountManagerCallback!");
285         delete asyncContext;
286         return NapiGetNull(env);
287     }
288     napi_value resourceName = nullptr;
289     NAPI_CALL(env, napi_create_string_latin1(env, "AddAccountImplicitly", NAPI_AUTO_LENGTH, &resourceName));
290     NAPI_CALL(env,
291         napi_create_async_work(env,
292             nullptr,
293             resourceName,
294             [](napi_env env, void *data) {
295                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
296                 ErrCode errCode = AppAccountManager::AddAccountImplicitly(asyncContext->owner,
297                     asyncContext->authType, asyncContext->options, asyncContext->appAccountMgrCb);
298                 asyncContext->errCode = ConvertToJSErrCodeV8(errCode);
299             },
300             [](napi_env env, napi_status status, void *data) {
301                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
302                 AAFwk::Want errResult;
303                 if ((asyncContext->errCode != 0) && (asyncContext->appAccountMgrCb != nullptr)) {
304                     asyncContext->appAccountMgrCb->OnResult(asyncContext->errCode, errResult);
305                 }
306                 napi_delete_async_work(env, asyncContext->work);
307                 delete asyncContext;
308                 asyncContext = nullptr;
309             },
310             reinterpret_cast<void *>(asyncContext),
311             &asyncContext->work));
312     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
313     return NapiGetNull(env);
314 }
315 
DeleteAccount(napi_env env,napi_callback_info cbInfo)316 napi_value NapiAppAccount::DeleteAccount(napi_env env, napi_callback_info cbInfo)
317 {
318     return RemoveAccountInternal(env, cbInfo, false);
319 }
320 
RemoveAccount(napi_env env,napi_callback_info cbInfo)321 napi_value NapiAppAccount::RemoveAccount(napi_env env, napi_callback_info cbInfo)
322 {
323     return RemoveAccountInternal(env, cbInfo, true);
324 }
325 
RemoveAccountInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)326 napi_value NapiAppAccount::RemoveAccountInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
327 {
328     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
329     if (asyncContext == nullptr) {
330         ACCOUNT_LOGE("insufficient memory for asyncContext!");
331         return NapiGetNull(env);
332     }
333     asyncContext->env = env;
334     asyncContext->throwErr = isThrowable;
335     if ((!ParseContextWithTwoPara(env, cbInfo, asyncContext)) && isThrowable) {
336         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
337         delete asyncContext;
338         return NapiGetNull(env);
339     }
340 
341     napi_value result = nullptr;
342     if (asyncContext->callbackRef == nullptr) {
343         napi_create_promise(env, &asyncContext->deferred, &result);
344     } else {
345         napi_get_undefined(env, &result);
346     }
347 
348     napi_value resource = nullptr;
349     napi_create_string_utf8(env, "DeleteAccount", NAPI_AUTO_LENGTH, &resource);
350 
351     napi_create_async_work(env,
352         nullptr,
353         resource,
354         [](napi_env env, void *data) {
355             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
356             asyncContext->errCode = AppAccountManager::DeleteAccount(asyncContext->name);
357         },
358         [](napi_env env, napi_status status, void *data) {
359             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
360             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
361                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
362             ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
363             napi_delete_async_work(env, asyncContext->work);
364             delete asyncContext;
365             asyncContext = nullptr;
366         },
367         reinterpret_cast<void *>(asyncContext),
368         &asyncContext->work);
369     napi_queue_async_work(env, asyncContext->work);
370     return result;
371 }
372 
DisableAppAccess(napi_env env,napi_callback_info cbInfo)373 napi_value NapiAppAccount::DisableAppAccess(napi_env env, napi_callback_info cbInfo)
374 {
375     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
376     if (asyncContext == nullptr) {
377         ACCOUNT_LOGE("insufficient memory for asyncContext!");
378         return NapiGetNull(env);
379     }
380     asyncContext->env = env;
381     ParseContextWithBdName(env, cbInfo, asyncContext);
382     napi_value result = nullptr;
383     if (asyncContext->callbackRef == nullptr) {
384         napi_create_promise(env, &asyncContext->deferred, &result);
385     } else {
386         napi_get_undefined(env, &result);
387     }
388     napi_value resource = nullptr;
389     napi_create_string_utf8(env, "DisableAppAccess", NAPI_AUTO_LENGTH, &resource);
390     napi_create_async_work(env,
391         nullptr,
392         resource,
393         [](napi_env env, void *data) {
394             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
395             asyncContext->errCode = AppAccountManager::DisableAppAccess(asyncContext->name, asyncContext->bundleName);
396         },
397         [](napi_env env, napi_status status, void *data) {
398             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
399             ProcessCallbackOrPromise(env, asyncContext,
400                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode)), NapiGetNull(env));
401             napi_delete_async_work(env, asyncContext->work);
402             delete asyncContext;
403             asyncContext = nullptr;
404         },
405         reinterpret_cast<void *>(asyncContext),
406         &asyncContext->work);
407     napi_queue_async_work(env, asyncContext->work);
408     return result;
409 }
410 
EnableAppAccess(napi_env env,napi_callback_info cbInfo)411 napi_value NapiAppAccount::EnableAppAccess(napi_env env, napi_callback_info cbInfo)
412 {
413     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
414     if (asyncContext == nullptr) {
415         ACCOUNT_LOGE("insufficient memory for asyncContext!");
416         return NapiGetNull(env);
417     }
418     asyncContext->env = env;
419     ParseContextWithBdName(env, cbInfo, asyncContext);
420     napi_value result = nullptr;
421     if (asyncContext->callbackRef == nullptr) {
422         napi_create_promise(env, &asyncContext->deferred, &result);
423     } else {
424         napi_get_undefined(env, &result);
425     }
426     napi_value resource = nullptr;
427     napi_create_string_utf8(env, "EnableAppAccess", NAPI_AUTO_LENGTH, &resource);
428     napi_create_async_work(env,
429         nullptr,
430         resource,
431         [](napi_env env, void *data) {
432             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
433             ErrCode errCode = AppAccountManager::EnableAppAccess(asyncContext->name, asyncContext->bundleName);
434             asyncContext->errCode = ConvertToJSErrCode(errCode);
435         },
436         [](napi_env env, napi_status status, void *data) {
437             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
438             ProcessCallbackOrPromise(env, asyncContext,
439                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode)), NapiGetNull(env));
440             napi_delete_async_work(env, asyncContext->work);
441             delete asyncContext;
442             asyncContext = nullptr;
443         },
444         reinterpret_cast<void *>(asyncContext),
445         &asyncContext->work);
446     napi_queue_async_work(env, asyncContext->work);
447     return result;
448 }
449 
SetAppAccess(napi_env env,napi_callback_info cbInfo)450 napi_value NapiAppAccount::SetAppAccess(napi_env env, napi_callback_info cbInfo)
451 {
452     auto *context = new (std::nothrow) AppAccountAsyncContext();
453     if (context == nullptr) {
454         ACCOUNT_LOGE("insufficient memory for asyncContext!");
455         return NapiGetNull(env);
456     }
457     if (!ParseContextForSetAppAccess(env, cbInfo, context)) {
458         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
459         delete context;
460         return NapiGetNull(env);
461     }
462     context->env = env;
463     napi_value result = nullptr;
464     if (context->callbackRef == nullptr) {
465         napi_create_promise(env, &context->deferred, &result);
466     } else {
467         napi_get_undefined(env, &result);
468     }
469     napi_value resource = nullptr;
470     napi_create_string_utf8(env, "SetAppAccess", NAPI_AUTO_LENGTH, &resource);
471     napi_create_async_work(env, nullptr, resource,
472         [](napi_env env, void *data) {
473             AppAccountAsyncContext *context = reinterpret_cast<AppAccountAsyncContext *>(data);
474             context->errCode =
475                 AppAccountManager::SetAppAccess(context->name, context->bundleName, context->isAccessible);
476         },
477         [](napi_env env, napi_status status, void *data) {
478             AppAccountAsyncContext *context = reinterpret_cast<AppAccountAsyncContext *>(data);
479             ProcessCallbackOrPromise(env, context,
480                 GenerateBusinessError(env, context->errCode), NapiGetNull(env));
481             napi_delete_async_work(env, context->work);
482             delete context;
483             context = nullptr;
484         }, reinterpret_cast<void *>(context), &context->work);
485     napi_queue_async_work(env, context->work);
486     return result;
487 }
488 
CheckAppAccountSyncEnable(napi_env env,napi_callback_info cbInfo)489 napi_value NapiAppAccount::CheckAppAccountSyncEnable(napi_env env, napi_callback_info cbInfo)
490 {
491     return CheckDataSyncEnabledInternal(env, cbInfo, false);
492 }
493 
CheckDataSyncEnabled(napi_env env,napi_callback_info cbInfo)494 napi_value NapiAppAccount::CheckDataSyncEnabled(napi_env env, napi_callback_info cbInfo)
495 {
496     return CheckDataSyncEnabledInternal(env, cbInfo, true);
497 }
498 
CheckDataSyncEnabledInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)499 napi_value NapiAppAccount::CheckDataSyncEnabledInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
500 {
501     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
502     if (asyncContext == nullptr) {
503         ACCOUNT_LOGE("insufficient memory for asyncContext!");
504         return NapiGetNull(env);
505     }
506     asyncContext->env = env;
507     asyncContext->throwErr = isThrowable;
508     if ((!ParseContextWithTwoPara(env, cbInfo, asyncContext)) && isThrowable) {
509         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
510         delete asyncContext;
511         return NapiGetNull(env);
512     }
513 
514     napi_value result = nullptr;
515     if (asyncContext->callbackRef == nullptr) {
516         napi_create_promise(env, &asyncContext->deferred, &result);
517     } else {
518         napi_get_undefined(env, &result);
519     }
520 
521     napi_value resource = nullptr;
522     napi_create_string_utf8(env, "CheckAppAccountSyncEnable", NAPI_AUTO_LENGTH, &resource);
523 
524     napi_create_async_work(env,
525         nullptr,
526         resource,
527         [](napi_env env, void *data) {
528             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
529             asyncContext->errCode =
530                 AppAccountManager::CheckAppAccountSyncEnable(asyncContext->name, asyncContext->result);
531         },
532         [](napi_env env, napi_status status, void *data) {
533             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
534             napi_value boolVal = nullptr;
535             napi_get_boolean(env, asyncContext->result, &boolVal);
536             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
537                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
538             ProcessCallbackOrPromise(env, asyncContext, err, boolVal);
539             napi_delete_async_work(env, asyncContext->work);
540             delete asyncContext;
541             asyncContext = nullptr;
542         },
543         reinterpret_cast<void *>(asyncContext),
544         &asyncContext->work);
545     napi_queue_async_work(env, asyncContext->work);
546     return result;
547 }
548 
SetAccountCredential(napi_env env,napi_callback_info cbInfo)549 napi_value NapiAppAccount::SetAccountCredential(napi_env env, napi_callback_info cbInfo)
550 {
551     return SetCredentialInternal(env, cbInfo, false);
552 }
553 
SetCredential(napi_env env,napi_callback_info cbInfo)554 napi_value NapiAppAccount::SetCredential(napi_env env, napi_callback_info cbInfo)
555 {
556     return SetCredentialInternal(env, cbInfo, true);
557 }
558 
SetCredentialInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)559 napi_value NapiAppAccount::SetCredentialInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
560 {
561     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
562     if (asyncContext == nullptr) {
563         ACCOUNT_LOGE("insufficient memory for asyncContext!");
564         return NapiGetNull(env);
565     }
566     asyncContext->env = env;
567     asyncContext->throwErr = isThrowable;
568     if ((!ParseContextToSetCredential(env, cbInfo, asyncContext)) && isThrowable) {
569         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
570         delete asyncContext;
571         return NapiGetNull(env);
572     }
573 
574     napi_value result = nullptr;
575     if (asyncContext->callbackRef == nullptr) {
576         napi_create_promise(env, &asyncContext->deferred, &result);
577     } else {
578         napi_get_undefined(env, &result);
579     }
580 
581     napi_value resource = nullptr;
582     napi_create_string_utf8(env, "SetAccountCredential", NAPI_AUTO_LENGTH, &resource);
583 
584     napi_create_async_work(env, nullptr, resource,
585         [](napi_env env, void *data) {
586             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
587             if ((!asyncContext->throwErr) && (!CheckSpecialCharacters(asyncContext->name))) {
588                 asyncContext->errCode = ERR_APPACCOUNT_KIT_INVALID_PARAMETER;
589                 return;
590             }
591             asyncContext->errCode = AppAccountManager::SetAccountCredential(
592                 asyncContext->name, asyncContext->credentialType, asyncContext->credential);
593         },
594         [](napi_env env, napi_status status, void *data) {
595             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
596             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
597                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
598             ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
599             napi_delete_async_work(env, asyncContext->work);
600             delete asyncContext;
601             asyncContext = nullptr;
602         },
603         reinterpret_cast<void *>(asyncContext),
604         &asyncContext->work);
605     napi_queue_async_work(env, asyncContext->work);
606     return result;
607 }
608 
SetAccountExtraInfo(napi_env env,napi_callback_info cbInfo)609 napi_value NapiAppAccount::SetAccountExtraInfo(napi_env env, napi_callback_info cbInfo)
610 {
611     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
612     if (asyncContext == nullptr) {
613         ACCOUNT_LOGE("insufficient memory for asyncContext!");
614         return NapiGetNull(env);
615     }
616     asyncContext->env = env;
617     ParseContextForSetExInfo(env, cbInfo, asyncContext);
618 
619     napi_value result = nullptr;
620     if (asyncContext->callbackRef == nullptr) {
621         napi_create_promise(env, &asyncContext->deferred, &result);
622     } else {
623         napi_get_undefined(env, &result);
624     }
625 
626     napi_value resource = nullptr;
627     napi_create_string_utf8(env, "SetAccountExtraInfo", NAPI_AUTO_LENGTH, &resource);
628 
629     napi_create_async_work(env,
630         nullptr,
631         resource,
632         [](napi_env env, void *data) {
633             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
634             asyncContext->errCode = AppAccountManager::SetAccountExtraInfo(
635                 asyncContext->name, asyncContext->extraInfo);
636         },
637         [](napi_env env, napi_status status, void *data) {
638             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
639             ProcessCallbackOrPromise(env, asyncContext,
640                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode)), NapiGetNull(env));
641             napi_delete_async_work(env, asyncContext->work);
642             delete asyncContext;
643             asyncContext = nullptr;
644         },
645         reinterpret_cast<void *>(asyncContext),
646         &asyncContext->work);
647     napi_queue_async_work(env, asyncContext->work);
648     return result;
649 }
650 
SetAppAccountSyncEnable(napi_env env,napi_callback_info cbInfo)651 napi_value NapiAppAccount::SetAppAccountSyncEnable(napi_env env, napi_callback_info cbInfo)
652 {
653     return SetDataSyncEnabledInternal(env, cbInfo, false);
654 }
655 
SetDataSyncEnabled(napi_env env,napi_callback_info cbInfo)656 napi_value NapiAppAccount::SetDataSyncEnabled(napi_env env, napi_callback_info cbInfo)
657 {
658     return SetDataSyncEnabledInternal(env, cbInfo, true);
659 }
660 
SetDataSyncEnabledInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)661 napi_value NapiAppAccount::SetDataSyncEnabledInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
662 {
663     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
664     if (asyncContext == nullptr) {
665         ACCOUNT_LOGE("insufficient memory for asyncContext!");
666         return NapiGetNull(env);
667     }
668     asyncContext->env = env;
669     asyncContext->throwErr = isThrowable;
670     if ((!ParseContextWithIsEnable(env, cbInfo, asyncContext)) && isThrowable) {
671         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
672         delete asyncContext;
673         return NapiGetNull(env);
674     }
675 
676     napi_value result = nullptr;
677     if (asyncContext->callbackRef == nullptr) {
678         napi_create_promise(env, &asyncContext->deferred, &result);
679     } else {
680         napi_get_undefined(env, &result);
681     }
682 
683     napi_value resource = nullptr;
684     napi_create_string_utf8(env, "SetAppAccountSyncEnable", NAPI_AUTO_LENGTH, &resource);
685 
686     napi_create_async_work(env, nullptr, resource,
687         [](napi_env env, void *data) {
688             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
689             if ((!asyncContext->throwErr) && (!CheckSpecialCharacters(asyncContext->name))) {
690                 asyncContext->errCode = ERR_APPACCOUNT_KIT_INVALID_PARAMETER;
691                 return;
692             }
693             asyncContext->errCode =
694                 AppAccountManager::SetAppAccountSyncEnable(asyncContext->name, asyncContext->isEnable);
695         },
696         [](napi_env env, napi_status status, void *data) {
697             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
698             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
699                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
700             ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
701             napi_delete_async_work(env, asyncContext->work);
702             delete asyncContext;
703             asyncContext = nullptr;
704         },
705         reinterpret_cast<void *>(asyncContext),
706         &asyncContext->work);
707     napi_queue_async_work(env, asyncContext->work);
708     return result;
709 }
710 
SetAssociatedData(napi_env env,napi_callback_info cbInfo)711 napi_value NapiAppAccount::SetAssociatedData(napi_env env, napi_callback_info cbInfo)
712 {
713     return SetCustomDataInternal(env, cbInfo, false);
714 }
715 
SetCustomData(napi_env env,napi_callback_info cbInfo)716 napi_value NapiAppAccount::SetCustomData(napi_env env, napi_callback_info cbInfo)
717 {
718     return SetCustomDataInternal(env, cbInfo, true);
719 }
720 
SetCustomDataInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)721 napi_value NapiAppAccount::SetCustomDataInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
722 {
723     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
724     if (asyncContext == nullptr) {
725         ACCOUNT_LOGE("insufficient memory for asyncContext!");
726         return NapiGetNull(env);
727     }
728     asyncContext->env = env;
729     asyncContext->throwErr = isThrowable;
730     if ((!ParseContextForAssociatedData(env, cbInfo, asyncContext)) && isThrowable) {
731         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
732         delete asyncContext;
733         return NapiGetNull(env);
734     }
735 
736     napi_value result = nullptr;
737     if (asyncContext->callbackRef == nullptr) {
738         napi_create_promise(env, &asyncContext->deferred, &result);
739     } else {
740         napi_get_undefined(env, &result);
741     }
742 
743     napi_value resource = nullptr;
744     napi_create_string_utf8(env, "SetAssociatedData", NAPI_AUTO_LENGTH, &resource);
745 
746     napi_create_async_work(env, nullptr, resource,
747         [](napi_env env, void *data) {
748             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
749             if ((!asyncContext->throwErr) && (!CheckSpecialCharacters(asyncContext->name))) {
750                 asyncContext->errCode = ERR_APPACCOUNT_KIT_INVALID_PARAMETER;
751                 return;
752             }
753             asyncContext->errCode =
754                 AppAccountManager::SetAssociatedData(asyncContext->name, asyncContext->key, asyncContext->value);
755         },
756         [](napi_env env, napi_status status, void *data) {
757             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
758             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
759                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
760             ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
761             napi_delete_async_work(env, asyncContext->work);
762             delete asyncContext;
763             asyncContext = nullptr;
764         }, reinterpret_cast<void *>(asyncContext), &asyncContext->work);
765     napi_queue_async_work(env, asyncContext->work);
766     return result;
767 }
768 
GetAllAccessibleAccounts(napi_env env,napi_callback_info cbInfo)769 napi_value NapiAppAccount::GetAllAccessibleAccounts(napi_env env, napi_callback_info cbInfo)
770 {
771     return GetAllAccessibleAccountsInternal(env, cbInfo, false);
772 }
773 
GetAllAccessibleAccountsInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)774 napi_value NapiAppAccount::GetAllAccessibleAccountsInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
775 {
776     auto *asyncContext = new (std::nothrow) GetAccountsAsyncContext();
777     if (asyncContext == nullptr) {
778         ACCOUNT_LOGE("insufficient memory for asyncContext!");
779         return NapiGetNull(env);
780     }
781     asyncContext->env = env;
782     asyncContext->throwErr = isThrowable;
783     if ((!ParseContextCBArray(env, cbInfo, asyncContext)) && isThrowable) {
784         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
785         delete asyncContext;
786         return NapiGetNull(env);
787     }
788 
789     napi_value result = nullptr;
790     if (asyncContext->callbackRef == nullptr) {
791         napi_create_promise(env, &asyncContext->deferred, &result);
792     } else {
793         napi_get_undefined(env, &result);
794     }
795 
796     napi_value resource = nullptr;
797     napi_create_string_utf8(env, "GetAllAccessibleAccounts", NAPI_AUTO_LENGTH, &resource);
798 
799     napi_create_async_work(env, nullptr, resource,
800         [](napi_env env, void *data) {
801             GetAccountsAsyncContext *asyncContext = reinterpret_cast<GetAccountsAsyncContext *>(data);
802             if (asyncContext->throwErr) {
803                 asyncContext->errCode =
804                     AppAccountManager::QueryAllAccessibleAccounts(asyncContext->owner, asyncContext->appAccounts);
805             } else {
806                 asyncContext->errCode =
807                     AppAccountManager::GetAllAccessibleAccounts(asyncContext->appAccounts);
808             }
809         },
810         [](napi_env env, napi_status status, void *data) {
811             GetAccountsAsyncContext *asyncContext = reinterpret_cast<GetAccountsAsyncContext *>(data);
812             napi_value arrVal = nullptr;
813             GetAppAccountInfoForResult(env, asyncContext->appAccounts, arrVal);
814             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
815                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
816             ProcessCallbackOrPromise(env, asyncContext, err, arrVal);
817             napi_delete_async_work(env, asyncContext->work);
818             delete asyncContext;
819             asyncContext = nullptr;
820         },
821         reinterpret_cast<void *>(asyncContext),
822         &asyncContext->work);
823     napi_queue_async_work(env, asyncContext->work);
824     return result;
825 }
826 
GetAllAccounts(napi_env env,napi_callback_info cbInfo)827 napi_value NapiAppAccount::GetAllAccounts(napi_env env, napi_callback_info cbInfo)
828 {
829     size_t argc = ARGS_SIZE_TWO;
830     napi_value argv[ARGS_SIZE_TWO] = {0};
831     napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr);
832     if (argc == 0) {
833         return GetAllAccessibleAccountsInternal(env, cbInfo, true);
834     }
835     napi_valuetype valueType = napi_undefined;
836     napi_typeof(env, argv[0], &valueType);
837     if (valueType == napi_function) {
838         return GetAllAccessibleAccountsInternal(env, cbInfo, true);
839     }
840     return GetAccountsByOwnerInternal(env, cbInfo, false);
841 }
842 
GetAccountsByOwner(napi_env env,napi_callback_info cbInfo)843 napi_value NapiAppAccount::GetAccountsByOwner(napi_env env, napi_callback_info cbInfo)
844 {
845     return GetAccountsByOwnerInternal(env, cbInfo, true);
846 }
847 
GetAccountsByOwnerInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)848 napi_value NapiAppAccount::GetAccountsByOwnerInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
849 {
850     auto *asyncContext = new (std::nothrow) GetAccountsAsyncContext();
851     if (asyncContext == nullptr) {
852         ACCOUNT_LOGE("insufficient memory for asyncContext!");
853         return NapiGetNull(env);
854     }
855     asyncContext->env = env;
856     asyncContext->throwErr = isThrowable;
857     if ((!ParseContextWithStrCBArray(env, cbInfo, asyncContext)) && isThrowable) {
858         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
859         delete asyncContext;
860         return NapiGetNull(env);
861     }
862 
863     napi_value result = nullptr;
864     if (asyncContext->callbackRef == nullptr) {
865         napi_create_promise(env, &asyncContext->deferred, &result);
866     } else {
867         napi_get_undefined(env, &result);
868     }
869 
870     napi_value resource = nullptr;
871     napi_create_string_utf8(env, "GetAllAccounts", NAPI_AUTO_LENGTH, &resource);
872 
873     napi_create_async_work(env, nullptr, resource,
874         [](napi_env env, void *data) {
875             GetAccountsAsyncContext *asyncContext = reinterpret_cast<GetAccountsAsyncContext *>(data);
876             if (!asyncContext->throwErr) {
877                 asyncContext->errCode =
878                     AppAccountManager::GetAllAccounts(asyncContext->owner, asyncContext->appAccounts);
879                 return;
880             }
881             if (!asyncContext->owner.empty()) {
882                 asyncContext->errCode =
883                     AppAccountManager::QueryAllAccessibleAccounts(asyncContext->owner, asyncContext->appAccounts);
884                 return;
885             }
886             asyncContext->errCode = ERR_APPACCOUNT_KIT_INVALID_PARAMETER;
887         },
888         [](napi_env env, napi_status status, void *data) {
889             GetAccountsAsyncContext *asyncContext = reinterpret_cast<GetAccountsAsyncContext *>(data);
890             napi_value arrVal = nullptr;
891             GetAppAccountInfoForResult(env, asyncContext->appAccounts, arrVal);
892             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
893                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
894             ProcessCallbackOrPromise(env, asyncContext, err, arrVal);
895             napi_delete_async_work(env, asyncContext->work);
896             delete asyncContext;
897             asyncContext = nullptr;
898         }, reinterpret_cast<void *>(asyncContext), &asyncContext->work);
899     napi_queue_async_work(env, asyncContext->work);
900     return result;
901 }
902 
GetAccountCredential(napi_env env,napi_callback_info cbInfo)903 napi_value NapiAppAccount::GetAccountCredential(napi_env env, napi_callback_info cbInfo)
904 {
905     return GetCredentialInternal(env, cbInfo, false);
906 }
907 
GetCredential(napi_env env,napi_callback_info cbInfo)908 napi_value NapiAppAccount::GetCredential(napi_env env, napi_callback_info cbInfo)
909 {
910     return GetCredentialInternal(env, cbInfo, true);
911 }
912 
GetCredentialInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)913 napi_value NapiAppAccount::GetCredentialInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
914 {
915     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
916     if (asyncContext == nullptr) {
917         ACCOUNT_LOGE("insufficient memory for asyncContext!");
918         return NapiGetNull(env);
919     }
920     asyncContext->env = env;
921     asyncContext->throwErr = isThrowable;
922     if ((!ParseContextWithCredentialType(env, cbInfo, asyncContext)) && isThrowable) {
923         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
924         delete asyncContext;
925         return NapiGetNull(env);
926     }
927     napi_value result = nullptr;
928     if (asyncContext->callbackRef == nullptr) {
929         napi_create_promise(env, &asyncContext->deferred, &result);
930     } else {
931         napi_get_undefined(env, &result);
932     }
933 
934     napi_value resource = nullptr;
935     napi_create_string_utf8(env, "GetAccountCredential", NAPI_AUTO_LENGTH, &resource);
936 
937     napi_create_async_work(env,
938         nullptr,
939         resource,
940         [](napi_env env, void *data) {
941             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
942             asyncContext->errCode = AppAccountManager::GetAccountCredential(
943                 asyncContext->name, asyncContext->credentialType, asyncContext->credential);
944         },
945         [](napi_env env, napi_status status, void *data) {
946             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
947             napi_value strVal = nullptr;
948             napi_create_string_utf8(env, asyncContext->credential.c_str(), NAPI_AUTO_LENGTH, &strVal);
949             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
950                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
951             ProcessCallbackOrPromise(env, asyncContext, err, strVal);
952             napi_delete_async_work(env, asyncContext->work);
953             delete asyncContext;
954             asyncContext = nullptr;
955         },
956         reinterpret_cast<void *>(asyncContext),
957         &asyncContext->work);
958     napi_queue_async_work(env, asyncContext->work);
959     return result;
960 }
961 
GetAccountExtraInfo(napi_env env,napi_callback_info cbInfo)962 napi_value NapiAppAccount::GetAccountExtraInfo(napi_env env, napi_callback_info cbInfo)
963 {
964     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
965     if (asyncContext == nullptr) {
966         ACCOUNT_LOGE("insufficient memory for asyncContext!");
967         return NapiGetNull(env);
968     }
969     asyncContext->env = env;
970     ParseContextWithTwoPara(env, cbInfo, asyncContext);
971     napi_value result = nullptr;
972     if (asyncContext->callbackRef == nullptr) {
973         napi_create_promise(env, &asyncContext->deferred, &result);
974     } else {
975         napi_get_undefined(env, &result);
976     }
977 
978     napi_value resource = nullptr;
979     napi_create_string_utf8(env, "GetAccountExtraInfo", NAPI_AUTO_LENGTH, &resource);
980 
981     napi_create_async_work(env,
982         nullptr,
983         resource,
984         [](napi_env env, void *data) {
985             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
986             asyncContext->errCode = AppAccountManager::GetAccountExtraInfo(
987                 asyncContext->name, asyncContext->extraInfo);
988         },
989         [](napi_env env, napi_status status, void *data) {
990             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
991             napi_value strVal = nullptr;
992             napi_create_string_utf8(env, asyncContext->extraInfo.c_str(), NAPI_AUTO_LENGTH, &strVal);
993             ProcessCallbackOrPromise(env, asyncContext,
994                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode)), strVal);
995             napi_delete_async_work(env, asyncContext->work);
996             delete asyncContext;
997             asyncContext = nullptr;
998         },
999         reinterpret_cast<void *>(asyncContext),
1000         &asyncContext->work);
1001     napi_queue_async_work(env, asyncContext->work);
1002     return result;
1003 }
1004 
GetAssociatedData(napi_env env,napi_callback_info cbInfo)1005 napi_value NapiAppAccount::GetAssociatedData(napi_env env, napi_callback_info cbInfo)
1006 {
1007     return GetCustomDataInternal(env, cbInfo, false);
1008 }
1009 
GetCustomData(napi_env env,napi_callback_info cbInfo)1010 napi_value NapiAppAccount::GetCustomData(napi_env env, napi_callback_info cbInfo)
1011 {
1012     return GetCustomDataInternal(env, cbInfo, true);
1013 }
1014 
GetCustomDataInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1015 napi_value NapiAppAccount::GetCustomDataInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1016 {
1017     auto *asyncContext = new (std::nothrow) AppAccountAsyncContext();
1018     if (asyncContext == nullptr) {
1019         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1020         return NapiGetNull(env);
1021     }
1022     asyncContext->env = env;
1023     asyncContext->throwErr = isThrowable;
1024     if ((!ParseContextToGetData(env, cbInfo, asyncContext)) && isThrowable) {
1025         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1026         delete asyncContext;
1027         return NapiGetNull(env);
1028     }
1029     napi_value result = nullptr;
1030     if (asyncContext->callbackRef == nullptr) {
1031         napi_create_promise(env, &asyncContext->deferred, &result);
1032     } else {
1033         napi_get_undefined(env, &result);
1034     }
1035     napi_value resource = nullptr;
1036     napi_create_string_utf8(env, "GetAssociatedData", NAPI_AUTO_LENGTH, &resource);
1037     napi_create_async_work(env,
1038         nullptr,
1039         resource,
1040         [](napi_env env, void *data) {
1041             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
1042             asyncContext->errCode =
1043                 AppAccountManager::GetAssociatedData(asyncContext->name, asyncContext->key, asyncContext->value);
1044         },
1045         [](napi_env env, napi_status status, void *data) {
1046             AppAccountAsyncContext *asyncContext = reinterpret_cast<AppAccountAsyncContext *>(data);
1047             napi_value strVal = NapiGetNull(env);
1048             napi_create_string_utf8(env, asyncContext->value.c_str(), NAPI_AUTO_LENGTH, &strVal);
1049             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1050                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1051             ProcessCallbackOrPromise(env, asyncContext, err, strVal);
1052             napi_delete_async_work(env, asyncContext->work);
1053             delete asyncContext;
1054             asyncContext = nullptr;
1055         },
1056         reinterpret_cast<void *>(asyncContext),
1057         &asyncContext->work);
1058     napi_queue_async_work(env, asyncContext->work);
1059     return result;
1060 }
1061 
GetAssociatedDataSync(napi_env env,napi_callback_info cbInfo)1062 napi_value NapiAppAccount::GetAssociatedDataSync(napi_env env, napi_callback_info cbInfo)
1063 {
1064     AppAccountAsyncContext asyncContext;
1065     if (!ParseContextToGetData(env, cbInfo, &asyncContext)) {
1066         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext.errMsg));
1067         return NapiGetNull(env);
1068     }
1069     napi_value result = nullptr;
1070     ErrCode errCode = AppAccountManager::GetAssociatedData(asyncContext.name, asyncContext.key, asyncContext.value);
1071     if (errCode == ERR_OK) {
1072         NAPI_CALL(env, napi_create_string_utf8(env, asyncContext.value.c_str(), NAPI_AUTO_LENGTH, &result));
1073     } else {
1074         napi_throw(env, GenerateBusinessError(env, errCode));
1075     }
1076     return result;
1077 }
1078 
Authenticate(napi_env env,napi_callback_info cbInfo)1079 napi_value NapiAppAccount::Authenticate(napi_env env, napi_callback_info cbInfo)
1080 {
1081     return AuthInternal(env, cbInfo, false);
1082 }
1083 
Auth(napi_env env,napi_callback_info cbInfo)1084 napi_value NapiAppAccount::Auth(napi_env env, napi_callback_info cbInfo)
1085 {
1086     return AuthInternal(env, cbInfo, true);
1087 }
1088 
AuthInternalExecuteCB(napi_env env,void * data)1089 void AuthInternalExecuteCB(napi_env env, void *data)
1090 {
1091     auto asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1092     if ((!asyncContext->throwErr) && (!CheckSpecialCharacters(asyncContext->name))) {
1093         asyncContext->errCode = ConvertToJSErrCodeV8(ERR_APPACCOUNT_KIT_INVALID_PARAMETER);
1094         return;
1095     }
1096     ErrCode errCode = AppAccountManager::Authenticate(asyncContext->name, asyncContext->owner,
1097         asyncContext->authType, asyncContext->options, asyncContext->appAccountMgrCb);
1098     asyncContext->errCode =
1099         asyncContext->throwErr ? ConvertToJSErrCode(errCode) : ConvertToJSErrCodeV8(errCode);
1100 }
1101 
AuthInternalCompletedCB(napi_env env,napi_status status,void * data)1102 void AuthInternalCompletedCB(napi_env env, napi_status status, void *data)
1103 {
1104     OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1105     AAFwk::Want errResult;
1106     if ((asyncContext->errCode != 0) && (asyncContext->appAccountMgrCb != nullptr)) {
1107         asyncContext->appAccountMgrCb->OnResult(asyncContext->errCode, errResult);
1108     }
1109     napi_delete_async_work(env, asyncContext->work);
1110     delete asyncContext;
1111     asyncContext = nullptr;
1112 }
1113 
AuthInternal(napi_env env,napi_callback_info cbInfo,bool isNewApi)1114 napi_value NapiAppAccount::AuthInternal(napi_env env, napi_callback_info cbInfo, bool isNewApi)
1115 {
1116     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1117     if (asyncContext == nullptr) {
1118         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1119         return NapiGetNull(env);
1120     }
1121     asyncContext->env = env;
1122     asyncContext->throwErr = isNewApi;
1123     if (isNewApi) {
1124         if (!ParseContextForAuth(env, cbInfo, asyncContext)) {
1125             napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1126             delete asyncContext;
1127             return NapiGetNull(env);
1128         }
1129         asyncContext->options.SetParam(Constants::API_V9, true);
1130     } else {
1131         ParseContextForAuthenticate(env, cbInfo, asyncContext, ARGS_SIZE_FIVE);
1132     }
1133     napi_value result = nullptr;
1134     if (asyncContext->appAccountMgrCb == nullptr) {
1135         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1136     } else {
1137         NAPI_CALL(env, napi_get_undefined(env, &result));
1138     }
1139     napi_value resourceName = nullptr;
1140     NAPI_CALL(env, napi_create_string_latin1(env, "Authenticate", NAPI_AUTO_LENGTH, &resourceName));
1141     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
1142         AuthInternalExecuteCB,
1143         AuthInternalCompletedCB,
1144         reinterpret_cast<void *>(asyncContext),
1145         &asyncContext->work));
1146     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1147     return NapiGetNull(env);
1148 }
1149 
GetOAuthToken(napi_env env,napi_callback_info cbInfo)1150 napi_value NapiAppAccount::GetOAuthToken(napi_env env, napi_callback_info cbInfo)
1151 {
1152     return GetAuthTokenInternal(env, cbInfo, false);
1153 }
1154 
GetAuthToken(napi_env env,napi_callback_info cbInfo)1155 napi_value NapiAppAccount::GetAuthToken(napi_env env, napi_callback_info cbInfo)
1156 {
1157     return GetAuthTokenInternal(env, cbInfo, true);
1158 }
1159 
GetAuthTokenInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1160 napi_value NapiAppAccount::GetAuthTokenInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1161 {
1162     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1163     if (asyncContext == nullptr) {
1164         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1165         return NapiGetNull(env);
1166     }
1167     asyncContext->env = env;
1168     asyncContext->throwErr = isThrowable;
1169     if ((!ParseContextForGetOAuthToken(env, cbInfo, asyncContext)) && isThrowable) {
1170         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1171         delete asyncContext;
1172         return NapiGetNull(env);
1173     }
1174     napi_value result = nullptr;
1175     if (asyncContext->callbackRef == nullptr) {
1176         napi_create_promise(env, &asyncContext->deferred, &result);
1177     } else {
1178         napi_get_undefined(env, &result);
1179     }
1180     napi_value resource = nullptr;
1181     napi_create_string_utf8(env, "GetOAuthToken", NAPI_AUTO_LENGTH, &resource);
1182     napi_create_async_work(env, nullptr, resource,
1183         [](napi_env env, void *data) {
1184             auto asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1185             if (asyncContext->throwErr) {
1186                 asyncContext->errCode = AppAccountManager::GetAuthToken(
1187                     asyncContext->name, asyncContext->owner, asyncContext->authType, asyncContext->token);
1188             } else {
1189                 asyncContext->errCode = AppAccountManager::GetOAuthToken(
1190                     asyncContext->name, asyncContext->owner, asyncContext->authType, asyncContext->token);
1191             }
1192         },
1193         [](napi_env env, napi_status status, void *data) {
1194             OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1195             napi_value strVal = nullptr;
1196             napi_create_string_utf8(env, asyncContext->token.c_str(), NAPI_AUTO_LENGTH, &strVal);
1197             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1198                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1199             ProcessCallbackOrPromise(env, asyncContext, err, strVal);
1200             napi_delete_async_work(env, asyncContext->work);
1201             delete asyncContext;
1202             asyncContext = nullptr;
1203         },
1204         reinterpret_cast<void *>(asyncContext),
1205         &asyncContext->work);
1206     napi_queue_async_work(env, asyncContext->work);
1207     return result;
1208 }
1209 
SetOAuthToken(napi_env env,napi_callback_info cbInfo)1210 napi_value NapiAppAccount::SetOAuthToken(napi_env env, napi_callback_info cbInfo)
1211 {
1212     return SetAuthTokenInternal(env, cbInfo, false);
1213 }
1214 
SetAuthToken(napi_env env,napi_callback_info cbInfo)1215 napi_value NapiAppAccount::SetAuthToken(napi_env env, napi_callback_info cbInfo)
1216 {
1217     return SetAuthTokenInternal(env, cbInfo, true);
1218 }
1219 
SetAuthTokenInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1220 napi_value NapiAppAccount::SetAuthTokenInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1221 {
1222     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1223     if (asyncContext == nullptr) {
1224         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1225         return NapiGetNull(env);
1226     }
1227     asyncContext->env = env;
1228     asyncContext->throwErr = isThrowable;
1229     if ((!ParseContextForSetOAuthToken(env, cbInfo, asyncContext)) && isThrowable) {
1230         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1231         delete asyncContext;
1232         return NapiGetNull(env);
1233     }
1234     napi_value result = nullptr;
1235     if (asyncContext->callbackRef == nullptr) {
1236         napi_create_promise(env, &asyncContext->deferred, &result);
1237     } else {
1238         napi_get_undefined(env, &result);
1239     }
1240     napi_value resource = nullptr;
1241     napi_create_string_utf8(env, "SetOAuthToken", NAPI_AUTO_LENGTH, &resource);
1242     napi_create_async_work(env, nullptr, resource,
1243         [](napi_env env, void *data) {
1244             OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1245             if ((!asyncContext->throwErr) && (!CheckSpecialCharacters(asyncContext->name))) {
1246                 asyncContext->errCode = ERR_APPACCOUNT_KIT_INVALID_PARAMETER;
1247                 return;
1248             }
1249             asyncContext->errCode = AppAccountManager::SetOAuthToken(
1250                 asyncContext->name, asyncContext->authType, asyncContext->token);
1251         },
1252         [](napi_env env, napi_status status, void *data) {
1253             OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1254             napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1255                 GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1256             ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
1257             napi_delete_async_work(env, asyncContext->work);
1258             delete asyncContext;
1259             asyncContext = nullptr;
1260         },
1261         reinterpret_cast<void *>(asyncContext),
1262         &asyncContext->work);
1263     napi_queue_async_work(env, asyncContext->work);
1264     return result;
1265 }
1266 
DeleteOAuthToken(napi_env env,napi_callback_info cbInfo)1267 napi_value NapiAppAccount::DeleteOAuthToken(napi_env env, napi_callback_info cbInfo)
1268 {
1269     return DeleteAuthTokenInternal(env, cbInfo, false);
1270 }
1271 
DeleteAuthToken(napi_env env,napi_callback_info cbInfo)1272 napi_value NapiAppAccount::DeleteAuthToken(napi_env env, napi_callback_info cbInfo)
1273 {
1274     return DeleteAuthTokenInternal(env, cbInfo, true);
1275 }
1276 
DeleteAuthTokenInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1277 napi_value NapiAppAccount::DeleteAuthTokenInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1278 {
1279     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1280     if (asyncContext == nullptr) {
1281         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1282         return NapiGetNull(env);
1283     }
1284     asyncContext->env = env;
1285     asyncContext->throwErr = isThrowable;
1286     if ((!ParseContextForDeleteOAuthToken(env, cbInfo, asyncContext)) && isThrowable) {
1287         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1288         delete asyncContext;
1289         return NapiGetNull(env);
1290     }
1291     napi_value result = nullptr;
1292     if (asyncContext->callbackRef == nullptr) {
1293         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1294     } else {
1295         NAPI_CALL(env, napi_get_undefined(env, &result));
1296     }
1297     napi_value resource = nullptr;
1298     NAPI_CALL(env, napi_create_string_utf8(env, "DeleteOAuthToken", NAPI_AUTO_LENGTH, &resource));
1299     NAPI_CALL(env,
1300         napi_create_async_work(env, nullptr, resource,
1301             [](napi_env env, void *data) {
1302                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1303                 if (asyncContext->throwErr) {
1304                     asyncContext->errCode = AppAccountManager::DeleteAuthToken(
1305                         asyncContext->name, asyncContext->owner, asyncContext->authType, asyncContext->token);
1306                 } else {
1307                     asyncContext->errCode = AppAccountManager::DeleteOAuthToken(
1308                         asyncContext->name, asyncContext->owner, asyncContext->authType, asyncContext->token);
1309                 }
1310             },
1311             [](napi_env env, napi_status status, void *data) {
1312                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1313                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1314                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1315                 ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
1316                 napi_delete_async_work(env, asyncContext->work);
1317                 delete asyncContext;
1318                 asyncContext = nullptr;
1319             },
1320             reinterpret_cast<void *>(asyncContext),
1321             &asyncContext->work));
1322     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1323     return result;
1324 }
1325 
SetOAuthTokenVisibility(napi_env env,napi_callback_info cbInfo)1326 napi_value NapiAppAccount::SetOAuthTokenVisibility(napi_env env, napi_callback_info cbInfo)
1327 {
1328     return SetAuthTokenVisibilityInternal(env, cbInfo, false);
1329 }
1330 
SetAuthTokenVisibility(napi_env env,napi_callback_info cbInfo)1331 napi_value NapiAppAccount::SetAuthTokenVisibility(napi_env env, napi_callback_info cbInfo)
1332 {
1333     return SetAuthTokenVisibilityInternal(env, cbInfo, true);
1334 }
1335 
SetAuthTokenVisibilityInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1336 napi_value NapiAppAccount::SetAuthTokenVisibilityInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1337 {
1338     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1339     if (asyncContext == nullptr) {
1340         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1341         return NapiGetNull(env);
1342     }
1343     asyncContext->env = env;
1344     asyncContext->throwErr = isThrowable;
1345     if ((!ParseContextForSetOAuthTokenVisibility(env, cbInfo, asyncContext)) && isThrowable) {
1346         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1347         delete asyncContext;
1348         return NapiGetNull(env);
1349     }
1350     napi_value result = nullptr;
1351     if (asyncContext->callbackRef == nullptr) {
1352         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1353     } else {
1354         NAPI_CALL(env, napi_get_undefined(env, &result));
1355     }
1356     napi_value resource = nullptr;
1357     NAPI_CALL(env, napi_create_string_utf8(env, "SetOAuthTokenVisibility", NAPI_AUTO_LENGTH, &resource));
1358     NAPI_CALL(env,
1359         napi_create_async_work(env,
1360             nullptr,
1361             resource,
1362             [](napi_env env, void *data) {
1363                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1364                 if (asyncContext->throwErr) {
1365                     asyncContext->errCode = AppAccountManager::SetAuthTokenVisibility(
1366                         asyncContext->name, asyncContext->authType, asyncContext->bundleName, asyncContext->isVisible);
1367                 } else {
1368                     asyncContext->errCode = AppAccountManager::SetOAuthTokenVisibility(
1369                         asyncContext->name, asyncContext->authType, asyncContext->bundleName, asyncContext->isVisible);
1370                 }
1371             },
1372             [](napi_env env, napi_status status, void *data) {
1373                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1374                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1375                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1376                 ProcessCallbackOrPromise(env, asyncContext, err, NapiGetNull(env));
1377                 napi_delete_async_work(env, asyncContext->work);
1378                 delete asyncContext;
1379                 asyncContext = nullptr;
1380             },
1381             reinterpret_cast<void *>(asyncContext),
1382             &asyncContext->work));
1383     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1384     return result;
1385 }
1386 
CheckOAuthTokenVisibility(napi_env env,napi_callback_info cbInfo)1387 napi_value NapiAppAccount::CheckOAuthTokenVisibility(napi_env env, napi_callback_info cbInfo)
1388 {
1389     return CheckAuthTokenVisibilityInternal(env, cbInfo, false);
1390 }
1391 
CheckAuthTokenVisibility(napi_env env,napi_callback_info cbInfo)1392 napi_value NapiAppAccount::CheckAuthTokenVisibility(napi_env env, napi_callback_info cbInfo)
1393 {
1394     return CheckAuthTokenVisibilityInternal(env, cbInfo, true);
1395 }
1396 
CheckAuthTokenVisibilityInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1397 napi_value NapiAppAccount::CheckAuthTokenVisibilityInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1398 {
1399     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1400     if (asyncContext == nullptr) {
1401         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1402         return NapiGetNull(env);
1403     }
1404     asyncContext->env = env;
1405     asyncContext->throwErr = isThrowable;
1406     if ((!ParseContextForCheckOAuthTokenVisibility(env, cbInfo, asyncContext)) && isThrowable) {
1407         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1408         delete asyncContext;
1409         return NapiGetNull(env);
1410     }
1411     napi_value result = nullptr;
1412     if (asyncContext->callbackRef == nullptr) {
1413         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1414     } else {
1415         NAPI_CALL(env, napi_get_undefined(env, &result));
1416     }
1417     napi_value resource = nullptr;
1418     NAPI_CALL(env, napi_create_string_utf8(env, "CheckOAuthTokenVisibility", NAPI_AUTO_LENGTH, &resource));
1419     NAPI_CALL(env,
1420         napi_create_async_work(env,
1421             nullptr,
1422             resource,
1423             [](napi_env env, void *data) {
1424                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1425                 if (asyncContext->throwErr) {
1426                     asyncContext->errCode = AppAccountManager::CheckAuthTokenVisibility(
1427                         asyncContext->name, asyncContext->authType, asyncContext->bundleName, asyncContext->isVisible);
1428                 } else {
1429                     asyncContext->errCode = AppAccountManager::CheckOAuthTokenVisibility(
1430                         asyncContext->name, asyncContext->authType, asyncContext->bundleName, asyncContext->isVisible);
1431                 }
1432             },
1433             [](napi_env env, napi_status status, void *data) {
1434                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1435                 napi_value boolVal = nullptr;
1436                 napi_get_boolean(env, asyncContext->isVisible, &boolVal);
1437                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1438                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1439                 ProcessCallbackOrPromise(env, asyncContext, err, boolVal);
1440                 napi_delete_async_work(env, asyncContext->work);
1441                 delete asyncContext;
1442                 asyncContext = nullptr;
1443             },
1444             reinterpret_cast<void *>(asyncContext),
1445             &asyncContext->work));
1446     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1447     return result;
1448 }
1449 
GetAuthenticatorInfo(napi_env env,napi_callback_info cbInfo)1450 napi_value NapiAppAccount::GetAuthenticatorInfo(napi_env env, napi_callback_info cbInfo)
1451 {
1452     return QueryAuthenticatorInfoInternal(env, cbInfo, false);
1453 }
1454 
QueryAuthenticatorInfo(napi_env env,napi_callback_info cbInfo)1455 napi_value NapiAppAccount::QueryAuthenticatorInfo(napi_env env, napi_callback_info cbInfo)
1456 {
1457     return QueryAuthenticatorInfoInternal(env, cbInfo, true);
1458 }
1459 
QueryAuthenticatorInfoInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1460 napi_value NapiAppAccount::QueryAuthenticatorInfoInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1461 {
1462     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1463     if (asyncContext == nullptr) {
1464         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1465         return NapiGetNull(env);
1466     }
1467     asyncContext->env = env;
1468     asyncContext->throwErr = isThrowable;
1469     if ((!ParseContextForGetAuthenticatorInfo(env, cbInfo, asyncContext)) && isThrowable) {
1470         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1471         delete asyncContext;
1472         return NapiGetNull(env);
1473     }
1474     napi_value result = nullptr;
1475     if (asyncContext->callbackRef == nullptr) {
1476         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1477     } else {
1478         NAPI_CALL(env, napi_get_undefined(env, &result));
1479     }
1480     napi_value resource = nullptr;
1481     NAPI_CALL(env, napi_create_string_utf8(env, "GetAuthenticatorInfo", NAPI_AUTO_LENGTH, &resource));
1482     NAPI_CALL(env,
1483         napi_create_async_work(env,
1484             nullptr,
1485             resource,
1486             [](napi_env env, void *data) {
1487                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1488                 asyncContext->errCode = AppAccountManager::GetAuthenticatorInfo(
1489                     asyncContext->owner, asyncContext->authenticatorInfo);
1490             },
1491             [](napi_env env, napi_status status, void *data) {
1492                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1493                 napi_value result = nullptr;
1494                 napi_create_object(env, &result);
1495                 GetAuthenticatorInfoForResult(env, asyncContext->authenticatorInfo, result);
1496                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1497                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1498                 ProcessCallbackOrPromise(env, asyncContext, err, result);
1499                 napi_delete_async_work(env, asyncContext->work);
1500                 delete asyncContext;
1501                 asyncContext = nullptr;
1502             },
1503             reinterpret_cast<void *>(asyncContext),
1504             &asyncContext->work));
1505     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1506     return result;
1507 }
1508 
GetAllOAuthTokens(napi_env env,napi_callback_info cbInfo)1509 napi_value NapiAppAccount::GetAllOAuthTokens(napi_env env, napi_callback_info cbInfo)
1510 {
1511     return GetAllAuthTokensInternal(env, cbInfo, false);
1512 }
1513 
GetAllAuthTokens(napi_env env,napi_callback_info cbInfo)1514 napi_value NapiAppAccount::GetAllAuthTokens(napi_env env, napi_callback_info cbInfo)
1515 {
1516     return GetAllAuthTokensInternal(env, cbInfo, true);
1517 }
1518 
GetAllAuthTokensInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1519 napi_value NapiAppAccount::GetAllAuthTokensInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1520 {
1521     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1522     if (asyncContext == nullptr) {
1523         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1524         return NapiGetNull(env);
1525     }
1526     asyncContext->env = env;
1527     asyncContext->throwErr = isThrowable;
1528     if ((!ParseContextForGetAllOAuthTokens(env, cbInfo, asyncContext)) && isThrowable) {
1529         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1530         delete asyncContext;
1531         return NapiGetNull(env);
1532     }
1533     napi_value result = nullptr;
1534     if (asyncContext->callbackRef == nullptr) {
1535         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1536     } else {
1537         NAPI_CALL(env, napi_get_undefined(env, &result));
1538     }
1539     napi_value resource = nullptr;
1540     NAPI_CALL(env, napi_create_string_utf8(env, "GetAllOAuthTokens", NAPI_AUTO_LENGTH, &resource));
1541     NAPI_CALL(env,
1542         napi_create_async_work(env,
1543             nullptr,
1544             resource,
1545             [](napi_env env, void *data) {
1546                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1547                 asyncContext->errCode = AppAccountManager::GetAllOAuthTokens(
1548                     asyncContext->name, asyncContext->owner, asyncContext->oauthTokenInfos);
1549             },
1550             [](napi_env env, napi_status status, void *data) {
1551                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1552                 napi_value arrVal = nullptr;
1553                 napi_create_array(env, &arrVal);
1554                 GetOAuthTokenInfoForResult(env, asyncContext->oauthTokenInfos, arrVal);
1555                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1556                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1557                 ProcessCallbackOrPromise(env, asyncContext, err, arrVal);
1558                 napi_delete_async_work(env, asyncContext->work);
1559                 delete asyncContext;
1560                 asyncContext = nullptr;
1561             },
1562             reinterpret_cast<void *>(asyncContext),
1563             &asyncContext->work));
1564     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1565     return result;
1566 }
1567 
GetOAuthList(napi_env env,napi_callback_info cbInfo)1568 napi_value NapiAppAccount::GetOAuthList(napi_env env, napi_callback_info cbInfo)
1569 {
1570     return GetAuthListInternal(env, cbInfo, false);
1571 }
1572 
GetAuthList(napi_env env,napi_callback_info cbInfo)1573 napi_value NapiAppAccount::GetAuthList(napi_env env, napi_callback_info cbInfo)
1574 {
1575     return GetAuthListInternal(env, cbInfo, true);
1576 }
1577 
GetAuthListInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1578 napi_value NapiAppAccount::GetAuthListInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1579 {
1580     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1581     if (asyncContext == nullptr) {
1582         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1583         return NapiGetNull(env);
1584     }
1585     asyncContext->env = env;
1586     asyncContext->throwErr = isThrowable;
1587     if ((!ParseContextForGetOAuthList(env, cbInfo, asyncContext)) && isThrowable) {
1588         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1589         delete asyncContext;
1590         return NapiGetNull(env);
1591     }
1592     napi_value result = nullptr;
1593     if (asyncContext->callbackRef == nullptr) {
1594         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1595     } else {
1596         NAPI_CALL(env, napi_get_undefined(env, &result));
1597     }
1598     napi_value resource = nullptr;
1599     NAPI_CALL(env, napi_create_string_utf8(env, "GetOAuthList", NAPI_AUTO_LENGTH, &resource));
1600     NAPI_CALL(env,
1601         napi_create_async_work(env, nullptr, resource,
1602             [](napi_env env, void *data) {
1603                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1604                 if (asyncContext->throwErr) {
1605                     asyncContext->errCode = AppAccountManager::GetAuthList(
1606                         asyncContext->name, asyncContext->authType, asyncContext->authList);
1607                 } else {
1608                     asyncContext->errCode = AppAccountManager::GetOAuthList(
1609                         asyncContext->name, asyncContext->authType, asyncContext->authList);
1610                 }
1611             },
1612             [](napi_env env, napi_status status, void *data) {
1613                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1614                 napi_value arrVal = nullptr;
1615                 napi_create_array(env, &arrVal);
1616                 GetOAuthListForResult(env, asyncContext->authList, arrVal);
1617                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1618                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1619                 ProcessCallbackOrPromise(env, asyncContext, err, arrVal);
1620                 napi_delete_async_work(env, asyncContext->work);
1621                 delete asyncContext;
1622                 asyncContext = nullptr;
1623             },
1624             reinterpret_cast<void *>(asyncContext),
1625             &asyncContext->work));
1626     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1627     return result;
1628 }
1629 
GetAuthenticatorCallback(napi_env env,napi_callback_info cbInfo)1630 napi_value NapiAppAccount::GetAuthenticatorCallback(napi_env env, napi_callback_info cbInfo)
1631 {
1632     return GetAuthCallbackInternal(env, cbInfo, false);
1633 }
1634 
GetAuthCallback(napi_env env,napi_callback_info cbInfo)1635 napi_value NapiAppAccount::GetAuthCallback(napi_env env, napi_callback_info cbInfo)
1636 {
1637     return GetAuthCallbackInternal(env, cbInfo, true);
1638 }
1639 
GetAuthCallbackInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1640 napi_value NapiAppAccount::GetAuthCallbackInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1641 {
1642     auto *asyncContext = new (std::nothrow) OAuthAsyncContext();
1643     if (asyncContext == nullptr) {
1644         ACCOUNT_LOGE("insufficient memory for asyncContext!");
1645         return NapiGetNull(env);
1646     }
1647     asyncContext->env = env;
1648     asyncContext->throwErr = isThrowable;
1649     if ((!ParseContextForGetAuthenticatorCallback(env, cbInfo, asyncContext)) && isThrowable) {
1650         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, asyncContext->errMsg));
1651         delete asyncContext;
1652         return NapiGetNull(env);
1653     }
1654     napi_value result = nullptr;
1655     if (asyncContext->callbackRef == nullptr) {
1656         NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
1657     } else {
1658         NAPI_CALL(env, napi_get_undefined(env, &result));
1659     }
1660     napi_value resource = nullptr;
1661     NAPI_CALL(env, napi_create_string_utf8(env, "GetAuthenticatorCallback", NAPI_AUTO_LENGTH, &resource));
1662     NAPI_CALL(env,
1663         napi_create_async_work(env,
1664             nullptr,
1665             resource,
1666             [](napi_env env, void *data) {
1667                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1668                 asyncContext->errCode = AppAccountManager::GetAuthenticatorCallback(
1669                     asyncContext->sessionId, asyncContext->authenticatorCb);
1670             },
1671             [](napi_env env, napi_status status, void *data) {
1672                 OAuthAsyncContext *asyncContext = reinterpret_cast<OAuthAsyncContext *>(data);
1673                 napi_value result = nullptr;
1674                 GetAuthenticatorCallbackForResult(env, asyncContext->authenticatorCb, &result);
1675                 napi_value err = asyncContext->throwErr ? GenerateBusinessError(env, asyncContext->errCode) :
1676                     GetErrorCodeValue(env, ConvertToJSErrCodeV8(asyncContext->errCode));
1677                 ProcessCallbackOrPromise(env, asyncContext, err, result);
1678                 napi_delete_async_work(env, asyncContext->work);
1679                 delete asyncContext;
1680                 asyncContext = nullptr;
1681             },
1682             reinterpret_cast<void *>(asyncContext),
1683             &asyncContext->work));
1684     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
1685     return result;
1686 }
1687 
CheckAppAccess(napi_env env,napi_callback_info cbInfo)1688 napi_value NapiAppAccount::CheckAppAccess(napi_env env, napi_callback_info cbInfo)
1689 {
1690     auto *context = new (std::nothrow) AppAccountAsyncContext();
1691     if (context == nullptr) {
1692         ACCOUNT_LOGE("insufficient memory for context!");
1693         return NapiGetNull(env);
1694     }
1695     context->env = env;
1696     if (!ParseContextWithBdName(env, cbInfo, context)) {
1697         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1698         delete context;
1699         return NapiGetNull(env);
1700     }
1701     napi_value result = nullptr;
1702     if (context->callbackRef == nullptr) {
1703         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
1704     } else {
1705         NAPI_CALL(env, napi_get_undefined(env, &result));
1706     }
1707     napi_value resource = nullptr;
1708     NAPI_CALL(env, napi_create_string_utf8(env, "CheckAppAccess", NAPI_AUTO_LENGTH, &resource));
1709     NAPI_CALL(env, napi_create_async_work(env,
1710         nullptr,
1711         resource,
1712         [](napi_env env, void *data) {
1713             auto context = reinterpret_cast<AppAccountAsyncContext *>(data);
1714             context->errCode = AppAccountManager::CheckAppAccess(
1715                 context->name, context->bundleName, context->isAccessible);
1716         },
1717         [](napi_env env, napi_status status, void *data) {
1718             auto context = reinterpret_cast<AppAccountAsyncContext *>(data);
1719             napi_value boolVal = nullptr;
1720             napi_get_boolean(env, context->isAccessible, &boolVal);
1721             ProcessCallbackOrPromise(env, context, GenerateBusinessError(env, context->errCode), boolVal);
1722             napi_delete_async_work(env, context->work);
1723             delete context;
1724             context = nullptr;
1725         },
1726         reinterpret_cast<void *>(context),
1727         &context->work));
1728     NAPI_CALL(env, napi_queue_async_work(env, context->work));
1729     return result;
1730 }
1731 
DeleteAccountCredential(napi_env env,napi_callback_info cbInfo)1732 napi_value NapiAppAccount::DeleteAccountCredential(napi_env env, napi_callback_info cbInfo)
1733 {
1734     return DeleteCredentialInternal(env, cbInfo, false);
1735 }
1736 
DeleteCredential(napi_env env,napi_callback_info cbInfo)1737 napi_value NapiAppAccount::DeleteCredential(napi_env env, napi_callback_info cbInfo)
1738 {
1739     return DeleteCredentialInternal(env, cbInfo, true);
1740 }
1741 
DeleteCredentialInternal(napi_env env,napi_callback_info cbInfo,bool isThrowable)1742 napi_value NapiAppAccount::DeleteCredentialInternal(napi_env env, napi_callback_info cbInfo, bool isThrowable)
1743 {
1744     napi_value result = NapiGetNull(env);
1745     auto *context = new (std::nothrow) AppAccountAsyncContext();
1746     if (context == nullptr) {
1747         ACCOUNT_LOGE("insufficient memory for context!");
1748         return result;
1749     }
1750     context->env = env;
1751     context->throwErr = isThrowable;
1752     if (!ParseContextWithCredentialType(env, cbInfo, context) && isThrowable) {
1753         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1754         delete context;
1755         return result;
1756     }
1757     if (context->callbackRef == nullptr) {
1758         napi_create_promise(env, &context->deferred, &result);
1759     }
1760     napi_value resource = nullptr;
1761     napi_create_string_utf8(env, "DeleteAccountCredential", NAPI_AUTO_LENGTH, &resource);
1762     napi_create_async_work(env, nullptr, resource,
1763         [](napi_env env, void *data) {
1764             auto context = reinterpret_cast<AppAccountAsyncContext *>(data);
1765             context->errCode = AppAccountManager::DeleteAccountCredential(
1766                 context->name, context->credentialType);
1767         },
1768         [](napi_env env, napi_status status, void *data) {
1769             auto context = reinterpret_cast<AppAccountAsyncContext *>(data);
1770             if (context->throwErr) {
1771                 ProcessCallbackOrPromise(env, context, GenerateBusinessError(env, context->errCode), NapiGetNull(env));
1772             } else {
1773                 napi_value ret = nullptr;
1774                 napi_get_undefined(env, &ret);
1775                 ProcessCallbackOrPromise(env, context, GenerateBusinessError(env, context->errCode), ret);
1776             }
1777             napi_delete_async_work(env, context->work);
1778             delete context;
1779             context = nullptr;
1780         }, reinterpret_cast<void *>(context), &context->work);
1781     napi_queue_async_work(env, context->work);
1782     return result;
1783 }
1784 
CheckAccountLabels(napi_env env,napi_callback_info cbInfo)1785 napi_value NapiAppAccount::CheckAccountLabels(napi_env env, napi_callback_info cbInfo)
1786 {
1787     auto context = new (std::nothrow) CheckAccountLabelsContext();
1788     if (context == nullptr) {
1789         ACCOUNT_LOGE("insufficient memory for context!");
1790         return NapiGetNull(env);
1791     }
1792     context->env = env;
1793     if (!ParseContextForCheckAccountLabels(env, cbInfo, context)) {
1794         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1795         delete context;
1796         return NapiGetNull(env);
1797     }
1798     napi_value result = nullptr;
1799     if (context->callbackRef == nullptr) {
1800         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
1801     } else {
1802         NAPI_CALL(env, napi_get_undefined(env, &result));
1803     }
1804     napi_value resource = nullptr;
1805     NAPI_CALL(env, napi_create_string_utf8(env, "CheckAccountLabels", NAPI_AUTO_LENGTH, &resource));
1806     NAPI_CALL(env, napi_create_async_work(env,
1807         nullptr,
1808         resource,
1809         [](napi_env env, void *data) {
1810             auto context = reinterpret_cast<CheckAccountLabelsContext *>(data);
1811             sptr<AuthenticatorAsyncCallback> callback = new (std::nothrow) AuthenticatorAsyncCallback(
1812                 *context, CheckAccountLabelsOnResultWork);
1813             if (callback == nullptr) {
1814                 ACCOUNT_LOGE("failed to create AuthenticatorAsyncCallback for insufficient memory");
1815                 context->errCode = ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1816                 return;
1817             }
1818             context->errCode = AppAccountManager::CheckAccountLabels(
1819                 context->name, context->owner, context->labels, callback);
1820         },
1821         [](napi_env env, napi_status status, void *data) {
1822             auto context = reinterpret_cast<CheckAccountLabelsContext *>(data);
1823             if (context->errCode != ERR_OK) {
1824                 ProcessCallbackOrPromise(env, context, GenerateBusinessError(env, context->errCode), NapiGetNull(env));
1825             }
1826             napi_delete_async_work(env, context->work);
1827             delete context;
1828             context = nullptr;
1829         },
1830         reinterpret_cast<void *>(context), &context->work));
1831     NAPI_CALL(env, napi_queue_async_work(env, context->work));
1832     return result;
1833 }
1834 
SelectAccountsByOptions(napi_env env,napi_callback_info cbInfo)1835 napi_value NapiAppAccount::SelectAccountsByOptions(napi_env env, napi_callback_info cbInfo)
1836 {
1837     auto *context = new (std::nothrow) SelectAccountsContext();
1838     if (context == nullptr) {
1839         ACCOUNT_LOGE("insufficient memory for context!");
1840         return NapiGetNull(env);
1841     }
1842     context->env = env;
1843     if (!ParseContextForSelectAccount(env, cbInfo, context)) {
1844         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1845         delete context;
1846         return NapiGetNull(env);
1847     }
1848     napi_value result = nullptr;
1849     if (context->callbackRef == nullptr) {
1850         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
1851     } else {
1852         NAPI_CALL(env, napi_get_undefined(env, &result));
1853     }
1854     napi_value resource = nullptr;
1855     NAPI_CALL(env, napi_create_string_utf8(env, "SelectAccountsByOptions", NAPI_AUTO_LENGTH, &resource));
1856     NAPI_CALL(env, napi_create_async_work(env,
1857         nullptr,
1858         resource,
1859         [](napi_env env, void *data) {
1860             auto context = reinterpret_cast<SelectAccountsContext *>(data);
1861             sptr<AuthenticatorAsyncCallback> callback = new (std::nothrow) AuthenticatorAsyncCallback(
1862                 *context, SelectAccountsOnResultWork);
1863             if (callback == nullptr) {
1864                 ACCOUNT_LOGD("failed to create AuthenticatorAsyncCallback for insufficient memory");
1865                 context->errCode = ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1866                 return;
1867             }
1868             context->errCode =
1869                 AppAccountManager::SelectAccountsByOptions(context->options, callback);
1870         },
1871         [](napi_env env, napi_status status, void *data) {
1872             auto context = reinterpret_cast<SelectAccountsContext *>(data);
1873             if (context->errCode != ERR_OK) {
1874                 ProcessCallbackOrPromise(env, context, GenerateBusinessError(env, context->errCode), NapiGetNull(env));
1875             }
1876             napi_delete_async_work(env, context->work);
1877             delete context;
1878             context = nullptr;
1879         },
1880         reinterpret_cast<void *>(context), &context->work));
1881     NAPI_CALL(env, napi_queue_async_work(env, context->work));
1882     return result;
1883 }
1884 
VerifyCredential(napi_env env,napi_callback_info cbInfo)1885 napi_value NapiAppAccount::VerifyCredential(napi_env env, napi_callback_info cbInfo)
1886 {
1887     auto *context = new (std::nothrow) VerifyCredentialContext();
1888     if (context == nullptr) {
1889         ACCOUNT_LOGE("insufficient memory for context!");
1890         return NapiGetNull(env);
1891     }
1892     context->env = env;
1893     if (!ParseContextForVerifyCredential(env, cbInfo, context)) {
1894         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1895         delete context;
1896         return NapiGetNull(env);
1897     }
1898     context->appAccountMgrCb = new (std::nothrow) AppAccountManagerCallback(env, context->callback);
1899     if (context->appAccountMgrCb == nullptr) {
1900         ACCOUNT_LOGD("failed to create AppAccountManagerCallback for insufficient memory");
1901         AAFwk::WantParams result;
1902         ProcessOnResultCallback(env, context->callback, ERR_JS_SYSTEM_SERVICE_EXCEPTION, result);
1903         delete context;
1904         return NapiGetNull(env);
1905     }
1906     napi_value resource = nullptr;
1907     NAPI_CALL(env, napi_create_string_utf8(env, "VerifyCredential", NAPI_AUTO_LENGTH, &resource));
1908     NAPI_CALL(env, napi_create_async_work(env,
1909         nullptr,
1910         resource,
1911         [](napi_env env, void *data) {
1912             auto context = reinterpret_cast<VerifyCredentialContext *>(data);
1913             ErrCode errCode = AppAccountManager::VerifyCredential(
1914                 context->name, context->owner, context->options, context->appAccountMgrCb);
1915             context->errCode = ConvertToJSErrCode(errCode);
1916         },
1917         VerifyCredCompleteCB, reinterpret_cast<void *>(context), &context->work));
1918     NAPI_CALL(env, napi_queue_async_work(env, context->work));
1919     return NapiGetNull(env);
1920 }
1921 
SetAuthenticatorProperties(napi_env env,napi_callback_info cbInfo)1922 napi_value NapiAppAccount::SetAuthenticatorProperties(napi_env env, napi_callback_info cbInfo)
1923 {
1924     auto *context = new (std::nothrow) SetPropertiesContext();
1925     if (context == nullptr) {
1926         ACCOUNT_LOGE("insufficient memory for context!");
1927         return NapiGetNull(env);
1928     }
1929     context->env = env;
1930     if (!ParseContextForSetProperties(env, cbInfo, context)) {
1931         napi_throw(env, GenerateBusinessError(env, ERR_JS_PARAMETER_ERROR, context->errMsg));
1932         delete context;
1933         return NapiGetNull(env);
1934     }
1935     context->appAccountMgrCb = new (std::nothrow) AppAccountManagerCallback(env, context->callback);
1936     if (context->appAccountMgrCb == nullptr) {
1937         ACCOUNT_LOGD("failed to create AppAccountManagerCallback for insufficient memory");
1938         AAFwk::WantParams result;
1939         ProcessOnResultCallback(env, context->callback, ERR_JS_SYSTEM_SERVICE_EXCEPTION, result);
1940         delete context;
1941         return NapiGetNull(env);
1942     }
1943     napi_value resource = nullptr;
1944     NAPI_CALL(env, napi_create_string_utf8(env, "SetAuthenticatorProperties", NAPI_AUTO_LENGTH, &resource));
1945     NAPI_CALL(env, napi_create_async_work(env,
1946         nullptr,
1947         resource,
1948         [](napi_env env, void *data) {
1949             auto context = reinterpret_cast<SetPropertiesContext *>(data);
1950             ErrCode errCode = AppAccountManager::SetAuthenticatorProperties(
1951                 context->owner, context->options, context->appAccountMgrCb);
1952             context->errCode = ConvertToJSErrCode(errCode);
1953         },
1954         [](napi_env env, napi_status status, void *data) {
1955             auto context = reinterpret_cast<SetPropertiesContext *>(data);
1956             if ((context->errCode != ERR_JS_SUCCESS) && (context->appAccountMgrCb != nullptr)) {
1957                 AAFwk::Want errResult;
1958                 context->appAccountMgrCb->OnResult(context->errCode, errResult);
1959             }
1960             napi_delete_async_work(env, context->work);
1961             delete context;
1962             context = nullptr;
1963         },
1964         reinterpret_cast<void *>(context),
1965         &context->work));
1966     NAPI_CALL(env, napi_queue_async_work(env, context->work));
1967     return NapiGetNull(env);
1968 }
1969 
Subscribe(napi_env env,napi_callback_info cbInfo)1970 napi_value NapiAppAccount::Subscribe(napi_env env, napi_callback_info cbInfo)
1971 {
1972     AsyncContextForSubscribe *context = new (std::nothrow) AsyncContextForSubscribe(env);
1973     if (context == nullptr) {
1974         ACCOUNT_LOGE("asyncContextForOn is null");
1975         return NapiGetNull(env);
1976     }
1977     if (!ParseParametersBySubscribe(env, cbInfo, context)) {
1978         if (context->type != TYPE_CHANGE) {
1979             napi_throw(env, GenerateBusinessError(env, context->errCode, context->errMsg));
1980         }
1981         delete context;
1982         return NapiGetNull(env);
1983     }
1984     if (context->appAccountManager == nullptr) {
1985         if (context->type != TYPE_CHANGE) {
1986             napi_throw(env, GenerateBusinessError(env, ERR_JS_SYSTEM_SERVICE_EXCEPTION,
1987                 std::string("system service exception")));
1988         }
1989         delete context;
1990         return NapiGetNull(env);
1991     }
1992     AppAccountSubscribeInfo subscribeInfo(context->owners);
1993     context->subscriber = std::make_shared<SubscriberPtr>(subscribeInfo);
1994     if (context->subscriber == nullptr) {
1995         ACCOUNT_LOGE("fail to create subscriber");
1996         delete context;
1997         return NapiGetNull(env);
1998     }
1999     context->subscriber->SetEnv(env);
2000     context->subscriber->SetCallbackRef(context->callbackRef);
2001 
2002     {
2003         std::lock_guard<std::mutex> lock(g_lockForAppAccountSubscribers);
2004         g_AppAccountSubscribers[context->appAccountManager].emplace_back(context);
2005     }
2006 
2007     ErrCode errCode = AppAccountManager::SubscribeAppAccount(context->subscriber);
2008     if ((errCode != ERR_OK) && (context->type != TYPE_CHANGE)) {
2009         napi_throw(env, GenerateBusinessError(env, errCode));
2010     }
2011     return NapiGetNull(env);
2012 }
2013 
Unsubscribe(napi_env env,napi_callback_info cbInfo)2014 napi_value NapiAppAccount::Unsubscribe(napi_env env, napi_callback_info cbInfo)
2015 {
2016     AsyncContextForUnsubscribe *context = new (std::nothrow) AsyncContextForUnsubscribe(env);
2017     if (context == nullptr) {
2018         ACCOUNT_LOGE("asyncContextForOff is null");
2019         return NapiGetNull(env);
2020     }
2021     if (!ParseParametersByUnsubscribe(env, cbInfo, context)) {
2022         if (context->type != TYPE_CHANGE) {
2023             napi_throw(env, GenerateBusinessError(env, context->errCode, context->errMsg));
2024         }
2025         delete context;
2026         return NapiGetNull(env);
2027     };
2028     bool isFind = false;
2029     std::vector<std::shared_ptr<SubscriberPtr>> subscribers = {nullptr};
2030     napi_value result = GetSubscriberByUnsubscribe(env, subscribers, context, isFind);
2031     if (!result) {
2032         ACCOUNT_LOGE("Unsubscribe failed. The current subscriber does not exist");
2033         return NapiGetNull(env);
2034     }
2035     context->subscribers = subscribers;
2036 
2037     napi_value resourceName = nullptr;
2038     napi_create_string_latin1(env, "Unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
2039 
2040     napi_create_async_work(env,
2041         nullptr,
2042         resourceName,
2043         UnsubscribeExecuteCB,
2044         UnsubscribeCallbackCompletedCB,
2045         reinterpret_cast<void *>(context),
2046         &context->work);
2047     napi_queue_async_work(env, context->work);
2048     return NapiGetNull(env);
2049 }
2050 }  // namespace AccountJsKit
2051 }  // namespace OHOS
2052