aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/bookmark/BookmarkFileService.php4
-rw-r--r--application/bookmark/BookmarkFilter.php17
-rw-r--r--application/front/controller/admin/ShaarliAdminController.php2
-rw-r--r--application/front/controller/visitor/FeedController.php4
-rw-r--r--application/front/controller/visitor/ShaarliVisitorController.php26
-rw-r--r--application/legacy/LegacyController.php12
-rw-r--r--application/legacy/LegacyRouter.php134
-rw-r--r--application/plugin/PluginManager.php4
-rw-r--r--doc/md/Plugin-System.md68
-rw-r--r--package.json2
-rw-r--r--plugins/qrcode/qrcode.php4
-rw-r--r--tests/bookmark/BookmarkFileServiceTest.php30
-rw-r--r--tests/bookmark/BookmarkFilterTest.php14
-rw-r--r--tests/front/controller/visitor/FeedControllerTest.php6
-rw-r--r--tests/legacy/LegacyRouterTest.php512
-rw-r--r--yarn.lock18
16 files changed, 152 insertions, 705 deletions
diff --git a/application/bookmark/BookmarkFileService.php b/application/bookmark/BookmarkFileService.php
index e3a61146..c9ec2609 100644
--- a/application/bookmark/BookmarkFileService.php
+++ b/application/bookmark/BookmarkFileService.php
@@ -362,7 +362,9 @@ class BookmarkFileService implements BookmarkServiceInterface
362 */ 362 */
363 public function filterDay($request) 363 public function filterDay($request)
364 { 364 {
365 return $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_DAY, $request); 365 $visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC;
366
367 return $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_DAY, $request, false, $visibility);
366 } 368 }
367 369
368 /** 370 /**
diff --git a/application/bookmark/BookmarkFilter.php b/application/bookmark/BookmarkFilter.php
index 797a36b8..6636bbfe 100644
--- a/application/bookmark/BookmarkFilter.php
+++ b/application/bookmark/BookmarkFilter.php
@@ -115,7 +115,7 @@ class BookmarkFilter
115 return $this->filterTags($request, $casesensitive, $visibility); 115 return $this->filterTags($request, $casesensitive, $visibility);
116 } 116 }
117 case self::$FILTER_DAY: 117 case self::$FILTER_DAY:
118 return $this->filterDay($request); 118 return $this->filterDay($request, $visibility);
119 default: 119 default:
120 return $this->noFilter($visibility); 120 return $this->noFilter($visibility);
121 } 121 }
@@ -425,21 +425,26 @@ class BookmarkFilter
425 * print_r($mydb->filterDay('20120125')); 425 * print_r($mydb->filterDay('20120125'));
426 * 426 *
427 * @param string $day day to filter. 427 * @param string $day day to filter.
428 * 428 * @param string $visibility return only all/private/public bookmarks.
429
429 * @return array all link matching given day. 430 * @return array all link matching given day.
430 * 431 *
431 * @throws Exception if date format is invalid. 432 * @throws Exception if date format is invalid.
432 */ 433 */
433 public function filterDay($day) 434 public function filterDay($day, $visibility)
434 { 435 {
435 if (!checkDateFormat('Ymd', $day)) { 436 if (!checkDateFormat('Ymd', $day)) {
436 throw new Exception('Invalid date format'); 437 throw new Exception('Invalid date format');
437 } 438 }
438 439
439 $filtered = []; 440 $filtered = [];
440 foreach ($this->bookmarks as $key => $l) { 441 foreach ($this->bookmarks as $key => $bookmark) {
441 if ($l->getCreated()->format('Ymd') == $day) { 442 if ($visibility === static::$PUBLIC && $bookmark->isPrivate()) {
442 $filtered[$key] = $l; 443 continue;
444 }
445
446 if ($bookmark->getCreated()->format('Ymd') == $day) {
447 $filtered[$key] = $bookmark;
443 } 448 }
444 } 449 }
445 450
diff --git a/application/front/controller/admin/ShaarliAdminController.php b/application/front/controller/admin/ShaarliAdminController.php
index 3b5939bb..c26c9cbe 100644
--- a/application/front/controller/admin/ShaarliAdminController.php
+++ b/application/front/controller/admin/ShaarliAdminController.php
@@ -4,9 +4,7 @@ declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller\Admin; 5namespace Shaarli\Front\Controller\Admin;
6 6
7use Shaarli\Container\ShaarliContainer;
8use Shaarli\Front\Controller\Visitor\ShaarliVisitorController; 7use Shaarli\Front\Controller\Visitor\ShaarliVisitorController;
9use Shaarli\Front\Exception\UnauthorizedException;
10use Shaarli\Front\Exception\WrongTokenException; 8use Shaarli\Front\Exception\WrongTokenException;
11use Shaarli\Security\SessionManager; 9use Shaarli\Security\SessionManager;
12use Slim\Http\Request; 10use Slim\Http\Request;
diff --git a/application/front/controller/visitor/FeedController.php b/application/front/controller/visitor/FeedController.php
index da2848c2..8d8b546a 100644
--- a/application/front/controller/visitor/FeedController.php
+++ b/application/front/controller/visitor/FeedController.php
@@ -46,10 +46,10 @@ class FeedController extends ShaarliVisitorController
46 46
47 $data = $this->container->feedBuilder->buildData($feedType, $request->getParams()); 47 $data = $this->container->feedBuilder->buildData($feedType, $request->getParams());
48 48
49 $this->executePageHooks('render_feed', $data, $feedType); 49 $this->executePageHooks('render_feed', $data, 'feed.' . $feedType);
50 $this->assignAllView($data); 50 $this->assignAllView($data);
51 51
52 $content = $this->render('feed.'. $feedType); 52 $content = $this->render('feed.' . $feedType);
53 53
54 $cache->cache($content); 54 $cache->cache($content);
55 55
diff --git a/application/front/controller/visitor/ShaarliVisitorController.php b/application/front/controller/visitor/ShaarliVisitorController.php
index f17c8ed3..cd27455b 100644
--- a/application/front/controller/visitor/ShaarliVisitorController.php
+++ b/application/front/controller/visitor/ShaarliVisitorController.php
@@ -78,16 +78,14 @@ abstract class ShaarliVisitorController
78 'footer', 78 'footer',
79 ]; 79 ];
80 80
81 $parameters = $this->buildPluginParameters($template);
82
81 foreach ($common_hooks as $name) { 83 foreach ($common_hooks as $name) {
82 $pluginData = []; 84 $pluginData = [];
83 $this->container->pluginManager->executeHooks( 85 $this->container->pluginManager->executeHooks(
84 'render_' . $name, 86 'render_' . $name,
85 $pluginData, 87 $pluginData,
86 [ 88 $parameters
87 'target' => $template,
88 'loggedin' => $this->container->loginManager->isLoggedIn(),
89 'basePath' => $this->container->basePath,
90 ]
91 ); 89 );
92 $this->assignView('plugins_' . $name, $pluginData); 90 $this->assignView('plugins_' . $name, $pluginData);
93 } 91 }
@@ -95,19 +93,23 @@ abstract class ShaarliVisitorController
95 93
96 protected function executePageHooks(string $hook, array &$data, string $template = null): void 94 protected function executePageHooks(string $hook, array &$data, string $template = null): void
97 { 95 {
98 $params = [
99 'target' => $template,
100 'loggedin' => $this->container->loginManager->isLoggedIn(),
101 'basePath' => $this->container->basePath,
102 ];
103
104 $this->container->pluginManager->executeHooks( 96 $this->container->pluginManager->executeHooks(
105 $hook, 97 $hook,
106 $data, 98 $data,
107 $params 99 $this->buildPluginParameters($template)
108 ); 100 );
109 } 101 }
110 102
103 protected function buildPluginParameters(?string $template): array
104 {
105 return [
106 'target' => $template,
107 'loggedin' => $this->container->loginManager->isLoggedIn(),
108 'basePath' => $this->container->basePath,
109 'bookmarkService' => $this->container->bookmarkService
110 ];
111 }
112
111 /** 113 /**
112 * Simple helper which prepend the base path to redirect path. 114 * Simple helper which prepend the base path to redirect path.
113 * 115 *
diff --git a/application/legacy/LegacyController.php b/application/legacy/LegacyController.php
index e16dd0f4..826604e7 100644
--- a/application/legacy/LegacyController.php
+++ b/application/legacy/LegacyController.php
@@ -39,13 +39,23 @@ class LegacyController extends ShaarliVisitorController
39 /** Legacy route: ?post= */ 39 /** Legacy route: ?post= */
40 public function post(Request $request, Response $response): Response 40 public function post(Request $request, Response $response): Response
41 { 41 {
42 $parameters = count($request->getQueryParams()) > 0 ? '?' . http_build_query($request->getQueryParams()) : '';
43 $route = '/admin/shaare'; 42 $route = '/admin/shaare';
43 $buildParameters = function (?array $parameters, bool $encode) {
44 if ($encode) {
45 $parameters = array_map('urlencode', $parameters);
46 }
47
48 return count($parameters) > 0 ? '?' . http_build_query($parameters) : '';
49 };
50
44 51
45 if (!$this->container->loginManager->isLoggedIn()) { 52 if (!$this->container->loginManager->isLoggedIn()) {
53 $parameters = $buildParameters($request->getQueryParams(), true);
46 return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters); 54 return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters);
47 } 55 }
48 56
57 $parameters = $buildParameters($request->getQueryParams(), false);
58
49 return $this->redirect($response, $route . $parameters); 59 return $this->redirect($response, $route . $parameters);
50 } 60 }
51 61
diff --git a/application/legacy/LegacyRouter.php b/application/legacy/LegacyRouter.php
index cea99154..0449c7e1 100644
--- a/application/legacy/LegacyRouter.php
+++ b/application/legacy/LegacyRouter.php
@@ -17,15 +17,15 @@ class LegacyRouter
17 17
18 public static $PAGE_PICWALL = 'picwall'; 18 public static $PAGE_PICWALL = 'picwall';
19 19
20 public static $PAGE_TAGCLOUD = 'tagcloud'; 20 public static $PAGE_TAGCLOUD = 'tag.cloud';
21 21
22 public static $PAGE_TAGLIST = 'taglist'; 22 public static $PAGE_TAGLIST = 'tag.list';
23 23
24 public static $PAGE_DAILY = 'daily'; 24 public static $PAGE_DAILY = 'daily';
25 25
26 public static $PAGE_FEED_ATOM = 'atom'; 26 public static $PAGE_FEED_ATOM = 'feed.atom';
27 27
28 public static $PAGE_FEED_RSS = 'rss'; 28 public static $PAGE_FEED_RSS = 'feed.rss';
29 29
30 public static $PAGE_TOOLS = 'tools'; 30 public static $PAGE_TOOLS = 'tools';
31 31
@@ -37,7 +37,7 @@ class LegacyRouter
37 37
38 public static $PAGE_ADDLINK = 'addlink'; 38 public static $PAGE_ADDLINK = 'addlink';
39 39
40 public static $PAGE_EDITLINK = 'edit_link'; 40 public static $PAGE_EDITLINK = 'editlink';
41 41
42 public static $PAGE_DELETELINK = 'delete_link'; 42 public static $PAGE_DELETELINK = 'delete_link';
43 43
@@ -60,128 +60,4 @@ class LegacyRouter
60 public static $PAGE_THUMBS_UPDATE = 'thumbs_update'; 60 public static $PAGE_THUMBS_UPDATE = 'thumbs_update';
61 61
62 public static $GET_TOKEN = 'token'; 62 public static $GET_TOKEN = 'token';
63
64 /**
65 * Reproducing renderPage() if hell, to avoid regression.
66 *
67 * This highlights how bad this needs to be rewrite,
68 * but let's focus on plugins for now.
69 *
70 * @param string $query $_SERVER['QUERY_STRING'].
71 * @param array $get $_SERVER['GET'].
72 * @param bool $loggedIn true if authenticated user.
73 *
74 * @return string page found.
75 */
76 public static function findPage($query, $get, $loggedIn)
77 {
78 $loggedIn = ($loggedIn === true) ? true : false;
79
80 if (empty($query) && !isset($get['edit_link']) && !isset($get['post'])) {
81 return self::$PAGE_LINKLIST;
82 }
83
84 if (startsWith($query, 'do=' . self::$PAGE_LOGIN) && $loggedIn === false) {
85 return self::$PAGE_LOGIN;
86 }
87
88 if (startsWith($query, 'do=' . self::$PAGE_PICWALL)) {
89 return self::$PAGE_PICWALL;
90 }
91
92 if (startsWith($query, 'do=' . self::$PAGE_TAGCLOUD)) {
93 return self::$PAGE_TAGCLOUD;
94 }
95
96 if (startsWith($query, 'do=' . self::$PAGE_TAGLIST)) {
97 return self::$PAGE_TAGLIST;
98 }
99
100 if (startsWith($query, 'do=' . self::$PAGE_OPENSEARCH)) {
101 return self::$PAGE_OPENSEARCH;
102 }
103
104 if (startsWith($query, 'do=' . self::$PAGE_DAILY)) {
105 return self::$PAGE_DAILY;
106 }
107
108 if (startsWith($query, 'do=' . self::$PAGE_FEED_ATOM)) {
109 return self::$PAGE_FEED_ATOM;
110 }
111
112 if (startsWith($query, 'do=' . self::$PAGE_FEED_RSS)) {
113 return self::$PAGE_FEED_RSS;
114 }
115
116 if (startsWith($query, 'do=' . self::$PAGE_THUMBS_UPDATE)) {
117 return self::$PAGE_THUMBS_UPDATE;
118 }
119
120 if (startsWith($query, 'do=' . self::$AJAX_THUMB_UPDATE)) {
121 return self::$AJAX_THUMB_UPDATE;
122 }
123
124 // At this point, only loggedin pages.
125 if (!$loggedIn) {
126 return self::$PAGE_LINKLIST;
127 }
128
129 if (startsWith($query, 'do=' . self::$PAGE_TOOLS)) {
130 return self::$PAGE_TOOLS;
131 }
132
133 if (startsWith($query, 'do=' . self::$PAGE_CHANGEPASSWORD)) {
134 return self::$PAGE_CHANGEPASSWORD;
135 }
136
137 if (startsWith($query, 'do=' . self::$PAGE_CONFIGURE)) {
138 return self::$PAGE_CONFIGURE;
139 }
140
141 if (startsWith($query, 'do=' . self::$PAGE_CHANGETAG)) {
142 return self::$PAGE_CHANGETAG;
143 }
144
145 if (startsWith($query, 'do=' . self::$PAGE_ADDLINK)) {
146 return self::$PAGE_ADDLINK;
147 }
148
149 if (isset($get['edit_link']) || isset($get['post'])) {
150 return self::$PAGE_EDITLINK;
151 }
152
153 if (isset($get['delete_link'])) {
154 return self::$PAGE_DELETELINK;
155 }
156
157 if (isset($get[self::$PAGE_CHANGE_VISIBILITY])) {
158 return self::$PAGE_CHANGE_VISIBILITY;
159 }
160
161 if (startsWith($query, 'do=' . self::$PAGE_PINLINK)) {
162 return self::$PAGE_PINLINK;
163 }
164
165 if (startsWith($query, 'do=' . self::$PAGE_EXPORT)) {
166 return self::$PAGE_EXPORT;
167 }
168
169 if (startsWith($query, 'do=' . self::$PAGE_IMPORT)) {
170 return self::$PAGE_IMPORT;
171 }
172
173 if (startsWith($query, 'do=' . self::$PAGE_PLUGINSADMIN)) {
174 return self::$PAGE_PLUGINSADMIN;
175 }
176
177 if (startsWith($query, 'do=' . self::$PAGE_SAVE_PLUGINSADMIN)) {
178 return self::$PAGE_SAVE_PLUGINSADMIN;
179 }
180
181 if (startsWith($query, 'do=' . self::$GET_TOKEN)) {
182 return self::$GET_TOKEN;
183 }
184
185 return self::$PAGE_LINKLIST;
186 }
187} 63}
diff --git a/application/plugin/PluginManager.php b/application/plugin/PluginManager.php
index 2d93cb3a..7881e3be 100644
--- a/application/plugin/PluginManager.php
+++ b/application/plugin/PluginManager.php
@@ -112,6 +112,10 @@ class PluginManager
112 $data['_BASE_PATH_'] = $params['basePath']; 112 $data['_BASE_PATH_'] = $params['basePath'];
113 } 113 }
114 114
115 if (isset($params['bookmarkService'])) {
116 $data['_BOOKMARK_SERVICE_'] = $params['bookmarkService'];
117 }
118
115 foreach ($this->loadedPlugins as $plugin) { 119 foreach ($this->loadedPlugins as $plugin) {
116 $hookFunction = $this->buildHookName($hook, $plugin); 120 $hookFunction = $this->buildHookName($hook, $plugin);
117 121
diff --git a/doc/md/Plugin-System.md b/doc/md/Plugin-System.md
index f264e873..87a2638d 100644
--- a/doc/md/Plugin-System.md
+++ b/doc/md/Plugin-System.md
@@ -73,6 +73,26 @@ Every hook function has a `$data` parameter. Its content differs for each hooks.
73 73
74 return $data; 74 return $data;
75 75
76#### Special data
77
78Special additional data are passed to every hook through the
79`$data` parameter to give you access to additional context, and services.
80
81Complete list:
82
83 * `_PAGE_` (string): if the current hook is used to render a template, its name is passed through this additional parameter.
84 * `_LOGGEDIN_` (bool): whether the user is logged in or not.
85 * `_BASE_PATH_` (string): if Shaarli instance is hosted under a subfolder, contains the subfolder path to `index.php` (e.g. `https://domain.tld/shaarli/` -> `/shaarli/`).
86 * `_BOOKMARK_SERVICE_` (`BookmarkServiceInterface`): bookmark service instance, for advanced usage.
87
88Example:
89
90```php
91if ($data['_PAGE_'] === TemplatePage::LINKLIST && $data['LOGGEDIN'] === true) {
92 // Do something for logged in users when the link list is rendered
93}
94```
95
76#### Filling templates placeholder 96#### Filling templates placeholder
77 97
78Template placeholders are displayed in template in specific places. 98Template placeholders are displayed in template in specific places.
@@ -95,7 +115,7 @@ When a page is displayed, every variable send to the template engine is passed t
95 115
96The data contained by this array can be altered before template rendering. 116The data contained by this array can be altered before template rendering.
97 117
98For exemple, in linklist, it is possible to alter every title: 118For example, in linklist, it is possible to alter every title:
99 119
100```php 120```php
101// mind the reference if you want $data to be altered 121// mind the reference if you want $data to be altered
@@ -156,8 +176,7 @@ Allow plugin to add content in page headers.
156 176
157`$data` is an array containing: 177`$data` is an array containing:
158 178
159- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.). 179 - [Special data](#special-data)
160- `_LOGGEDIN_`: true if user is logged in, false otherwise.
161 180
162##### Template placeholders 181##### Template placeholders
163 182
@@ -185,8 +204,7 @@ Allow plugin to include their own CSS files.
185 204
186`$data` is an array containing: 205`$data` is an array containing:
187 206
188- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.). 207 - [Special data](#special-data)
189- `_LOGGEDIN_`: true if user is logged in, false otherwise.
190 208
191##### Template placeholders 209##### Template placeholders
192 210
@@ -208,8 +226,7 @@ Allow plugin to add content in page footer and include their own JS files.
208 226
209`$data` is an array containing: 227`$data` is an array containing:
210 228
211- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.). 229 - [Special data](#special-data)
212- `_LOGGEDIN_`: true if user is logged in, false otherwise.
213 230
214##### Template placeholders 231##### Template placeholders
215 232
@@ -236,8 +253,8 @@ It allows to add content at the begining and end of the page, after every link d
236 253
237`$data` is an array containing: 254`$data` is an array containing:
238 255
239- `_LOGGEDIN_`: true if user is logged in, false otherwise. 256 - All templates data, including links.
240- All templates data, including links. 257 - [Special data](#special-data)
241 258
242##### Template placeholders 259##### Template placeholders
243 260
@@ -271,7 +288,8 @@ Allow to add fields in the form, or display elements.
271 288
272`$data` is an array containing: 289`$data` is an array containing:
273 290
274- All templates data. 291 - All templates data.
292 - [Special data](#special-data)
275 293
276##### Template placeholders 294##### Template placeholders
277 295
@@ -293,7 +311,8 @@ Allow to add content at the end of the page.
293 311
294`$data` is an array containing: 312`$data` is an array containing:
295 313
296- All templates data. 314 - All templates data.
315 - [Special data](#special-data)
297 316
298##### Template placeholders 317##### Template placeholders
299 318
@@ -315,8 +334,8 @@ Allow to add content at the top and bottom of the page.
315 334
316`$data` is an array containing: 335`$data` is an array containing:
317 336
318- `_LOGGEDIN_`: true if user is logged in, false otherwise. 337 - All templates data.
319- All templates data. 338 - [Special data](#special-data)
320 339
321##### Template placeholders 340##### Template placeholders
322 341
@@ -339,8 +358,8 @@ Allow to add content at the top and bottom of the page.
339 358
340`$data` is an array containing: 359`$data` is an array containing:
341 360
342- `_LOGGEDIN_`: true if user is logged in, false otherwise. 361 - All templates data.
343- All templates data. 362 - [Special data](#special-data)
344 363
345##### Template placeholders 364##### Template placeholders
346 365
@@ -368,8 +387,8 @@ Allow to add content at the top and bottom of the page.
368 387
369`$data` is an array containing: 388`$data` is an array containing:
370 389
371- `_LOGGEDIN_`: true if user is logged in, false otherwise. 390 - All templates data.
372- All templates data. 391 - [Special data](#special-data)
373 392
374##### Template placeholders 393##### Template placeholders
375 394
@@ -394,8 +413,8 @@ Allow to add content at the top and bottom of the page, the bottom of each link
394 413
395`$data` is an array containing: 414`$data` is an array containing:
396 415
397- `_LOGGEDIN_`: true if user is logged in, false otherwise. 416 - All templates data, including links.
398- All templates data, including links. 417 - [Special data](#special-data)
399 418
400##### Template placeholders 419##### Template placeholders
401 420
@@ -420,9 +439,8 @@ Allow to add tags in the feed, either in the header or for each items. Items (li
420 439
421`$data` is an array containing: 440`$data` is an array containing:
422 441
423- `_LOGGEDIN_`: true if user is logged in, false otherwise. 442 - All templates data, including links.
424- `_PAGE_`: containing either `rss` or `atom`. 443 - [Special data](#special-data)
425- All templates data, including links.
426 444
427##### Template placeholders 445##### Template placeholders
428 446
@@ -456,6 +474,8 @@ Allow to alter the link being saved in the datastore.
456- created 474- created
457- updated 475- updated
458 476
477Also [special data](#special-data).
478
459 479
460#### delete_link 480#### delete_link
461 481
@@ -465,7 +485,7 @@ Allow to execute any action before the link is actually removed from the datasto
465 485
466##### Data 486##### Data
467 487
468`$data` is an array containing the link being saved: 488`$data` is an array containing the link being deleted:
469 489
470- id 490- id
471- title 491- title
@@ -477,6 +497,7 @@ Allow to execute any action before the link is actually removed from the datasto
477- created 497- created
478- updated 498- updated
479 499
500Also [special data](#special-data).
480 501
481#### save_plugin_parameters 502#### save_plugin_parameters
482 503
@@ -492,6 +513,7 @@ For example it is used to update the CSS file of the `default_colors` plugins.
492So if the plugin has a parameter called `MYPLUGIN_PARAMETER`, 513So if the plugin has a parameter called `MYPLUGIN_PARAMETER`,
493the array will contain an entry with `MYPLUGIN_PARAMETER` as a key. 514the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
494 515
516Also [special data](#special-data).
495 517
496## Guide for template designer 518## Guide for template designer
497 519
diff --git a/package.json b/package.json
index f3d9b51e..dc2b2872 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
21 "eslint-plugin-import": "^2.8.0", 21 "eslint-plugin-import": "^2.8.0",
22 "extract-text-webpack-plugin": "^3.0.2", 22 "extract-text-webpack-plugin": "^3.0.2",
23 "file-loader": "^1.1.6", 23 "file-loader": "^1.1.6",
24 "node-sass": "^4.12.0", 24 "node-sass": "^4.13.1",
25 "sass-lint": "^1.12.1", 25 "sass-lint": "^1.12.1",
26 "sass-loader": "^6.0.6", 26 "sass-loader": "^6.0.6",
27 "style-loader": "^0.19.1", 27 "style-loader": "^0.19.1",
diff --git a/plugins/qrcode/qrcode.php b/plugins/qrcode/qrcode.php
index 3b5dae34..56ae47b3 100644
--- a/plugins/qrcode/qrcode.php
+++ b/plugins/qrcode/qrcode.php
@@ -42,7 +42,7 @@ function hook_qrcode_render_linklist($data)
42function hook_qrcode_render_footer($data) 42function hook_qrcode_render_footer($data)
43{ 43{
44 if ($data['_PAGE_'] == TemplatePage::LINKLIST) { 44 if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
45 $data['js_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js'; 45 $data['js_files'][] = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
46 } 46 }
47 47
48 return $data; 48 return $data;
@@ -58,7 +58,7 @@ function hook_qrcode_render_footer($data)
58function hook_qrcode_render_includes($data) 58function hook_qrcode_render_includes($data)
59{ 59{
60 if ($data['_PAGE_'] == TemplatePage::LINKLIST) { 60 if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
61 $data['css_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css'; 61 $data['css_files'][] = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css';
62 } 62 }
63 63
64 return $data; 64 return $data;
diff --git a/tests/bookmark/BookmarkFileServiceTest.php b/tests/bookmark/BookmarkFileServiceTest.php
index a91f374f..a4ec1013 100644
--- a/tests/bookmark/BookmarkFileServiceTest.php
+++ b/tests/bookmark/BookmarkFileServiceTest.php
@@ -1066,6 +1066,36 @@ class BookmarkFileServiceTest extends TestCase
1066 } 1066 }
1067 1067
1068 /** 1068 /**
1069 * Test filterDay while logged in
1070 */
1071 public function testFilterDayLoggedIn(): void
1072 {
1073 $bookmarks = $this->privateLinkDB->filterDay('20121206');
1074 $expectedIds = [4, 9, 1, 0];
1075
1076 static::assertCount(4, $bookmarks);
1077 foreach ($bookmarks as $bookmark) {
1078 $i = ($i ?? -1) + 1;
1079 static::assertSame($expectedIds[$i], $bookmark->getId());
1080 }
1081 }
1082
1083 /**
1084 * Test filterDay while logged out
1085 */
1086 public function testFilterDayLoggedOut(): void
1087 {
1088 $bookmarks = $this->publicLinkDB->filterDay('20121206');
1089 $expectedIds = [4, 9, 1];
1090
1091 static::assertCount(3, $bookmarks);
1092 foreach ($bookmarks as $bookmark) {
1093 $i = ($i ?? -1) + 1;
1094 static::assertSame($expectedIds[$i], $bookmark->getId());
1095 }
1096 }
1097
1098 /**
1069 * Allows to test LinkDB's private methods 1099 * Allows to test LinkDB's private methods
1070 * 1100 *
1071 * @see 1101 * @see
diff --git a/tests/bookmark/BookmarkFilterTest.php b/tests/bookmark/BookmarkFilterTest.php
index d4c71cb9..91e139c2 100644
--- a/tests/bookmark/BookmarkFilterTest.php
+++ b/tests/bookmark/BookmarkFilterTest.php
@@ -6,7 +6,6 @@ use Exception;
6use PHPUnit\Framework\TestCase; 6use PHPUnit\Framework\TestCase;
7use ReferenceLinkDB; 7use ReferenceLinkDB;
8use Shaarli\Config\ConfigManager; 8use Shaarli\Config\ConfigManager;
9use Shaarli\Formatter\FormatterFactory;
10use Shaarli\History; 9use Shaarli\History;
11 10
12/** 11/**
@@ -36,7 +35,7 @@ class BookmarkFilterTest extends TestCase
36 /** 35 /**
37 * Instantiate linkFilter with ReferenceLinkDB data. 36 * Instantiate linkFilter with ReferenceLinkDB data.
38 */ 37 */
39 public static function setUpBeforeClass() 38 public static function setUpBeforeClass(): void
40 { 39 {
41 $conf = new ConfigManager('tests/utils/config/configJson'); 40 $conf = new ConfigManager('tests/utils/config/configJson');
42 $conf->set('resource.datastore', self::$testDatastore); 41 $conf->set('resource.datastore', self::$testDatastore);
@@ -190,6 +189,17 @@ class BookmarkFilterTest extends TestCase
190 } 189 }
191 190
192 /** 191 /**
192 * Return bookmarks for a given day
193 */
194 public function testFilterDayRestrictedVisibility(): void
195 {
196 $this->assertEquals(
197 3,
198 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20121206', false, BookmarkFilter::$PUBLIC))
199 );
200 }
201
202 /**
193 * 404 - day not found 203 * 404 - day not found
194 */ 204 */
195 public function testFilterUnknownDay() 205 public function testFilterUnknownDay()
diff --git a/tests/front/controller/visitor/FeedControllerTest.php b/tests/front/controller/visitor/FeedControllerTest.php
index fb417e2a..0a6b577f 100644
--- a/tests/front/controller/visitor/FeedControllerTest.php
+++ b/tests/front/controller/visitor/FeedControllerTest.php
@@ -52,7 +52,7 @@ class FeedControllerTest extends TestCase
52 static::assertSame('data', $data['content']); 52 static::assertSame('data', $data['content']);
53 53
54 static::assertArrayHasKey('loggedin', $param); 54 static::assertArrayHasKey('loggedin', $param);
55 static::assertSame('rss', $param['target']); 55 static::assertSame('feed.rss', $param['target']);
56 }) 56 })
57 ; 57 ;
58 58
@@ -91,7 +91,7 @@ class FeedControllerTest extends TestCase
91 static::assertSame('data', $data['content']); 91 static::assertSame('data', $data['content']);
92 92
93 static::assertArrayHasKey('loggedin', $param); 93 static::assertArrayHasKey('loggedin', $param);
94 static::assertSame('atom', $param['target']); 94 static::assertSame('feed.atom', $param['target']);
95 }) 95 })
96 ; 96 ;
97 97
@@ -131,7 +131,7 @@ class FeedControllerTest extends TestCase
131 static::assertSame('data', $data['content']); 131 static::assertSame('data', $data['content']);
132 132
133 static::assertArrayHasKey('loggedin', $param); 133 static::assertArrayHasKey('loggedin', $param);
134 static::assertSame('atom', $param['target']); 134 static::assertSame('feed.atom', $param['target']);
135 }) 135 })
136 ; 136 ;
137 137
diff --git a/tests/legacy/LegacyRouterTest.php b/tests/legacy/LegacyRouterTest.php
deleted file mode 100644
index c2019ca7..00000000
--- a/tests/legacy/LegacyRouterTest.php
+++ /dev/null
@@ -1,512 +0,0 @@
1<?php
2
3namespace Shaarli\Legacy;
4
5use PHPUnit\Framework\TestCase;
6
7/**
8 * Unit tests for Router
9 */
10class LegacyRouterTest extends TestCase
11{
12 /**
13 * Test findPage: login page output.
14 * Valid: page should be return.
15 *
16 * @return void
17 */
18 public function testFindPageLoginValid()
19 {
20 $this->assertEquals(
21 LegacyRouter::$PAGE_LOGIN,
22 LegacyRouter::findPage('do=login', array(), false)
23 );
24
25 $this->assertEquals(
26 LegacyRouter::$PAGE_LOGIN,
27 LegacyRouter::findPage('do=login', array(), 1)
28 );
29
30 $this->assertEquals(
31 LegacyRouter::$PAGE_LOGIN,
32 LegacyRouter::findPage('do=login&stuff', array(), false)
33 );
34 }
35
36 /**
37 * Test findPage: login page output.
38 * Invalid: page shouldn't be return.
39 *
40 * @return void
41 */
42 public function testFindPageLoginInvalid()
43 {
44 $this->assertNotEquals(
45 LegacyRouter::$PAGE_LOGIN,
46 LegacyRouter::findPage('do=login', array(), true)
47 );
48
49 $this->assertNotEquals(
50 LegacyRouter::$PAGE_LOGIN,
51 LegacyRouter::findPage('do=other', array(), false)
52 );
53 }
54
55 /**
56 * Test findPage: picwall page output.
57 * Valid: page should be return.
58 *
59 * @return void
60 */
61 public function testFindPagePicwallValid()
62 {
63 $this->assertEquals(
64 LegacyRouter::$PAGE_PICWALL,
65 LegacyRouter::findPage('do=picwall', array(), false)
66 );
67
68 $this->assertEquals(
69 LegacyRouter::$PAGE_PICWALL,
70 LegacyRouter::findPage('do=picwall', array(), true)
71 );
72 }
73
74 /**
75 * Test findPage: picwall page output.
76 * Invalid: page shouldn't be return.
77 *
78 * @return void
79 */
80 public function testFindPagePicwallInvalid()
81 {
82 $this->assertEquals(
83 LegacyRouter::$PAGE_PICWALL,
84 LegacyRouter::findPage('do=picwall&stuff', array(), false)
85 );
86
87 $this->assertNotEquals(
88 LegacyRouter::$PAGE_PICWALL,
89 LegacyRouter::findPage('do=other', array(), false)
90 );
91 }
92
93 /**
94 * Test findPage: tagcloud page output.
95 * Valid: page should be return.
96 *
97 * @return void
98 */
99 public function testFindPageTagcloudValid()
100 {
101 $this->assertEquals(
102 LegacyRouter::$PAGE_TAGCLOUD,
103 LegacyRouter::findPage('do=tagcloud', array(), false)
104 );
105
106 $this->assertEquals(
107 LegacyRouter::$PAGE_TAGCLOUD,
108 LegacyRouter::findPage('do=tagcloud', array(), true)
109 );
110
111 $this->assertEquals(
112 LegacyRouter::$PAGE_TAGCLOUD,
113 LegacyRouter::findPage('do=tagcloud&stuff', array(), false)
114 );
115 }
116
117 /**
118 * Test findPage: tagcloud page output.
119 * Invalid: page shouldn't be return.
120 *
121 * @return void
122 */
123 public function testFindPageTagcloudInvalid()
124 {
125 $this->assertNotEquals(
126 LegacyRouter::$PAGE_TAGCLOUD,
127 LegacyRouter::findPage('do=other', array(), false)
128 );
129 }
130
131 /**
132 * Test findPage: linklist page output.
133 * Valid: page should be return.
134 *
135 * @return void
136 */
137 public function testFindPageLinklistValid()
138 {
139 $this->assertEquals(
140 LegacyRouter::$PAGE_LINKLIST,
141 LegacyRouter::findPage('', array(), true)
142 );
143
144 $this->assertEquals(
145 LegacyRouter::$PAGE_LINKLIST,
146 LegacyRouter::findPage('whatever', array(), true)
147 );
148
149 $this->assertEquals(
150 LegacyRouter::$PAGE_LINKLIST,
151 LegacyRouter::findPage('whatever', array(), false)
152 );
153
154 $this->assertEquals(
155 LegacyRouter::$PAGE_LINKLIST,
156 LegacyRouter::findPage('do=tools', array(), false)
157 );
158 }
159
160 /**
161 * Test findPage: tools page output.
162 * Valid: page should be return.
163 *
164 * @return void
165 */
166 public function testFindPageToolsValid()
167 {
168 $this->assertEquals(
169 LegacyRouter::$PAGE_TOOLS,
170 LegacyRouter::findPage('do=tools', array(), true)
171 );
172
173 $this->assertEquals(
174 LegacyRouter::$PAGE_TOOLS,
175 LegacyRouter::findPage('do=tools&stuff', array(), true)
176 );
177 }
178
179 /**
180 * Test findPage: tools page output.
181 * Invalid: page shouldn't be return.
182 *
183 * @return void
184 */
185 public function testFindPageToolsInvalid()
186 {
187 $this->assertNotEquals(
188 LegacyRouter::$PAGE_TOOLS,
189 LegacyRouter::findPage('do=tools', array(), 1)
190 );
191
192 $this->assertNotEquals(
193 LegacyRouter::$PAGE_TOOLS,
194 LegacyRouter::findPage('do=tools', array(), false)
195 );
196
197 $this->assertNotEquals(
198 LegacyRouter::$PAGE_TOOLS,
199 LegacyRouter::findPage('do=other', array(), true)
200 );
201 }
202
203 /**
204 * Test findPage: changepasswd page output.
205 * Valid: page should be return.
206 *
207 * @return void
208 */
209 public function testFindPageChangepasswdValid()
210 {
211 $this->assertEquals(
212 LegacyRouter::$PAGE_CHANGEPASSWORD,
213 LegacyRouter::findPage('do=changepasswd', array(), true)
214 );
215 $this->assertEquals(
216 LegacyRouter::$PAGE_CHANGEPASSWORD,
217 LegacyRouter::findPage('do=changepasswd&stuff', array(), true)
218 );
219 }
220
221 /**
222 * Test findPage: changepasswd page output.
223 * Invalid: page shouldn't be return.
224 *
225 * @return void
226 */
227 public function testFindPageChangepasswdInvalid()
228 {
229 $this->assertNotEquals(
230 LegacyRouter::$PAGE_CHANGEPASSWORD,
231 LegacyRouter::findPage('do=changepasswd', array(), 1)
232 );
233
234 $this->assertNotEquals(
235 LegacyRouter::$PAGE_CHANGEPASSWORD,
236 LegacyRouter::findPage('do=changepasswd', array(), false)
237 );
238
239 $this->assertNotEquals(
240 LegacyRouter::$PAGE_CHANGEPASSWORD,
241 LegacyRouter::findPage('do=other', array(), true)
242 );
243 }
244 /**
245 * Test findPage: configure page output.
246 * Valid: page should be return.
247 *
248 * @return void
249 */
250 public function testFindPageConfigureValid()
251 {
252 $this->assertEquals(
253 LegacyRouter::$PAGE_CONFIGURE,
254 LegacyRouter::findPage('do=configure', array(), true)
255 );
256
257 $this->assertEquals(
258 LegacyRouter::$PAGE_CONFIGURE,
259 LegacyRouter::findPage('do=configure&stuff', array(), true)
260 );
261 }
262
263 /**
264 * Test findPage: configure page output.
265 * Invalid: page shouldn't be return.
266 *
267 * @return void
268 */
269 public function testFindPageConfigureInvalid()
270 {
271 $this->assertNotEquals(
272 LegacyRouter::$PAGE_CONFIGURE,
273 LegacyRouter::findPage('do=configure', array(), 1)
274 );
275
276 $this->assertNotEquals(
277 LegacyRouter::$PAGE_CONFIGURE,
278 LegacyRouter::findPage('do=configure', array(), false)
279 );
280
281 $this->assertNotEquals(
282 LegacyRouter::$PAGE_CONFIGURE,
283 LegacyRouter::findPage('do=other', array(), true)
284 );
285 }
286
287 /**
288 * Test findPage: changetag page output.
289 * Valid: page should be return.
290 *
291 * @return void
292 */
293 public function testFindPageChangetagValid()
294 {
295 $this->assertEquals(
296 LegacyRouter::$PAGE_CHANGETAG,
297 LegacyRouter::findPage('do=changetag', array(), true)
298 );
299
300 $this->assertEquals(
301 LegacyRouter::$PAGE_CHANGETAG,
302 LegacyRouter::findPage('do=changetag&stuff', array(), true)
303 );
304 }
305
306 /**
307 * Test findPage: changetag page output.
308 * Invalid: page shouldn't be return.
309 *
310 * @return void
311 */
312 public function testFindPageChangetagInvalid()
313 {
314 $this->assertNotEquals(
315 LegacyRouter::$PAGE_CHANGETAG,
316 LegacyRouter::findPage('do=changetag', array(), 1)
317 );
318
319 $this->assertNotEquals(
320 LegacyRouter::$PAGE_CHANGETAG,
321 LegacyRouter::findPage('do=changetag', array(), false)
322 );
323
324 $this->assertNotEquals(
325 LegacyRouter::$PAGE_CHANGETAG,
326 LegacyRouter::findPage('do=other', array(), true)
327 );
328 }
329
330 /**
331 * Test findPage: addlink page output.
332 * Valid: page should be return.
333 *
334 * @return void
335 */
336 public function testFindPageAddlinkValid()
337 {
338 $this->assertEquals(
339 LegacyRouter::$PAGE_ADDLINK,
340 LegacyRouter::findPage('do=addlink', array(), true)
341 );
342
343 $this->assertEquals(
344 LegacyRouter::$PAGE_ADDLINK,
345 LegacyRouter::findPage('do=addlink&stuff', array(), true)
346 );
347 }
348
349 /**
350 * Test findPage: addlink page output.
351 * Invalid: page shouldn't be return.
352 *
353 * @return void
354 */
355 public function testFindPageAddlinkInvalid()
356 {
357 $this->assertNotEquals(
358 LegacyRouter::$PAGE_ADDLINK,
359 LegacyRouter::findPage('do=addlink', array(), 1)
360 );
361
362 $this->assertNotEquals(
363 LegacyRouter::$PAGE_ADDLINK,
364 LegacyRouter::findPage('do=addlink', array(), false)
365 );
366
367 $this->assertNotEquals(
368 LegacyRouter::$PAGE_ADDLINK,
369 LegacyRouter::findPage('do=other', array(), true)
370 );
371 }
372
373 /**
374 * Test findPage: export page output.
375 * Valid: page should be return.
376 *
377 * @return void
378 */
379 public function testFindPageExportValid()
380 {
381 $this->assertEquals(
382 LegacyRouter::$PAGE_EXPORT,
383 LegacyRouter::findPage('do=export', array(), true)
384 );
385
386 $this->assertEquals(
387 LegacyRouter::$PAGE_EXPORT,
388 LegacyRouter::findPage('do=export&stuff', array(), true)
389 );
390 }
391
392 /**
393 * Test findPage: export page output.
394 * Invalid: page shouldn't be return.
395 *
396 * @return void
397 */
398 public function testFindPageExportInvalid()
399 {
400 $this->assertNotEquals(
401 LegacyRouter::$PAGE_EXPORT,
402 LegacyRouter::findPage('do=export', array(), 1)
403 );
404
405 $this->assertNotEquals(
406 LegacyRouter::$PAGE_EXPORT,
407 LegacyRouter::findPage('do=export', array(), false)
408 );
409
410 $this->assertNotEquals(
411 LegacyRouter::$PAGE_EXPORT,
412 LegacyRouter::findPage('do=other', array(), true)
413 );
414 }
415
416 /**
417 * Test findPage: import page output.
418 * Valid: page should be return.
419 *
420 * @return void
421 */
422 public function testFindPageImportValid()
423 {
424 $this->assertEquals(
425 LegacyRouter::$PAGE_IMPORT,
426 LegacyRouter::findPage('do=import', array(), true)
427 );
428
429 $this->assertEquals(
430 LegacyRouter::$PAGE_IMPORT,
431 LegacyRouter::findPage('do=import&stuff', array(), true)
432 );
433 }
434
435 /**
436 * Test findPage: import page output.
437 * Invalid: page shouldn't be return.
438 *
439 * @return void
440 */
441 public function testFindPageImportInvalid()
442 {
443 $this->assertNotEquals(
444 LegacyRouter::$PAGE_IMPORT,
445 LegacyRouter::findPage('do=import', array(), 1)
446 );
447
448 $this->assertNotEquals(
449 LegacyRouter::$PAGE_IMPORT,
450 LegacyRouter::findPage('do=import', array(), false)
451 );
452
453 $this->assertNotEquals(
454 LegacyRouter::$PAGE_IMPORT,
455 LegacyRouter::findPage('do=other', array(), true)
456 );
457 }
458
459 /**
460 * Test findPage: editlink page output.
461 * Valid: page should be return.
462 *
463 * @return void
464 */
465 public function testFindPageEditlinkValid()
466 {
467 $this->assertEquals(
468 LegacyRouter::$PAGE_EDITLINK,
469 LegacyRouter::findPage('whatever', array('edit_link' => 1), true)
470 );
471
472 $this->assertEquals(
473 LegacyRouter::$PAGE_EDITLINK,
474 LegacyRouter::findPage('', array('edit_link' => 1), true)
475 );
476
477
478 $this->assertEquals(
479 LegacyRouter::$PAGE_EDITLINK,
480 LegacyRouter::findPage('whatever', array('post' => 1), true)
481 );
482
483 $this->assertEquals(
484 LegacyRouter::$PAGE_EDITLINK,
485 LegacyRouter::findPage('whatever', array('post' => 1, 'edit_link' => 1), true)
486 );
487 }
488
489 /**
490 * Test findPage: editlink page output.
491 * Invalid: page shouldn't be return.
492 *
493 * @return void
494 */
495 public function testFindPageEditlinkInvalid()
496 {
497 $this->assertNotEquals(
498 LegacyRouter::$PAGE_EDITLINK,
499 LegacyRouter::findPage('whatever', array('edit_link' => 1), false)
500 );
501
502 $this->assertNotEquals(
503 LegacyRouter::$PAGE_EDITLINK,
504 LegacyRouter::findPage('whatever', array('edit_link' => 1), 1)
505 );
506
507 $this->assertNotEquals(
508 LegacyRouter::$PAGE_EDITLINK,
509 LegacyRouter::findPage('whatever', array(), true)
510 );
511 }
512}
diff --git a/yarn.lock b/yarn.lock
index df647950..a7ddcfd3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3432,10 +3432,10 @@ lodash.uniq@^4.5.0:
3432 resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" 3432 resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
3433 integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= 3433 integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
3434 3434
3435lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10: 3435lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
3436 version "4.17.19" 3436 version "4.17.20"
3437 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" 3437 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
3438 integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== 3438 integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
3439 3439
3440longest@^1.0.1: 3440longest@^1.0.1:
3441 version "1.0.1" 3441 version "1.0.1"
@@ -3787,10 +3787,10 @@ node-pre-gyp@^0.12.0:
3787 semver "^5.3.0" 3787 semver "^5.3.0"
3788 tar "^4" 3788 tar "^4"
3789 3789
3790node-sass@^4.12.0: 3790node-sass@^4.13.1:
3791 version "4.12.0" 3791 version "4.13.1"
3792 resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" 3792 resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3"
3793 integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== 3793 integrity sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==
3794 dependencies: 3794 dependencies:
3795 async-foreach "^0.1.3" 3795 async-foreach "^0.1.3"
3796 chalk "^1.1.1" 3796 chalk "^1.1.1"
@@ -3799,7 +3799,7 @@ node-sass@^4.12.0:
3799 get-stdin "^4.0.1" 3799 get-stdin "^4.0.1"
3800 glob "^7.0.3" 3800 glob "^7.0.3"
3801 in-publish "^2.0.0" 3801 in-publish "^2.0.0"
3802 lodash "^4.17.11" 3802 lodash "^4.17.15"
3803 meow "^3.7.0" 3803 meow "^3.7.0"
3804 mkdirp "^0.5.1" 3804 mkdirp "^0.5.1"
3805 nan "^2.13.2" 3805 nan "^2.13.2"