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