1 /*
2  * Copyright (c) 2022 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_callback.h"
17 
18 #include <uv.h>
19 #include "account_error_no.h"
20 #include "account_log_wrapper.h"
21 #include "iapp_account_authenticator_callback.h"
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24 #include "napi_app_account_common.h"
25 #include "napi_common.h"
26 
27 namespace OHOS {
28 namespace AccountJsKit {
NapiAppAccountAuthenticatorCallback(const sptr<IRemoteObject> & object)29 NapiAppAccountAuthenticatorCallback::NapiAppAccountAuthenticatorCallback(const sptr<IRemoteObject> &object)
30     : object_(object)
31 {}
32 
~NapiAppAccountAuthenticatorCallback()33 NapiAppAccountAuthenticatorCallback::~NapiAppAccountAuthenticatorCallback()
34 {
35     object_ = nullptr;
36 }
37 
GetRemoteObject()38 sptr<IRemoteObject> NapiAppAccountAuthenticatorCallback::GetRemoteObject()
39 {
40     return object_;
41 }
42 
Init(napi_env env,napi_value exports)43 napi_value NapiAppAccountAuthenticatorCallback::Init(napi_env env, napi_value exports)
44 {
45     const std::string className = "AuthenticatorCallback";
46     const std::string classNameNew = "AuthCallback";
47     napi_property_descriptor properties[] = {
48         DECLARE_NAPI_FUNCTION("onResult", JsOnResult),
49         DECLARE_NAPI_FUNCTION("onRequestRedirected", JsOnRequestRedirected),
50         DECLARE_NAPI_FUNCTION("onRequestContinued", JsOnRequestContinued),
51     };
52     napi_value constructor = nullptr;
53     NAPI_CALL(env, napi_define_class(env, className.c_str(), className.length(), JsConstructor, nullptr,
54         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor));
55     NAPI_CALL(env, napi_define_class(env, classNameNew.c_str(), classNameNew.length(), JsConstructor, nullptr,
56         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor));
57     NAPI_ASSERT(env, constructor != nullptr, "define js class Authenticator failed");
58     napi_status status = napi_set_named_property(env, exports, className.c_str(), constructor);
59     NAPI_ASSERT(env, status == napi_ok, "set property Authenticator to exports failed");
60     status = napi_set_named_property(env, exports, classNameNew.c_str(), constructor);
61     NAPI_ASSERT(env, status == napi_ok, "set property Authenticator to exports failed");
62     napi_value global = nullptr;
63     status = napi_get_global(env, &global);
64     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
65     status = napi_set_named_property(env, global, "AuthCallbackConstructor_", constructor);
66     NAPI_ASSERT(env, status == napi_ok, "set stub constructor failed");
67     return exports;
68 }
69 
ParseContextForOnResult(napi_env env,napi_callback_info cbInfo,CallbackParam * param)70 static void ParseContextForOnResult(napi_env env, napi_callback_info cbInfo, CallbackParam *param)
71 {
72     size_t argc = ARGS_SIZE_FOUR;
73     napi_value argv[ARGS_SIZE_FOUR] = {0};
74     napi_value thisVar = nullptr;
75     napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr);
76     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&(param->callback)));
77     for (size_t i = 0; i < argc; ++i) {
78         napi_valuetype valueType = napi_undefined;
79         napi_typeof(env, argv[i], &valueType);
80         if (i == 0 && valueType == napi_number) {
81             napi_get_value_int32(env, argv[i], &(param->resultCode));
82         } else if (i == 1 && valueType == napi_object) {
83             if (!AppExecFwk::UnwrapWantParams(env, argv[i], param->result)) {
84                 ACCOUNT_LOGE("UnwrapWantParams failed");
85                 return;
86             }
87         } else {
88             ACCOUNT_LOGE("Type matching failed");
89         }
90     }
91 }
92 
ParseContextForRequestRedirected(napi_env env,napi_callback_info cbInfo,CallbackParam * param)93 static void ParseContextForRequestRedirected(napi_env env, napi_callback_info cbInfo, CallbackParam *param)
94 {
95     size_t argc = ARGS_SIZE_ONE;
96     napi_value argv[ARGS_SIZE_ONE] = {0};
97     napi_value thisVar = nullptr;
98     napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, nullptr);
99     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&(param->callback)));
100     napi_valuetype valueType = napi_undefined;
101     napi_typeof(env, argv[0], &valueType);
102     if (valueType == napi_object) {
103         if (!AppExecFwk::UnwrapWant(env, argv[0], param->request)) {
104             return;
105         }
106     } else {
107         ACCOUNT_LOGE("Type matching failed");
108     }
109 }
110 
OnAuthenticatorWorkComplete(napi_env env,napi_status status,void * data)111 static void OnAuthenticatorWorkComplete(napi_env env, napi_status status, void *data)
112 {
113     (void)status;
114     CallbackParam *param = reinterpret_cast<CallbackParam *>(data);
115     napi_delete_async_work(env, param->work);
116     delete param;
117     param = nullptr;
118 }
119 
JsOnResult(napi_env env,napi_callback_info cbInfo)120 napi_value NapiAppAccountAuthenticatorCallback::JsOnResult(napi_env env, napi_callback_info cbInfo)
121 {
122     auto param = std::make_unique<CallbackParam>();
123     param->env = env;
124     ParseContextForOnResult(env, cbInfo, param.get());
125 
126     napi_value resourceName = nullptr;
127     NAPI_CALL(env, napi_create_string_latin1(env, "JsOnResult", NAPI_AUTO_LENGTH, &resourceName));
128 
129     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
130             [](napi_env env, void *data) {
131                 CallbackParam *param = reinterpret_cast<CallbackParam *>(data);
132                 if ((param == nullptr) || (param->callback == nullptr)) {
133                     ACCOUNT_LOGE("invalid parameters");
134                     return;
135                 }
136                 auto callbackProxy = iface_cast<IAppAccountAuthenticatorCallback>(param->callback->GetRemoteObject());
137                 if ((callbackProxy != nullptr) && (callbackProxy->AsObject() != nullptr)) {
138                     AAFwk::Want result;
139                     result.SetParams(param->result);
140                     callbackProxy->OnResult(param->resultCode, result);
141                 }
142             },
143             OnAuthenticatorWorkComplete,
144             reinterpret_cast<void *>(param.get()), &param->work));
145     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->work, napi_qos_default));
146     param.release();
147     return NapiGetNull(env);
148 }
149 
JsOnRequestRedirected(napi_env env,napi_callback_info cbInfo)150 napi_value NapiAppAccountAuthenticatorCallback::JsOnRequestRedirected(napi_env env, napi_callback_info cbInfo)
151 {
152     auto param = std::make_unique<CallbackParam>();
153     param->env = env;
154     ParseContextForRequestRedirected(env, cbInfo, param.get());
155 
156     napi_value resourceName = nullptr;
157     NAPI_CALL(env, napi_create_string_latin1(env, "JsOnRequestRedirected", NAPI_AUTO_LENGTH, &resourceName));
158 
159     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
160             [](napi_env env, void *data) {
161                 CallbackParam *param = reinterpret_cast<CallbackParam *>(data);
162                 if ((param == nullptr) || (param->callback == nullptr)) {
163                     ACCOUNT_LOGE("invalid parameters");
164                     return;
165                 }
166                 auto callbackProxy = iface_cast<IAppAccountAuthenticatorCallback>(param->callback->GetRemoteObject());
167                 if ((callbackProxy != nullptr) && (callbackProxy->AsObject() != nullptr)) {
168                     callbackProxy->OnRequestRedirected(param->request);
169                 }
170             },
171             OnAuthenticatorWorkComplete,
172             reinterpret_cast<void *>(param.get()), &param->work));
173     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->work, napi_qos_default));
174     param.release();
175     return NapiGetNull(env);
176 }
177 
JsOnRequestContinued(napi_env env,napi_callback_info cbInfo)178 napi_value NapiAppAccountAuthenticatorCallback::JsOnRequestContinued(napi_env env, napi_callback_info cbInfo)
179 {
180     auto param = std::make_unique<CallbackParam>();
181     napi_value thisVar = nullptr;
182     napi_get_cb_info(env, cbInfo, nullptr, nullptr, &thisVar, nullptr);
183     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&(param->callback)));
184     napi_value resourceName = nullptr;
185     NAPI_CALL(env, napi_create_string_latin1(env, "JsOnRequestContinued", NAPI_AUTO_LENGTH, &resourceName));
186     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
187             [](napi_env env, void *data) {
188                 CallbackParam *param = reinterpret_cast<CallbackParam *>(data);
189                 if ((param == nullptr) || (param->callback == nullptr)) {
190                     ACCOUNT_LOGE("invalid parameters");
191                     return;
192                 }
193                 auto callbackProxy = iface_cast<IAppAccountAuthenticatorCallback>(param->callback->GetRemoteObject());
194                 if ((callbackProxy != nullptr) && (callbackProxy->AsObject() != nullptr)) {
195                     callbackProxy->OnRequestContinued();
196                 }
197             },
198             OnAuthenticatorWorkComplete,
199             reinterpret_cast<void *>(param.get()),
200             &param->work));
201     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->work, napi_qos_default));
202     param.release();
203     return NapiGetNull(env);
204 }
205 
JsConstructor(napi_env env,napi_callback_info info)206 napi_value NapiAppAccountAuthenticatorCallback::JsConstructor(napi_env env, napi_callback_info info)
207 {
208     napi_value thisVar = nullptr;
209     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
210     return thisVar;
211 }
212 }  // namespace AccountJsKit
213 }  // namespace OHOS
214