1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_app_account_authenticator.h"
17
18 #include <uv.h>
19
20 #include "account_log_wrapper.h"
21 #include "app_account_constants.h"
22 #include "iapp_account_authenticator_callback.h"
23 #include "ipc_object_stub.h"
24 #include "napi/native_api.h"
25 #include "napi/native_node_api.h"
26 #include "napi_account_common.h"
27 #include "napi_app_account_authenticator_callback.h"
28 #include "napi_app_account_common.h"
29 #include "napi_common.h"
30 #include "napi_remote_object.h"
31
32 namespace OHOS {
33 namespace AccountJsKit {
34 using namespace OHOS::AccountSA;
35
OnEnvCleanUp(void * data)36 static void OnEnvCleanUp(void *data)
37 {
38 if (data == nullptr) {
39 ACCOUNT_LOGE("data is nullptr");
40 return;
41 }
42 auto authenticator = reinterpret_cast<NapiAppAccountAuthenticator *>(data);
43 authenticator->SetEnv(nullptr);
44 }
45
NapiAppAccountAuthenticator(napi_env env,JsAuthenticator & jsAuthenticator)46 NapiAppAccountAuthenticator::NapiAppAccountAuthenticator(napi_env env, JsAuthenticator &jsAuthenticator)
47 : env_(env), jsAuthenticator_(jsAuthenticator)
48 {}
49
~NapiAppAccountAuthenticator()50 NapiAppAccountAuthenticator::~NapiAppAccountAuthenticator()
51 {
52 std::vector<napi_ref> napiRefVec = {
53 jsAuthenticator_.addAccountImplicitly,
54 jsAuthenticator_.authenticate,
55 jsAuthenticator_.verifyCredential,
56 jsAuthenticator_.checkAccountLabels,
57 jsAuthenticator_.setProperties,
58 jsAuthenticator_.isAccountRemovable,
59 jsAuthenticator_.createAccountImplicitly,
60 jsAuthenticator_.auth
61 };
62 ReleaseNapiRefArray(env_, napiRefVec);
63 jsAuthenticator_.addAccountImplicitly = nullptr;
64 jsAuthenticator_.authenticate = nullptr;
65 jsAuthenticator_.verifyCredential = nullptr;
66 jsAuthenticator_.checkAccountLabels = nullptr;
67 jsAuthenticator_.setProperties = nullptr;
68 jsAuthenticator_.isAccountRemovable = nullptr;
69 jsAuthenticator_.createAccountImplicitly = nullptr;
70 jsAuthenticator_.auth = nullptr;
71 napi_remove_env_cleanup_hook(env_, OnEnvCleanUp, this);
72 }
73
CheckObjectLegality() const74 bool NapiAppAccountAuthenticator::CheckObjectLegality() const
75 {
76 return true;
77 }
78
GetObjectType() const79 int NapiAppAccountAuthenticator::GetObjectType() const
80 {
81 return OBJECT_TYPE_NATIVE;
82 }
83
SetEnv(napi_env env)84 void NapiAppAccountAuthenticator::SetEnv(napi_env env)
85 {
86 env_ = env;
87 }
88
InitWorkEnv(uv_loop_s ** loop,uv_work_t ** work,JsAuthenticatorParam ** param)89 ErrCode NapiAppAccountAuthenticator::InitWorkEnv(uv_loop_s **loop, uv_work_t **work, JsAuthenticatorParam **param)
90 {
91 napi_get_uv_event_loop(env_, loop);
92 if (*loop == nullptr) {
93 ACCOUNT_LOGE("failed to get uv event loop");
94 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
95 }
96 *work = new (std::nothrow) uv_work_t;
97 if (*work == nullptr) {
98 ACCOUNT_LOGE("failed to allocate memory");
99 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
100 }
101 *param = new (std::nothrow) JsAuthenticatorParam();
102 if (*param == nullptr) {
103 ACCOUNT_LOGE("failed to allocate memory");
104 delete *work;
105 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
106 }
107 (*param)->env = env_;
108 (*param)->jsAuthenticator = jsAuthenticator_;
109 return ERR_OK;
110 }
111
AddAccountImplicitly(const std::string & authType,const std::string & callerBundleName,const AAFwk::WantParams & options,const sptr<IRemoteObject> & callback)112 ErrCode NapiAppAccountAuthenticator::AddAccountImplicitly(
113 const std::string &authType, const std::string &callerBundleName,
114 const AAFwk::WantParams &options, const sptr<IRemoteObject> &callback)
115 {
116 if (jsAuthenticator_.addAccountImplicitly == nullptr) {
117 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
118 }
119 uv_loop_s *loop = nullptr;
120 uv_work_t *work = nullptr;
121 JsAuthenticatorParam *param = nullptr;
122 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
123 if (result != ERR_OK) {
124 ACCOUNT_LOGE("failed to InitWorkEnv");
125 return result;
126 }
127 param->authType = authType;
128 param->callerBundleName = callerBundleName;
129 param->options = options;
130 param->callback = callback;
131 work->data = reinterpret_cast<void *>(param);
132 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, AddAccountImplicitlyWork, uv_qos_default);
133 if (ret != 0) {
134 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
135 delete work;
136 delete param;
137 }
138 return ret;
139 }
140
Authenticate(const std::string & name,const std::string & authType,const std::string & callerBundleName,const AAFwk::WantParams & options,const sptr<IRemoteObject> & callback)141 ErrCode NapiAppAccountAuthenticator::Authenticate(const std::string &name, const std::string &authType,
142 const std::string &callerBundleName, const AAFwk::WantParams &options, const sptr<IRemoteObject> &callback)
143 {
144 if (jsAuthenticator_.authenticate == nullptr) {
145 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
146 }
147 uv_loop_s *loop = nullptr;
148 uv_work_t *work = nullptr;
149 JsAuthenticatorParam *param = nullptr;
150 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
151 if (result != ERR_OK) {
152 return result;
153 }
154 param->authType = authType;
155 param->name = name;
156 param->callerBundleName = callerBundleName;
157 param->options = options;
158 param->callback = callback;
159 work->data = reinterpret_cast<void *>(param);
160 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, AuthenticateWork, uv_qos_default);
161 if (ret != 0) {
162 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
163 delete work;
164 delete param;
165 }
166 return ret;
167 }
168
CreateAccountImplicitly(const CreateAccountImplicitlyOptions & options,const sptr<IRemoteObject> & callback)169 ErrCode NapiAppAccountAuthenticator::CreateAccountImplicitly(
170 const CreateAccountImplicitlyOptions &options, const sptr<IRemoteObject> &callback)
171 {
172 if (jsAuthenticator_.createAccountImplicitly == nullptr) {
173 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
174 }
175 uv_loop_s *loop = nullptr;
176 uv_work_t *work = nullptr;
177 JsAuthenticatorParam *param = nullptr;
178 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
179 if (result != ERR_OK) {
180 ACCOUNT_LOGE("failed to InitWorkEnv");
181 return result;
182 }
183 param->createOptions = options;
184 param->callback = callback;
185 work->data = reinterpret_cast<void *>(param);
186 int32_t ret =
187 uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CreateAccountImplicitlyWork, uv_qos_default);
188 if (ret != 0) {
189 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
190 delete work;
191 delete param;
192 }
193 return ret;
194 }
195
Auth(const std::string & name,const std::string & authType,const AAFwk::WantParams & options,const sptr<IRemoteObject> & callback)196 ErrCode NapiAppAccountAuthenticator::Auth(const std::string &name, const std::string &authType,
197 const AAFwk::WantParams &options, const sptr<IRemoteObject> &callback)
198 {
199 if (jsAuthenticator_.auth == nullptr) {
200 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
201 }
202 uv_loop_s *loop = nullptr;
203 uv_work_t *work = nullptr;
204 JsAuthenticatorParam *param = nullptr;
205 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
206 if (result != ERR_OK) {
207 return result;
208 }
209 param->authType = authType;
210 param->name = name;
211 param->options = options;
212 param->callback = callback;
213 work->data = reinterpret_cast<void *>(param);
214 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, AuthWork, uv_qos_default);
215 if (ret != 0) {
216 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
217 delete work;
218 delete param;
219 }
220 return ret;
221 }
222
VerifyCredential(const std::string & name,const VerifyCredentialOptions & options,const sptr<IRemoteObject> & callback)223 ErrCode NapiAppAccountAuthenticator::VerifyCredential(
224 const std::string &name, const VerifyCredentialOptions &options, const sptr<IRemoteObject> &callback)
225 {
226 if (jsAuthenticator_.verifyCredential == nullptr) {
227 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
228 }
229 uv_loop_s *loop = nullptr;
230 uv_work_t *work = nullptr;
231 JsAuthenticatorParam *param = nullptr;
232 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
233 if (result != ERR_OK) {
234 return result;
235 }
236 param->verifyCredOptions = options;
237 param->name = name;
238 param->callback = callback;
239 work->data = reinterpret_cast<void *>(param);
240 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, VerifyCredentialWork, uv_qos_default);
241 if (ret != 0) {
242 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
243 delete work;
244 delete param;
245 }
246 return ret;
247 }
248
SetProperties(const SetPropertiesOptions & options,const sptr<IRemoteObject> & callback)249 ErrCode NapiAppAccountAuthenticator::SetProperties(
250 const SetPropertiesOptions &options, const sptr<IRemoteObject> &callback)
251 {
252 if (jsAuthenticator_.setProperties == nullptr) {
253 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
254 }
255 uv_loop_s *loop = nullptr;
256 uv_work_t *work = nullptr;
257 JsAuthenticatorParam *param = nullptr;
258 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
259 if (result != ERR_OK) {
260 return result;
261 }
262 param->setPropOptions = options;
263 param->callback = callback;
264 work->data = reinterpret_cast<void *>(param);
265 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, SetPropertiesWork, uv_qos_default);
266 if (ret != 0) {
267 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
268 delete work;
269 delete param;
270 }
271 return ret;
272 }
273
CheckAccountLabels(const std::string & name,const std::vector<std::string> & labels,const sptr<IRemoteObject> & callback)274 ErrCode NapiAppAccountAuthenticator::CheckAccountLabels(
275 const std::string &name, const std::vector<std::string> &labels, const sptr<IRemoteObject> &callback)
276 {
277 if (jsAuthenticator_.checkAccountLabels == nullptr) {
278 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
279 }
280 uv_loop_s *loop = nullptr;
281 uv_work_t *work = nullptr;
282 JsAuthenticatorParam *param = nullptr;
283 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
284 if (result != ERR_OK) {
285 return result;
286 }
287 param->labels = labels;
288 param->name = name;
289 param->callback = callback;
290 work->data = reinterpret_cast<void *>(param);
291 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, CheckAccountLabelsWork, uv_qos_default);
292 if (ret != 0) {
293 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
294 delete work;
295 delete param;
296 }
297 return ret;
298 }
299
IsAccountRemovable(const std::string & name,const sptr<IRemoteObject> & callback)300 ErrCode NapiAppAccountAuthenticator::IsAccountRemovable(const std::string &name, const sptr<IRemoteObject> &callback)
301 {
302 if (jsAuthenticator_.isAccountRemovable == nullptr) {
303 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
304 }
305 uv_loop_s *loop = nullptr;
306 uv_work_t *work = nullptr;
307 JsAuthenticatorParam *param = nullptr;
308 ErrCode result = InitWorkEnv(&loop, &work, ¶m);
309 if (result != ERR_OK) {
310 return result;
311 }
312 param->name = name;
313 param->callback = callback;
314 work->data = reinterpret_cast<void *>(param);
315 int32_t ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, IsAccountRemovableWork, uv_qos_default);
316 if (ret != 0) {
317 ACCOUNT_LOGE("failed to uv_queue_work_with_qos, errCode: %{public}d", ret);
318 delete work;
319 delete param;
320 }
321 return ret;
322 }
323
CreateAuthenticatorCallback(napi_env env,sptr<IRemoteObject> nativeCallback)324 napi_value NapiAppAccountAuthenticator::CreateAuthenticatorCallback(
325 napi_env env, sptr<IRemoteObject> nativeCallback)
326 {
327 napi_value global = nullptr;
328 napi_get_global(env, &global);
329 if (global == nullptr) {
330 ACCOUNT_LOGE("failed to get napi global");
331 return nullptr;
332 }
333 napi_value jsAuthCallbackConstructor = nullptr;
334 napi_get_named_property(env, global, "AuthCallbackConstructor_", &jsAuthCallbackConstructor);
335 if (jsAuthCallbackConstructor == nullptr) {
336 ACCOUNT_LOGE("jsAuthCallbackConstructor is null");
337 return nullptr;
338 }
339 napi_value jsCallback = nullptr;
340 NAPI_CALL(env, napi_new_instance(env, jsAuthCallbackConstructor, 0, nullptr, &jsCallback));
341 auto callback = new (std::nothrow) NapiAppAccountAuthenticatorCallback(nativeCallback);
342 if (callback == nullptr) {
343 ACCOUNT_LOGE("failed to create NapiAppAccountAuthenticatorCallback");
344 return nullptr;
345 }
346 napi_status status = napi_wrap(
347 env, jsCallback, callback,
348 [](napi_env env, void *data, void *hint) {
349 ACCOUNT_LOGI("js AuthCallback instance garbage collection");
350 delete (reinterpret_cast<NapiAppAccountAuthenticatorCallback *>(data));
351 },
352 nullptr, nullptr);
353 if (status != napi_ok) {
354 ACCOUNT_LOGE("Wrap js AuthenticatorStub and native callback failed");
355 delete callback;
356 return nullptr;
357 }
358 return jsCallback;
359 }
360
CreateJsVerifyCredentialOptions(napi_env env,VerifyCredentialOptions & options,napi_value * jsOptions)361 void NapiAppAccountAuthenticator::CreateJsVerifyCredentialOptions(
362 napi_env env, VerifyCredentialOptions &options, napi_value *jsOptions)
363 {
364 NAPI_CALL_RETURN_VOID(env, napi_create_object(env, jsOptions));
365 napi_value strVal;
366 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, options.credentialType.c_str(), NAPI_AUTO_LENGTH, &strVal));
367 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, *jsOptions, "credentialType", strVal));
368 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, options.credential.c_str(), NAPI_AUTO_LENGTH, &strVal));
369 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, *jsOptions, "credential", strVal));
370 napi_value jsParam = AppExecFwk::WrapWantParams(env, options.parameters);
371 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, *jsOptions, "parameters", jsParam));
372 }
373
CreateJsSetPropertiesOptions(napi_env env,SetPropertiesOptions & options,napi_value * jsOptions)374 void NapiAppAccountAuthenticator::CreateJsSetPropertiesOptions(
375 napi_env env, SetPropertiesOptions &options, napi_value *jsOptions)
376 {
377 NAPI_CALL_RETURN_VOID(env, napi_create_object(env, jsOptions));
378 napi_value jsProperties = AppExecFwk::WrapWantParams(env, options.properties);
379 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, *jsOptions, "properties", jsProperties));
380 napi_value jsParam = AppExecFwk::WrapWantParams(env, options.parameters);
381 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, *jsOptions, "parameters", jsParam));
382 }
383
CallJsFunction(napi_env env,napi_ref funcRef,napi_value * argv,size_t argc)384 void NapiAppAccountAuthenticator::CallJsFunction(
385 napi_env env, napi_ref funcRef, napi_value *argv, size_t argc)
386 {
387 napi_value undefined = nullptr;
388 napi_get_undefined(env, &undefined);
389 napi_value returnVal;
390 napi_value function = nullptr;
391 napi_get_reference_value(env, funcRef, &function);
392 napi_call_function(env, undefined, function, argc, argv, &returnVal);
393 }
394
AddAccountImplicitlyWork(uv_work_t * work,int status)395 void NapiAppAccountAuthenticator::AddAccountImplicitlyWork(uv_work_t *work, int status)
396 {
397 std::unique_ptr<uv_work_t> workPtr(work);
398 napi_handle_scope scope = nullptr;
399 if (!InitUvWorkCallbackEnv(work, scope)) {
400 return;
401 }
402 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
403 napi_value jsAuthType;
404 napi_create_string_utf8(param->env, param->authType.c_str(), NAPI_AUTO_LENGTH, &jsAuthType);
405 napi_value jsCallerBundleName;
406 napi_create_string_utf8(param->env, param->callerBundleName.c_str(), NAPI_AUTO_LENGTH, &jsCallerBundleName);
407 napi_value jsOptions = AppExecFwk::WrapWantParams(param->env, param->options);
408 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
409 napi_value argv[] = { jsAuthType, jsCallerBundleName, jsOptions, jsCallback};
410 CallJsFunction(param->env, param->jsAuthenticator.addAccountImplicitly, argv, ARGS_SIZE_FOUR);
411 napi_close_handle_scope(param->env, scope);
412 }
413
AuthenticateWork(uv_work_t * work,int status)414 void NapiAppAccountAuthenticator::AuthenticateWork(uv_work_t *work, int status)
415 {
416 std::unique_ptr<uv_work_t> workPtr(work);
417 napi_handle_scope scope = nullptr;
418 if (!InitUvWorkCallbackEnv(work, scope)) {
419 return;
420 }
421 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
422 napi_value jsName;
423 napi_create_string_utf8(param->env, param->name.c_str(), NAPI_AUTO_LENGTH, &jsName);
424 napi_value jsAuthType;
425 napi_create_string_utf8(param->env, param->authType.c_str(), NAPI_AUTO_LENGTH, &jsAuthType);
426 napi_value jsCallerBundleName;
427 napi_create_string_utf8(param->env, param->callerBundleName.c_str(), NAPI_AUTO_LENGTH, &jsCallerBundleName);
428 napi_value jsOptions = AppExecFwk::WrapWantParams(param->env, param->options);
429 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
430 napi_value argv[] = { jsName, jsAuthType, jsCallerBundleName, jsOptions, jsCallback};
431 CallJsFunction(param->env, param->jsAuthenticator.authenticate, argv, ARGS_SIZE_FIVE);
432 napi_close_handle_scope(param->env, scope);
433 }
434
CreateAccountImplicitlyWork(uv_work_t * work,int status)435 void NapiAppAccountAuthenticator::CreateAccountImplicitlyWork(uv_work_t *work, int status)
436 {
437 std::unique_ptr<uv_work_t> workPtr(work);
438 napi_handle_scope scope = nullptr;
439 if (!InitUvWorkCallbackEnv(work, scope)) {
440 return;
441 }
442 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
443 napi_value jsObject = nullptr;
444 napi_create_object(param->env, &jsObject);
445 if (param->createOptions.hasAuthType) {
446 napi_value jsAuthType;
447 napi_create_string_utf8(param->env, param->createOptions.authType.c_str(), NAPI_AUTO_LENGTH, &jsAuthType);
448 napi_set_named_property(param->env, jsObject, "authType", jsAuthType);
449 }
450 if (param->createOptions.hasRequiredLabels) {
451 napi_value jsRequiredLabels = CreateStringArray(param->env, param->createOptions.requiredLabels);
452 napi_set_named_property(param->env, jsObject, "requiredLabels", jsRequiredLabels);
453 }
454 napi_value jsParams = AppExecFwk::WrapWantParams(param->env, param->createOptions.parameters.GetParams());
455 napi_set_named_property(param->env, jsObject, "parameters", jsParams);
456 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
457 napi_value argv[] = {jsObject, jsCallback};
458 CallJsFunction(param->env, param->jsAuthenticator.createAccountImplicitly, argv, ARGS_SIZE_TWO);
459 napi_close_handle_scope(param->env, scope);
460 }
461
AuthWork(uv_work_t * work,int status)462 void NapiAppAccountAuthenticator::AuthWork(uv_work_t *work, int status)
463 {
464 std::unique_ptr<uv_work_t> workPtr(work);
465 napi_handle_scope scope = nullptr;
466 if (!InitUvWorkCallbackEnv(work, scope)) {
467 return;
468 }
469 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
470 napi_value jsName;
471 napi_create_string_utf8(param->env, param->name.c_str(), NAPI_AUTO_LENGTH, &jsName);
472 napi_value jsAuthType;
473 napi_create_string_utf8(param->env, param->authType.c_str(), NAPI_AUTO_LENGTH, &jsAuthType);
474 napi_value jsOptions = AppExecFwk::WrapWantParams(param->env, param->options);
475 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
476 napi_value argv[] = { jsName, jsAuthType, jsOptions, jsCallback};
477 CallJsFunction(param->env, param->jsAuthenticator.auth, argv, ARGS_SIZE_FOUR);
478 napi_close_handle_scope(param->env, scope);
479 }
480
VerifyCredentialWork(uv_work_t * work,int status)481 void NapiAppAccountAuthenticator::VerifyCredentialWork(uv_work_t *work, int status)
482 {
483 std::unique_ptr<uv_work_t> workPtr(work);
484 napi_handle_scope scope = nullptr;
485 if (!InitUvWorkCallbackEnv(work, scope)) {
486 return;
487 }
488 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
489 napi_value jsName;
490 napi_create_string_utf8(param->env, param->name.c_str(), NAPI_AUTO_LENGTH, &jsName);
491 napi_value jsOptions;
492 CreateJsVerifyCredentialOptions(param->env, param->verifyCredOptions, &jsOptions);
493 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
494 napi_value argv[] = { jsName, jsOptions, jsCallback};
495 CallJsFunction(param->env, param->jsAuthenticator.verifyCredential, argv, ARGS_SIZE_THREE);
496 napi_close_handle_scope(param->env, scope);
497 }
498
SetPropertiesWork(uv_work_t * work,int status)499 void NapiAppAccountAuthenticator::SetPropertiesWork(uv_work_t *work, int status)
500 {
501 std::unique_ptr<uv_work_t> workPtr(work);
502 napi_handle_scope scope = nullptr;
503 if (!InitUvWorkCallbackEnv(work, scope)) {
504 return;
505 }
506 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
507 napi_value jsOptions;
508 CreateJsSetPropertiesOptions(param->env, param->setPropOptions, &jsOptions);
509 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
510 napi_value argv[] = {jsOptions, jsCallback};
511 CallJsFunction(param->env, param->jsAuthenticator.setProperties, argv, ARGS_SIZE_TWO);
512 napi_close_handle_scope(param->env, scope);
513 }
514
CheckAccountLabelsWork(uv_work_t * work,int status)515 void NapiAppAccountAuthenticator::CheckAccountLabelsWork(uv_work_t *work, int status)
516 {
517 std::unique_ptr<uv_work_t> workPtr(work);
518 napi_handle_scope scope = nullptr;
519 if (!InitUvWorkCallbackEnv(work, scope)) {
520 return;
521 }
522 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
523 napi_value jsName;
524 napi_create_string_utf8(param->env, param->name.c_str(), NAPI_AUTO_LENGTH, &jsName);
525 napi_value jsLabels = nullptr;
526 napi_create_array(param->env, &jsLabels);
527 for (size_t i = 0; i < param->labels.size(); ++i) {
528 napi_value value = nullptr;
529 napi_create_string_utf8(param->env, param->labels[i].c_str(), NAPI_AUTO_LENGTH, &value);
530 napi_set_element(param->env, jsLabels, i, value);
531 }
532 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
533 napi_value argv[] = {jsName, jsLabels, jsCallback};
534 CallJsFunction(param->env, param->jsAuthenticator.checkAccountLabels, argv, ARGS_SIZE_THREE);
535 napi_close_handle_scope(param->env, scope);
536 }
537
IsAccountRemovableWork(uv_work_t * work,int status)538 void NapiAppAccountAuthenticator::IsAccountRemovableWork(uv_work_t *work, int status)
539 {
540 std::unique_ptr<uv_work_t> workPtr(work);
541 napi_handle_scope scope = nullptr;
542 if (!InitUvWorkCallbackEnv(work, scope)) {
543 return;
544 }
545 std::unique_ptr<JsAuthenticatorParam> param(reinterpret_cast<JsAuthenticatorParam *>(work->data));
546 napi_value jsName;
547 napi_create_string_utf8(param->env, param->name.c_str(), NAPI_AUTO_LENGTH, &jsName);
548 napi_value jsCallback = CreateAuthenticatorCallback(param->env, param->callback);
549 napi_value argv[] = {jsName, jsCallback};
550 CallJsFunction(param->env, param->jsAuthenticator.isAccountRemovable, argv, ARGS_SIZE_TWO);
551 napi_close_handle_scope(param->env, scope);
552 }
553
GetJsRemoteObject()554 napi_value NapiAppAccountAuthenticator::GetJsRemoteObject()
555 {
556 return remoteObject_;
557 }
558
SetJsRemoteObject(napi_value remoteObject)559 void NapiAppAccountAuthenticator::SetJsRemoteObject(napi_value remoteObject)
560 {
561 remoteObject_ = remoteObject;
562 }
563
GetRemoteObject(napi_env env,napi_callback_info cbInfo)564 napi_value NapiAppAccountAuthenticator::GetRemoteObject(napi_env env, napi_callback_info cbInfo)
565 {
566 napi_value thisVar = nullptr;
567 napi_get_cb_info(env, cbInfo, nullptr, nullptr, &thisVar, nullptr);
568 return thisVar;
569 }
570
Init(napi_env env,napi_value exports)571 napi_value NapiAppAccountAuthenticator::Init(napi_env env, napi_value exports)
572 {
573 const std::string className = "Authenticator";
574 napi_value constructor = nullptr;
575 napi_define_class(env, className.c_str(), className.length(), JsConstructor, nullptr,
576 0, nullptr, &constructor);
577 NAPI_ASSERT(env, constructor != nullptr, "define js class Authenticator failed");
578 napi_status status = napi_set_named_property(env, exports, className.c_str(), constructor);
579 NAPI_ASSERT(env, status == napi_ok, "set property Authenticator to exports failed");
580 return exports;
581 }
582
GetNamedFunction(napi_env env,napi_value value,const std::string & name,napi_ref * result)583 napi_status NapiAppAccountAuthenticator::GetNamedFunction(
584 napi_env env, napi_value value, const std::string &name, napi_ref *result)
585 {
586 napi_value jsFunc = nullptr;
587 napi_get_named_property(env, value, name.c_str(), &jsFunc);
588 return napi_create_reference(env, jsFunc, 1, result);
589 }
590
JsConstructor(napi_env env,napi_callback_info info)591 napi_value NapiAppAccountAuthenticator::JsConstructor(napi_env env, napi_callback_info info)
592 {
593 napi_value thisVar = nullptr;
594 napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
595 NAPI_ASSERT(env, status == napi_ok, "get callback info failed");
596 JsAuthenticator jsAuthenticator;
597 GetNamedFunction(env, thisVar, "addAccountImplicitly", &jsAuthenticator.addAccountImplicitly);
598 GetNamedFunction(env, thisVar, "authenticate", &jsAuthenticator.authenticate);
599 GetNamedFunction(env, thisVar, "verifyCredential", &jsAuthenticator.verifyCredential);
600 GetNamedFunction(env, thisVar, "checkAccountLabels", &jsAuthenticator.checkAccountLabels);
601 GetNamedFunction(env, thisVar, "isAccountRemovable", &jsAuthenticator.isAccountRemovable);
602 GetNamedFunction(env, thisVar, "checkAccountRemovable", &jsAuthenticator.isAccountRemovable);
603 GetNamedFunction(env, thisVar, "setProperties", &jsAuthenticator.setProperties);
604 GetNamedFunction(env, thisVar, "createAccountImplicitly", &jsAuthenticator.createAccountImplicitly);
605 GetNamedFunction(env, thisVar, "auth", &jsAuthenticator.auth);
606 napi_value object = nullptr;
607 napi_create_object(env, &object);
608 NAPIRemoteObjectExport(env, object);
609 sptr<NapiAppAccountAuthenticator> authenticator =
610 new (std::nothrow) NapiAppAccountAuthenticator(env, jsAuthenticator);
611 if (authenticator == nullptr) {
612 ACCOUNT_LOGE("failed to construct NapiAppAccountAuthenticator");
613 return nullptr;
614 }
615 napi_value napiRemoteObj = NAPI_ohos_rpc_CreateJsRemoteObject(env, authenticator->AsObject());
616 napi_value func = nullptr;
617 napi_create_function(env, "getRemoteObject", 0, GetRemoteObject, nullptr, &func);
618 NAPI_ASSERT(env, func != nullptr, "create function getRemoteObject failed");
619 status = napi_set_named_property(env, napiRemoteObj, "getRemoteObject", func);
620 NAPI_ASSERT(env, status == napi_ok, "set property getRemoteObject failed");
621 status = napi_add_env_cleanup_hook(env, OnEnvCleanUp, authenticator.GetRefPtr());
622 NAPI_ASSERT(env, status == napi_ok, "add cleanup hook failed");
623 return napiRemoteObj;
624 }
625 } // namespace AccountJsKit
626 } // namespace OHOS