' . __('Safe mode') . '
' . '' . __('You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities') . '
' . 'blog && $core->auth->check($permissions, $core->blog->id)) { return; } // Check if dashboard is not the current page et if it is granted for the user if (!$home && $core->blog && $core->auth->check('usage,contentadmin', $core->blog->id)) { // Go back to the dashboard http::redirect(DC_ADMIN_URL); } if (session_id()) { $core->session->destroy(); } http::redirect(DC_AUTH_PAGE); } # Check super admin public static function checkSuper($home = false) { $core = self::getCore(); if (!$core->auth->isSuperAdmin()) { // Check if dashboard is not the current page et if it is granted for the user if (!$home && $core->blog && $core->auth->check('usage,contentadmin', $core->blog->id)) { // Go back to the dashboard http::redirect(DC_ADMIN_URL); } if (session_id()) { $core->session->destroy(); } http::redirect(DC_AUTH_PAGE); } } # Top of admin page public static function open($title = '', $head = '', $breadcrumb = '', $options = []) { $core = self::getCore(); $js = []; # List of user's blogs if ($core->auth->getBlogCount() == 1 || $core->auth->getBlogCount() > 20) { $blog_box = '
' . __('Blog:') . ' ' . html::escapeHTML($core->blog->name) . ''; if ($core->auth->getBlogCount() > 20) { $blog_box .= ' - ' . __('Change blog') . ''; } $blog_box .= '
'; } else { $rs_blogs = $core->getBlogs(['order' => 'LOWER(blog_name)', 'limit' => 20]); $blogs = []; while ($rs_blogs->fetch()) { $blogs[html::escapeHTML($rs_blogs->blog_name . ' - ' . $rs_blogs->blog_url)] = $rs_blogs->blog_id; } $blog_box = '' . $core->formNonce() . form::combo('switchblog', $blogs, $core->blog->id) . form::hidden(['redir'], $_SERVER['REQUEST_URI']) . '
'; } $safe_mode = isset($_SESSION['sess_safe_mode']) && $_SESSION['sess_safe_mode']; # Display $headers = new ArrayObject([]); # Content-Type $headers['content-type'] = 'Content-Type: text/html; charset=UTF-8'; # Referrer Policy for admin pages $headers['referrer'] = 'Referrer-Policy: strict-origin'; # Prevents Clickjacking as far as possible if (isset($options['x-frame-allow'])) { self::setXFrameOptions($headers, $options['x-frame-allow']); } else { self::setXFrameOptions($headers); } # Content-Security-Policy (only if safe mode if not active, it may help) if (!$safe_mode && $core->blog->settings->system->csp_admin_on) { // Get directives from settings if exist, else set defaults $csp = new ArrayObject([]); // SQlite Clearbricks driver does not allow using single quote at beginning or end of a field value // so we have to use neutral values (localhost and 127.0.0.1) for some CSP directives $csp_prefix = $core->con->syntax() == 'sqlite' ? 'localhost ' : ''; // Hack for SQlite Clearbricks syntax $csp_suffix = $core->con->syntax() == 'sqlite' ? ' 127.0.0.1' : ''; // Hack for SQlite Clearbricks syntax $csp['default-src'] = $core->blog->settings->system->csp_admin_default ?: $csp_prefix . "'self'" . $csp_suffix; $csp['script-src'] = $core->blog->settings->system->csp_admin_script ?: $csp_prefix . "'self' 'unsafe-eval'" . $csp_suffix; $csp['style-src'] = $core->blog->settings->system->csp_admin_style ?: $csp_prefix . "'self' 'unsafe-inline'" . $csp_suffix; $csp['img-src'] = $core->blog->settings->system->csp_admin_img ?: $csp_prefix . "'self' data: http://media.dotaddict.org blob:"; # Cope with blog post preview (via public URL in iframe) if (!is_null($core->blog->host)) { $csp['default-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); $csp['script-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); $csp['style-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); } # Cope with media display in media manager (via public URL) if (!is_null($core->media)) { $csp['img-src'] .= ' ' . parse_url($core->media->root_url, PHP_URL_HOST); } elseif (!is_null($core->blog->host)) { // Let's try with the blog URL $csp['img-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); } # Allow everything in iframe (used by editors to preview public content) $csp['child-src'] = "*"; # --BEHAVIOR-- adminPageHTTPHeaderCSP $core->callBehavior('adminPageHTTPHeaderCSP', $csp); // Construct CSP header $directives = []; foreach ($csp as $key => $value) { if ($value) { $directives[] = $key . ' ' . $value; } } if (count($directives)) { if (version_compare(phpversion(), '5.4', '>=')) { // csp_report.php needs PHP ≥ 5.4 $directives[] = "report-uri " . DC_ADMIN_URL . "csp_report.php"; } $report_only = ($core->blog->settings->system->csp_admin_report_only) ? '-Report-Only' : ''; $headers['csp'] = "Content-Security-Policy" . $report_only . ": " . implode(" ; ", $directives); } } # --BEHAVIOR-- adminPageHTTPHeaders $core->callBehavior('adminPageHTTPHeaders', $headers); foreach ($headers as $key => $value) { header($value); } echo '' . '' . "\n" . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . '' . __('You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities') . '
' . 'memory usage: ' . memory_get_usage() . ' (' . files::size(memory_get_usage()) . ')
'; if (function_exists('xdebug_get_profiler_filename')) { $res .= 'Elapsed time: ' . xdebug_time_index() . ' seconds
'; $prof_file = xdebug_get_profiler_filename(); if ($prof_file) { $res .= 'Profiler file : ' . xdebug_get_profiler_filename() . '
'; } else { $prof_url = http::getSelfURI(); $prof_url .= (strpos($prof_url, '?') === false) ? '?' : '&'; $prof_url .= 'XDEBUG_PROFILE'; $res .= ''; } /* xdebug configuration: zend_extension = /.../xdebug.so xdebug.auto_trace = On xdebug.trace_format = 0 xdebug.trace_options = 1 xdebug.show_mem_delta = On xdebug.profiler_enable = 0 xdebug.profiler_enable_trigger = 1 xdebug.profiler_output_dir = /tmp xdebug.profiler_append = 0 xdebug.profiler_output_name = timestamp */ } $res .= 'Global vars: ' . $global_vars . '
' . '' . sprintf(__('See also %s'), sprintf('%s', __('the global help'))) . '.
' . '