@@ -20,7 +20,9 @@ Napi::Object DDWAF::Init(Napi::Env env, Napi::Object exports) {
2020 mlog (" Setting up class DDWAF" );
2121 Napi::Function func = DefineClass (env, " DDWAF" , {
2222 StaticMethod<&DDWAF::version>(" version" ),
23- InstanceMethod<&DDWAF::update>(" update" ),
23+ InstanceMethod<&DDWAF::update_config>(" createOrUpdateConfig" ),
24+ InstanceMethod<&DDWAF::remove_config>(" removeConfig" ),
25+ InstanceAccessor (" configPaths" , &DDWAF::GetConfigPaths, nullptr , napi_enumerable),
2426 InstanceMethod<&DDWAF::createContext>(" createContext" ),
2527 InstanceMethod<&DDWAF::dispose>(" dispose" ),
2628 InstanceAccessor (" disposed" , &DDWAF::GetDisposed, nullptr , napi_enumerable),
@@ -42,29 +44,35 @@ Napi::Value DDWAF::GetDisposed(const Napi::CallbackInfo& info) {
4244DDWAF::DDWAF (const Napi::CallbackInfo& info) : Napi::ObjectWrap<DDWAF>(info) {
4345 Napi::Env env = info.Env ();
4446 size_t arg_len = info.Length ();
45- if (arg_len < 1 ) {
46- Napi::Error::New (env, " Wrong number of arguments, expected at least 1 " ).ThrowAsJavaScriptException ();
47+ if (arg_len < 2 ) {
48+ Napi::Error::New (env, " Wrong number of arguments, expected at least 2 " ).ThrowAsJavaScriptException ();
4749 return ;
4850 }
51+
4952 if (!info[0 ].IsObject ()) {
5053 Napi::TypeError::New (env, " First argument must be an object" ).ThrowAsJavaScriptException ();
5154 return ;
5255 }
5356
57+ if (!info[1 ].IsString ()) {
58+ Napi::TypeError::New (env, " Second argument must be a string" ).ThrowAsJavaScriptException ();
59+ return ;
60+ }
61+
5462 ddwaf_config waf_config{{0 , 0 , 0 }, {nullptr , nullptr }, ddwaf_object_free};
5563
5664 // do not touch these strings after the c_str() assigment
5765 std::string key_regex_str;
5866 std::string value_regex_str;
5967
60- if (arg_len >= 2 ) { // TODO(@simon-id): there is a bug here ?
68+ if (arg_len >= 3 ) { // TODO(@simon-id): there is a bug here ?
6169 // TODO(@simon-id) make a macro here someday
62- if (!info[1 ].IsObject ()) {
70+ if (!info[2 ].IsObject ()) {
6371 Napi::TypeError::New (env, " Second argument must be an object" ).ThrowAsJavaScriptException ();
6472 return ;
6573 }
6674
67- Napi::Object config = info[1 ].ToObject ();
75+ Napi::Object config = info[2 ].ToObject ();
6876
6977 if (config.Has (" obfuscatorKeyRegex" )) {
7078 Napi::Value key_regex = config.Get (" obfuscatorKeyRegex" );
@@ -94,23 +102,35 @@ DDWAF::DDWAF(const Napi::CallbackInfo& info) : Napi::ObjectWrap<DDWAF>(info) {
94102 ddwaf_object rules;
95103 mlog (" building rules" );
96104 to_ddwaf_object (&rules, env, info[0 ], 0 , false , false , JsSet::Create (env), nullptr );
105+ std::string config_path = info[1 ].As <Napi::String>().Utf8Value ();
97106
98107 ddwaf_object diagnostics;
99108
100- mlog (" Init WAF" );
101- ddwaf_handle handle = ddwaf_init (&rules, &waf_config, &diagnostics);
109+ mlog (" Init Builder" );
110+ ddwaf_builder builder = ddwaf_builder_init (&waf_config);
111+ bool result = ddwaf_builder_add_or_update_config (builder, LSTRARG (config_path.c_str ()), &rules, &diagnostics);
112+
102113 ddwaf_object_free (&rules);
103114
104115 Napi::Value diagnostics_js = from_ddwaf_object (&diagnostics, env);
105116 info.This ().As <Napi::Object>().Set (" diagnostics" , diagnostics_js);
106117
107118 ddwaf_object_free (&diagnostics);
108119
120+ if (!result) {
121+ Napi::Error::New (env, " Invalid rules" ).ThrowAsJavaScriptException ();
122+ return ;
123+ }
124+
125+ mlog (" Init WAF" );
126+ ddwaf_handle handle = ddwaf_builder_build_instance (builder);
127+
109128 if (handle == nullptr ) {
110129 Napi::Error::New (env, " Invalid rules" ).ThrowAsJavaScriptException ();
111130 return ;
112131 }
113132
133+ this ->_builder = builder;
114134 this ->_handle = handle;
115135 this ->_disposed = false ;
116136
@@ -124,6 +144,7 @@ void DDWAF::Finalize(Napi::Env env) {
124144 return ;
125145 }
126146 ddwaf_destroy (this ->_handle );
147+ ddwaf_builder_destroy (this ->_builder );
127148 this ->_disposed = true ;
128149}
129150
@@ -132,52 +153,133 @@ void DDWAF::dispose(const Napi::CallbackInfo& info) {
132153 return this ->Finalize (info.Env ());
133154}
134155
135- void DDWAF::update (const Napi::CallbackInfo& info) {
136- mlog (" calling update on DDWAF" );
156+ Napi::Value DDWAF::update_config (const Napi::CallbackInfo& info) {
157+ mlog (" Calling update config on DDWAF" );
137158
138159 Napi::Env env = info.Env ();
139160
140161 if (this ->_disposed ) {
141162 Napi::Error::New (env, " Could not update a disposed WAF instance" ).ThrowAsJavaScriptException ();
142- return ;
163+ return env. Undefined () ;
143164 }
144165
145- if (info.Length () < 1 ) {
146- Napi::Error::New (env, " Wrong number of arguments, expected at least 1 " ).ThrowAsJavaScriptException ();
147- return ;
166+ if (info.Length () < 2 ) {
167+ Napi::Error::New (env, " Wrong number of arguments, expected at least 2 " ).ThrowAsJavaScriptException ();
168+ return env. Undefined () ;
148169 }
170+
149171 if (!info[0 ].IsObject ()) {
150172 Napi::TypeError::New (env, " First argument must be an object" ).ThrowAsJavaScriptException ();
151- return ;
173+ return env.Undefined ();
174+ }
175+
176+ if (!info[1 ].IsString ()) {
177+ Napi::TypeError::New (env, " Second argument must be a string" ).ThrowAsJavaScriptException ();
178+ return env.Undefined ();
152179 }
153180
154181 ddwaf_object update;
155- mlog (" building rules update" );
182+ mlog (" Building config update" );
156183 to_ddwaf_object (&update, env, info[0 ], 0 , false , false , JsSet::Create (env), nullptr );
157184
185+ mlog (" Obtaining config update path" );
186+ std::string config_path = info[1 ].As <Napi::String>().Utf8Value ();
187+
158188 ddwaf_object diagnostics;
159189
160- mlog (" Update DDWAF instance" );
161- ddwaf_handle updated_handle = ddwaf_update (this ->_handle , &update, &diagnostics);
162- ddwaf_object_free (&update);
190+ mlog (" Applying new config to builder" );
191+ bool update_result = ddwaf_builder_add_or_update_config (
192+ this ->_builder ,
193+ LSTRARG (config_path.c_str ()),
194+ &update, &diagnostics);
163195
164196 Napi::Value diagnostics_js = from_ddwaf_object (&diagnostics, env);
165197 info.This ().As <Napi::Object>().Set (" diagnostics" , diagnostics_js);
166198
167199 ddwaf_object_free (&diagnostics);
168200
169- if (updated_handle == nullptr ) {
170- mlog (" DDWAF updated handle is null" );
171- Napi::Error::New (env, " WAF has not been updated" ).ThrowAsJavaScriptException ();
172- return ;
201+ if (!update_result) {
202+ mlog (" DDWAF Builder update config has failed" );
203+ return Napi::Boolean::New (env, false );
173204 }
174205
175- mlog (" New DDWAF updated instance" )
176- ddwaf_destroy (this ->_handle );
177- this -> _handle = updated_handle ;
206+ mlog (" Update DDWAF instance" );
207+ ddwaf_handle updated_handle = ddwaf_builder_build_instance (this ->_builder );
208+ ddwaf_object_free (&update) ;
178209
179- this ->update_known_addresses (info);
180- this ->update_known_actions (info);
210+ if (updated_handle != nullptr ) {
211+ mlog (" New DDWAF updated instance" )
212+ ddwaf_destroy (this ->_handle );
213+ this ->_handle = updated_handle;
214+
215+ this ->update_known_addresses (info);
216+ this ->update_known_actions (info);
217+ }
218+
219+ return Napi::Boolean::New (env, true );
220+ }
221+
222+ Napi::Value DDWAF::remove_config (const Napi::CallbackInfo& info) {
223+ mlog (" Calling remove config on DDWAF" );
224+
225+ Napi::Env env = info.Env ();
226+
227+ if (this ->_disposed ) {
228+ Napi::Error::New (env, " Could not update a disposed WAF instance" ).ThrowAsJavaScriptException ();
229+ return env.Undefined ();
230+ }
231+
232+ if (info.Length () < 1 ) {
233+ Napi::Error::New (env, " Wrong number of arguments, expected at least 1" ).ThrowAsJavaScriptException ();
234+ return env.Undefined ();
235+ }
236+
237+ if (!info[0 ].IsString ()) {
238+ Napi::TypeError::New (env, " First argument must be a string" ).ThrowAsJavaScriptException ();
239+ return env.Undefined ();
240+ }
241+
242+ mlog (" Obtaining config remove path" );
243+ std::string config_path = info[0 ].As <Napi::String>().Utf8Value ();
244+
245+ mlog (" Applying removed config to builder" );
246+ bool remove_result = ddwaf_builder_remove_config (this ->_builder , LSTRARG (config_path.c_str ()));
247+
248+ if (!remove_result) {
249+ mlog (" DDWAF Builder remove config has failed" );
250+ return Napi::Boolean::New (env, false );
251+ }
252+
253+ mlog (" Update DDWAF instance" );
254+ ddwaf_handle updated_handle = ddwaf_builder_build_instance (this ->_builder );
255+
256+ if (updated_handle != nullptr ) {
257+ mlog (" New DDWAF updated instance" )
258+ ddwaf_destroy (this ->_handle );
259+ this ->_handle = updated_handle;
260+
261+ this ->update_known_addresses (info);
262+ this ->update_known_actions (info);
263+ }
264+
265+ return Napi::Boolean::New (env, true );
266+ }
267+
268+ Napi::Value DDWAF::GetConfigPaths (const Napi::CallbackInfo& info) {
269+ Napi::Env env = info.Env ();
270+
271+ if (this ->_disposed ) {
272+ return Napi::Array::New (env, 0 );
273+ }
274+
275+ ddwaf_object config_paths;
276+ ddwaf_builder_get_config_paths (this ->_builder , &config_paths, nullptr , 0 );
277+
278+ Napi::Value config_paths_js = from_ddwaf_object (&config_paths, env);
279+
280+ ddwaf_object_free (&config_paths);
281+
282+ return config_paths_js;
181283}
182284
183285void DDWAF::update_known_addresses (const Napi::CallbackInfo& info) {
0 commit comments