1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Used to render the header of PMA's pages |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
declare(strict_types=1); |
7
|
|
|
|
8
|
|
|
namespace PhpMyAdmin; |
9
|
|
|
|
10
|
|
|
use PhpMyAdmin\ConfigStorage\Relation; |
11
|
|
|
use PhpMyAdmin\Container\ContainerBuilder; |
12
|
|
|
use PhpMyAdmin\Html\Generator; |
13
|
|
|
use PhpMyAdmin\Navigation\Navigation; |
14
|
|
|
use PhpMyAdmin\Theme\ThemeManager; |
15
|
|
|
|
16
|
|
|
use function array_merge; |
17
|
|
|
use function defined; |
18
|
|
|
use function htmlspecialchars; |
19
|
|
|
use function ini_get; |
20
|
|
|
use function json_encode; |
21
|
|
|
use function sprintf; |
22
|
|
|
use function strtolower; |
23
|
|
|
use function urlencode; |
24
|
|
|
|
25
|
|
|
use const JSON_HEX_TAG; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Class used to output the HTTP and HTML headers |
29
|
|
|
*/ |
30
|
|
|
class Header |
31
|
|
|
{ |
32
|
|
|
/** |
33
|
|
|
* Scripts instance |
34
|
|
|
*/ |
35
|
|
|
private Scripts $scripts; |
36
|
|
|
/** |
37
|
|
|
* Menu instance |
38
|
|
|
*/ |
39
|
|
|
private Menu $menu; |
40
|
|
|
/** |
41
|
|
|
* The page title |
42
|
|
|
*/ |
43
|
|
|
private string $title = ''; |
44
|
|
|
/** |
45
|
|
|
* The value for the id attribute for the body tag |
46
|
|
|
*/ |
47
|
|
|
private string $bodyId = ''; |
48
|
|
|
/** |
49
|
|
|
* Whether to show the top menu |
50
|
|
|
*/ |
51
|
|
|
private bool $menuEnabled; |
52
|
|
|
/** |
53
|
|
|
* Whether to show the warnings |
54
|
|
|
*/ |
55
|
|
|
private bool $warningsEnabled = true; |
56
|
|
|
|
57
|
|
|
private UserPreferences $userPreferences; |
58
|
|
|
|
59
|
|
|
private bool $isTransformationWrapper = false; |
60
|
|
|
|
61
|
36 |
|
public function __construct( |
62
|
|
|
private readonly Template $template, |
63
|
|
|
private readonly Console $console, |
64
|
|
|
private readonly Config $config, |
65
|
|
|
) { |
66
|
36 |
|
$dbi = DatabaseInterface::getInstance(); |
|
|
|
|
67
|
36 |
|
$this->menuEnabled = $dbi->isConnected(); |
68
|
36 |
|
$relation = new Relation($dbi); |
69
|
36 |
|
$this->menu = new Menu($dbi, $this->template, $this->config, $relation, Current::$database, Current::$table); |
70
|
36 |
|
$this->scripts = new Scripts($this->template); |
71
|
36 |
|
$this->addDefaultScripts(); |
72
|
|
|
|
73
|
36 |
|
$this->userPreferences = new UserPreferences($dbi, $relation, $this->template); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Loads common scripts |
78
|
|
|
*/ |
79
|
36 |
|
private function addDefaultScripts(): void |
80
|
|
|
{ |
81
|
36 |
|
$this->scripts->addFile('runtime.js'); |
82
|
36 |
|
$this->scripts->addFile('vendor/jquery/jquery.min.js'); |
83
|
36 |
|
$this->scripts->addFile('vendor/jquery/jquery-migrate.min.js'); |
84
|
36 |
|
$this->scripts->addFile('vendor/sprintf.js'); |
85
|
36 |
|
$this->scripts->addFile('vendor/jquery/jquery-ui.min.js'); |
86
|
36 |
|
$this->scripts->addFile('name-conflict-fixes.js'); |
87
|
36 |
|
$this->scripts->addFile('vendor/bootstrap/bootstrap.bundle.min.js'); |
88
|
36 |
|
$this->scripts->addFile('vendor/js.cookie.min.js'); |
89
|
36 |
|
$this->scripts->addFile('vendor/jquery/jquery.validate.min.js'); |
90
|
36 |
|
$this->scripts->addFile('vendor/jquery/jquery-ui-timepicker-addon.js'); |
91
|
36 |
|
$this->scripts->addFile('index.php', ['route' => '/messages', 'l' => $GLOBALS['lang']]); |
92
|
36 |
|
$this->scripts->addFile('shared.js'); |
93
|
36 |
|
$this->scripts->addFile('menu_resizer.js'); |
94
|
36 |
|
$this->scripts->addFile('main.js'); |
95
|
|
|
|
96
|
36 |
|
$this->scripts->addCode($this->getJsParamsCode()); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Returns, as an array, a list of parameters |
101
|
|
|
* used on the client side |
102
|
|
|
* |
103
|
|
|
* @return mixed[] |
104
|
|
|
*/ |
105
|
36 |
|
public function getJsParams(): array |
106
|
|
|
{ |
107
|
36 |
|
$pftext = $_SESSION['tmpval']['pftext'] ?? ''; |
108
|
|
|
|
109
|
36 |
|
$params = [ |
110
|
|
|
// Do not add any separator, JS code will decide |
111
|
36 |
|
'common_query' => Url::getCommonRaw([], ''), |
112
|
36 |
|
'opendb_url' => Util::getScriptNameForOption($this->config->settings['DefaultTabDatabase'], 'database'), |
113
|
36 |
|
'lang' => $GLOBALS['lang'], |
114
|
36 |
|
'server' => Current::$server, |
115
|
36 |
|
'table' => Current::$table, |
116
|
36 |
|
'db' => Current::$database, |
117
|
36 |
|
'token' => $_SESSION[' PMA_token '], |
118
|
36 |
|
'text_dir' => LanguageManager::$textDir, |
119
|
36 |
|
'LimitChars' => $this->config->settings['LimitChars'], |
120
|
36 |
|
'pftext' => $pftext, |
121
|
36 |
|
'confirm' => $this->config->settings['Confirm'], |
122
|
36 |
|
'LoginCookieValidity' => $this->config->settings['LoginCookieValidity'], |
123
|
36 |
|
'session_gc_maxlifetime' => (int) ini_get('session.gc_maxlifetime'), |
124
|
36 |
|
'logged_in' => DatabaseInterface::getInstance()->isConnected(), |
|
|
|
|
125
|
36 |
|
'is_https' => $this->config->isHttps(), |
126
|
36 |
|
'rootPath' => $this->config->getRootPath(), |
127
|
36 |
|
'arg_separator' => Url::getArgSeparator(), |
128
|
36 |
|
'version' => Version::VERSION, |
129
|
36 |
|
]; |
130
|
36 |
|
if ($this->config->hasSelectedServer()) { |
131
|
|
|
$params['auth_type'] = $this->config->selectedServer['auth_type']; |
132
|
|
|
if (isset($this->config->selectedServer['user'])) { |
133
|
|
|
$params['user'] = $this->config->selectedServer['user']; |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
36 |
|
return $params; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Returns, as a string, a list of parameters |
142
|
|
|
* used on the client side |
143
|
|
|
*/ |
144
|
36 |
|
public function getJsParamsCode(): string |
145
|
|
|
{ |
146
|
36 |
|
$params = $this->getJsParams(); |
147
|
|
|
|
148
|
36 |
|
return 'window.Navigation.update(window.CommonParams.setAll(' . json_encode($params, JSON_HEX_TAG) . '));'; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Returns the Scripts object |
153
|
|
|
* |
154
|
|
|
* @return Scripts object |
155
|
|
|
*/ |
156
|
8 |
|
public function getScripts(): Scripts |
157
|
|
|
{ |
158
|
8 |
|
return $this->scripts; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Returns the Menu object |
163
|
|
|
* |
164
|
|
|
* @return Menu object |
165
|
|
|
*/ |
166
|
|
|
public function getMenu(): Menu |
167
|
|
|
{ |
168
|
|
|
return $this->menu; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Setter for the ID attribute in the BODY tag |
173
|
|
|
* |
174
|
|
|
* @param string $id Value for the ID attribute |
175
|
|
|
*/ |
176
|
4 |
|
public function setBodyId(string $id): void |
177
|
|
|
{ |
178
|
4 |
|
$this->bodyId = htmlspecialchars($id); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Setter for the title of the page |
183
|
|
|
* |
184
|
|
|
* @param string $title New title |
185
|
|
|
*/ |
186
|
|
|
public function setTitle(string $title): void |
187
|
|
|
{ |
188
|
|
|
$this->title = htmlspecialchars($title); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Disables the display of the top menu |
193
|
|
|
*/ |
194
|
|
|
public function disableMenuAndConsole(): void |
195
|
|
|
{ |
196
|
|
|
$this->menuEnabled = false; |
197
|
|
|
$this->console->disable(); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Disables the display of the top menu |
202
|
|
|
*/ |
203
|
4 |
|
public function disableWarnings(): void |
204
|
|
|
{ |
205
|
4 |
|
$this->warningsEnabled = false; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** @return mixed[] */ |
209
|
4 |
|
public function getDisplay(): array |
210
|
|
|
{ |
211
|
4 |
|
$baseDir = defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : ''; |
212
|
|
|
|
213
|
|
|
/** @var ThemeManager $themeManager */ |
214
|
4 |
|
$themeManager = ContainerBuilder::getContainer()->get(ThemeManager::class); |
215
|
4 |
|
$theme = $themeManager->theme; |
216
|
|
|
|
217
|
4 |
|
$version = self::getVersionParameter(); |
218
|
|
|
|
219
|
|
|
// The user preferences have been merged at this point |
220
|
|
|
// so we can conditionally add CodeMirror, other scripts and settings |
221
|
4 |
|
if ($this->config->settings['CodemirrorEnable']) { |
222
|
|
|
$this->scripts->addFile('vendor/codemirror/lib/codemirror.js'); |
223
|
|
|
$this->scripts->addFile('vendor/codemirror/mode/sql/sql.js'); |
224
|
|
|
$this->scripts->addFile('vendor/codemirror/addon/runmode/runmode.js'); |
225
|
|
|
$this->scripts->addFile('vendor/codemirror/addon/hint/show-hint.js'); |
226
|
|
|
$this->scripts->addFile('vendor/codemirror/addon/hint/sql-hint.js'); |
227
|
|
|
if ($this->config->settings['LintEnable']) { |
228
|
|
|
$this->scripts->addFile('vendor/codemirror/addon/lint/lint.js'); |
229
|
|
|
$this->scripts->addFile('codemirror/addon/lint/sql-lint.js'); |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
4 |
|
if ($this->config->settings['SendErrorReports'] !== 'never') { |
234
|
|
|
$this->scripts->addFile('vendor/tracekit.js'); |
235
|
|
|
$this->scripts->addFile('error_report.js'); |
236
|
|
|
} |
237
|
|
|
|
238
|
4 |
|
if ($this->config->settings['enable_drag_drop_import'] === true) { |
239
|
|
|
$this->scripts->addFile('drag_drop_import.js'); |
240
|
|
|
} |
241
|
|
|
|
242
|
4 |
|
if (! $this->config->get('DisableShortcutKeys')) { |
243
|
|
|
$this->scripts->addFile('shortcuts_handler.js'); |
244
|
|
|
} |
245
|
|
|
|
246
|
4 |
|
$this->scripts->addCode($this->getVariablesForJavaScript()); |
247
|
|
|
|
248
|
4 |
|
$this->scripts->addCode( |
249
|
4 |
|
'ConsoleEnterExecutes=' . ($this->config->settings['ConsoleEnterExecutes'] ? 'true' : 'false'), |
250
|
4 |
|
); |
251
|
4 |
|
$this->scripts->addFiles($this->console->getScripts()); |
252
|
|
|
|
253
|
4 |
|
$dbi = DatabaseInterface::getInstance(); |
|
|
|
|
254
|
4 |
|
if ($this->menuEnabled && Current::$server > 0) { |
255
|
|
|
$navigation = (new Navigation($this->template, new Relation($dbi), $dbi, $this->config))->getDisplay(); |
256
|
|
|
} |
257
|
|
|
|
258
|
4 |
|
$customHeader = Config::renderHeader(); |
259
|
|
|
|
260
|
|
|
// offer to load user preferences from localStorage |
261
|
|
|
if ( |
262
|
4 |
|
$this->config->get('user_preferences') === 'session' |
263
|
4 |
|
&& ! isset($_SESSION['userprefs_autoload']) |
264
|
|
|
) { |
265
|
|
|
$loadUserPreferences = $this->userPreferences->autoloadGetHeader(); |
266
|
|
|
} |
267
|
|
|
|
268
|
4 |
|
if ($this->menuEnabled && Current::$server > 0) { |
269
|
|
|
$menu = $this->menu->getDisplay(); |
270
|
|
|
} |
271
|
|
|
|
272
|
4 |
|
$console = $this->console->getDisplay(); |
273
|
4 |
|
$messages = $this->getMessage(); |
274
|
4 |
|
$isLoggedIn = $dbi->isConnected(); |
275
|
|
|
|
276
|
4 |
|
$this->scripts->addFile('datetimepicker.js'); |
277
|
4 |
|
$this->scripts->addFile('validator-messages.js'); |
278
|
|
|
|
279
|
4 |
|
return [ |
280
|
4 |
|
'lang' => $GLOBALS['lang'], |
281
|
4 |
|
'allow_third_party_framing' => $this->config->settings['AllowThirdPartyFraming'], |
282
|
4 |
|
'base_dir' => $baseDir, |
283
|
4 |
|
'theme_path' => $theme->getPath(), |
284
|
4 |
|
'version' => $version, |
285
|
4 |
|
'text_dir' => LanguageManager::$textDir, |
286
|
4 |
|
'server' => Current::$server, |
287
|
4 |
|
'title' => $this->getPageTitle(), |
288
|
4 |
|
'scripts' => $this->scripts->getDisplay(), |
289
|
4 |
|
'body_id' => $this->bodyId, |
290
|
4 |
|
'navigation' => $navigation ?? '', |
291
|
4 |
|
'custom_header' => $customHeader, |
292
|
4 |
|
'load_user_preferences' => $loadUserPreferences ?? '', |
293
|
4 |
|
'show_hint' => $this->config->settings['ShowHint'], |
294
|
4 |
|
'is_warnings_enabled' => $this->warningsEnabled, |
295
|
4 |
|
'is_menu_enabled' => $this->menuEnabled, |
296
|
4 |
|
'is_logged_in' => $isLoggedIn, |
297
|
4 |
|
'menu' => $menu ?? '', |
298
|
4 |
|
'console' => $console, |
299
|
4 |
|
'messages' => $messages, |
300
|
4 |
|
'theme_color_mode' => $theme->getColorMode(), |
301
|
4 |
|
'theme_color_modes' => $theme->getColorModes(), |
302
|
4 |
|
'theme_id' => $theme->getId(), |
303
|
4 |
|
'current_user' => $dbi->getCurrentUserAndHost(), |
304
|
4 |
|
'is_mariadb' => $dbi->isMariaDB(), |
305
|
4 |
|
]; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Returns the message to be displayed at the top of |
310
|
|
|
* the page, including the executed SQL query, if any. |
311
|
|
|
*/ |
312
|
8 |
|
public function getMessage(): string |
313
|
|
|
{ |
314
|
8 |
|
$retval = ''; |
315
|
8 |
|
$message = ''; |
316
|
8 |
|
if (! empty($GLOBALS['message'])) { |
317
|
4 |
|
$message = $GLOBALS['message']; |
318
|
4 |
|
unset($GLOBALS['message']); |
319
|
4 |
|
} elseif (! empty($_REQUEST['message'])) { |
320
|
|
|
$message = $_REQUEST['message']; |
321
|
|
|
} |
322
|
|
|
|
323
|
8 |
|
if ($message !== '') { |
324
|
4 |
|
if (isset($GLOBALS['buffer_message'])) { |
325
|
|
|
$bufferMessage = $GLOBALS['buffer_message']; |
326
|
|
|
} |
327
|
|
|
|
328
|
4 |
|
$retval .= Generator::getMessage($message); |
329
|
4 |
|
if (isset($bufferMessage)) { |
330
|
|
|
$GLOBALS['buffer_message'] = $bufferMessage; |
331
|
|
|
} |
332
|
|
|
} |
333
|
|
|
|
334
|
8 |
|
return $retval; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** @return array<string, string> */ |
338
|
12 |
|
public function getHttpHeaders(): array |
339
|
|
|
{ |
340
|
12 |
|
$headers = []; |
341
|
|
|
|
342
|
|
|
/* Prevent against ClickJacking by disabling framing */ |
343
|
12 |
|
if (strtolower((string) $this->config->settings['AllowThirdPartyFraming']) === 'sameorigin') { |
344
|
4 |
|
$headers['X-Frame-Options'] = 'SAMEORIGIN'; |
345
|
8 |
|
} elseif ($this->config->settings['AllowThirdPartyFraming'] !== true) { |
346
|
4 |
|
$headers['X-Frame-Options'] = 'DENY'; |
347
|
|
|
} |
348
|
|
|
|
349
|
12 |
|
$headers['Referrer-Policy'] = 'same-origin'; |
350
|
|
|
|
351
|
12 |
|
$headers = array_merge($headers, $this->getCspHeaders()); |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* Re-enable possible disabled XSS filters. |
355
|
|
|
* |
356
|
|
|
* @see https://developer.mozilla.org/docs/Web/HTTP/Headers/X-XSS-Protection |
357
|
|
|
*/ |
358
|
12 |
|
$headers['X-XSS-Protection'] = '1; mode=block'; |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* "nosniff", prevents Internet Explorer and Google Chrome from MIME-sniffing |
362
|
|
|
* a response away from the declared content-type. |
363
|
|
|
* |
364
|
|
|
* @see https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options |
365
|
|
|
*/ |
366
|
12 |
|
$headers['X-Content-Type-Options'] = 'nosniff'; |
367
|
|
|
|
368
|
|
|
/** |
369
|
|
|
* Adobe cross-domain-policies. |
370
|
|
|
* |
371
|
|
|
* @see https://www.sentrium.co.uk/labs/application-security-101-http-headers |
372
|
|
|
*/ |
373
|
12 |
|
$headers['X-Permitted-Cross-Domain-Policies'] = 'none'; |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* Robots meta tag. |
377
|
|
|
* |
378
|
|
|
* @see https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag |
379
|
|
|
*/ |
380
|
12 |
|
$headers['X-Robots-Tag'] = 'noindex, nofollow'; |
381
|
|
|
|
382
|
|
|
/** |
383
|
|
|
* The HTTP Permissions-Policy header provides a mechanism to allow and deny |
384
|
|
|
* the use of browser features in a document |
385
|
|
|
* or within any <iframe> elements in the document. |
386
|
|
|
* |
387
|
|
|
* @see https://developer.mozilla.org/docs/Web/HTTP/Headers/Permissions-Policy |
388
|
|
|
*/ |
389
|
12 |
|
$headers['Permissions-Policy'] = 'fullscreen=(self), oversized-images=(self), interest-cohort=()'; |
390
|
|
|
|
391
|
12 |
|
$headers = array_merge($headers, Core::getNoCacheHeaders()); |
392
|
|
|
|
393
|
|
|
/** |
394
|
|
|
* A different Content-Type is set in {@see \PhpMyAdmin\Controllers\Transformation\WrapperController}. |
395
|
|
|
*/ |
396
|
12 |
|
if (! $this->isTransformationWrapper) { |
397
|
|
|
// Define the charset to be used |
398
|
12 |
|
$headers['Content-Type'] = 'text/html; charset=utf-8'; |
399
|
|
|
} |
400
|
|
|
|
401
|
12 |
|
return $headers; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* If the page is missing the title, this function |
406
|
|
|
* will set it to something reasonable |
407
|
|
|
*/ |
408
|
4 |
|
public function getPageTitle(): string |
409
|
|
|
{ |
410
|
4 |
|
if ($this->title === '') { |
411
|
4 |
|
if (Current::$server > 0) { |
412
|
|
|
if (Current::$table !== '') { |
413
|
|
|
$tempTitle = $this->config->settings['TitleTable']; |
414
|
|
|
} elseif (Current::$database !== '') { |
415
|
|
|
$tempTitle = $this->config->settings['TitleDatabase']; |
416
|
|
|
} elseif ($this->config->selectedServer['host'] !== '') { |
417
|
|
|
$tempTitle = $this->config->settings['TitleServer']; |
418
|
|
|
} else { |
419
|
|
|
$tempTitle = $this->config->settings['TitleDefault']; |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
$this->title = htmlspecialchars( |
423
|
|
|
Util::expandUserString($tempTitle), |
424
|
|
|
); |
425
|
|
|
} else { |
426
|
4 |
|
$this->title = 'phpMyAdmin'; |
427
|
|
|
} |
428
|
|
|
} |
429
|
|
|
|
430
|
4 |
|
return $this->title; |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* Get all the CSP allow policy headers |
435
|
|
|
* |
436
|
|
|
* @return array<string, string> |
437
|
|
|
*/ |
438
|
12 |
|
private function getCspHeaders(): array |
439
|
|
|
{ |
440
|
12 |
|
$mapTileUrl = ' tile.openstreetmap.org'; |
441
|
12 |
|
$captchaUrl = ''; |
442
|
12 |
|
$cspAllow = $this->config->settings['CSPAllow']; |
443
|
|
|
|
444
|
|
|
if ( |
445
|
12 |
|
! empty($this->config->settings['CaptchaLoginPrivateKey']) |
446
|
12 |
|
&& ! empty($this->config->settings['CaptchaLoginPublicKey']) |
447
|
12 |
|
&& ! empty($this->config->settings['CaptchaApi']) |
448
|
12 |
|
&& ! empty($this->config->settings['CaptchaRequestParam']) |
449
|
12 |
|
&& ! empty($this->config->settings['CaptchaResponseParam']) |
450
|
|
|
) { |
451
|
8 |
|
$captchaUrl = ' ' . $this->config->settings['CaptchaCsp'] . ' '; |
452
|
|
|
} |
453
|
|
|
|
454
|
12 |
|
$headers = []; |
455
|
|
|
|
456
|
12 |
|
$headers['Content-Security-Policy'] = sprintf( |
457
|
12 |
|
'default-src \'self\' %s%s;script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' %s%s;' |
458
|
12 |
|
. 'style-src \'self\' \'unsafe-inline\' %s%s;img-src \'self\' data: %s%s%s;object-src \'none\';', |
459
|
12 |
|
$captchaUrl, |
460
|
12 |
|
$cspAllow, |
461
|
12 |
|
$captchaUrl, |
462
|
12 |
|
$cspAllow, |
463
|
12 |
|
$captchaUrl, |
464
|
12 |
|
$cspAllow, |
465
|
12 |
|
$cspAllow, |
466
|
12 |
|
$mapTileUrl, |
467
|
12 |
|
$captchaUrl, |
468
|
12 |
|
); |
469
|
|
|
|
470
|
12 |
|
$headers['X-Content-Security-Policy'] = sprintf( |
471
|
12 |
|
'default-src \'self\' %s%s;options inline-script eval-script;' |
472
|
12 |
|
. 'referrer no-referrer;img-src \'self\' data: %s%s%s;object-src \'none\';', |
473
|
12 |
|
$captchaUrl, |
474
|
12 |
|
$cspAllow, |
475
|
12 |
|
$cspAllow, |
476
|
12 |
|
$mapTileUrl, |
477
|
12 |
|
$captchaUrl, |
478
|
12 |
|
); |
479
|
|
|
|
480
|
12 |
|
$headers['X-WebKit-CSP'] = sprintf( |
481
|
12 |
|
'default-src \'self\' %s%s;script-src \'self\' %s%s \'unsafe-inline\' \'unsafe-eval\';' |
482
|
12 |
|
. 'referrer no-referrer;style-src \'self\' \'unsafe-inline\' %s;' |
483
|
12 |
|
. 'img-src \'self\' data: %s%s%s;object-src \'none\';', |
484
|
12 |
|
$captchaUrl, |
485
|
12 |
|
$cspAllow, |
486
|
12 |
|
$captchaUrl, |
487
|
12 |
|
$cspAllow, |
488
|
12 |
|
$captchaUrl, |
489
|
12 |
|
$cspAllow, |
490
|
12 |
|
$mapTileUrl, |
491
|
12 |
|
$captchaUrl, |
492
|
12 |
|
); |
493
|
|
|
|
494
|
12 |
|
return $headers; |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
/** |
498
|
|
|
* Returns the phpMyAdmin version to be appended to the url to avoid caching |
499
|
|
|
* between versions |
500
|
|
|
* |
501
|
|
|
* @return string urlencoded pma version as a parameter |
502
|
|
|
*/ |
503
|
4 |
|
public static function getVersionParameter(): string |
504
|
|
|
{ |
505
|
4 |
|
return 'v=' . urlencode(Version::VERSION); |
506
|
|
|
} |
507
|
|
|
|
508
|
4 |
|
private function getVariablesForJavaScript(): string |
509
|
|
|
{ |
510
|
4 |
|
$maxInputVars = ini_get('max_input_vars'); |
511
|
4 |
|
$maxInputVarsValue = $maxInputVars === false || $maxInputVars === '' ? 'false' : (int) $maxInputVars; |
512
|
|
|
|
513
|
4 |
|
return $this->template->render('javascript/variables', [ |
514
|
4 |
|
'first_day_of_calendar' => $this->config->settings['FirstDayOfCalendar'] ?? 0, |
515
|
4 |
|
'max_input_vars' => $maxInputVarsValue, |
516
|
4 |
|
]); |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
public function setIsTransformationWrapper(bool $isTransformationWrapper): void |
520
|
|
|
{ |
521
|
|
|
$this->isTransformationWrapper = $isTransformationWrapper; |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
public function getConsole(): Console |
525
|
|
|
{ |
526
|
|
|
return $this->console; |
527
|
|
|
} |
528
|
|
|
} |
529
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.