Ver código fonte

Custom logo HTML (#4369)

* Custom logo HTML
Add option for custom HTML logo/title in the main Web UI view.
Can potentially be different per user.
#fix https://github.com/FreshRSS/FreshRSS/pull/3830/files#r850472247

* logo_html in main config
With new `./data/config.custom.php` to provide custom values before install

* Docker documentation

* whitespace

* Auto relax CSP to allow images for HTML logo

* Documentation
Alexandre Alapetite 3 anos atrás
pai
commit
f89819bd64

+ 14 - 0
Docker/README.md

@@ -205,6 +205,16 @@ In the FreshRSS setup, you will then specify the name of the container (`freshrs
 
 ## More deployment options
 
+### Provide default global settings
+
+An optional configuration file can be mounted to `/var/www/FreshRSS/data/config.custom.php` to provide custom settings before the FreshRSS setup,
+on the model of [`config.default.php`](../config.default.php).
+
+### Provide default user settings
+
+An optional configuration file can be mounted to `/var/www/FreshRSS/data/config-user.default.php` to provide custom user settings before a user is created,
+on the model of [`config-user.default.php`](../config-user.default.php).
+
 ### Custom Apache configuration (advanced users)
 
 The FreshRSS Docker image uses the [Web server Apache](https://httpd.apache.org/) internally.
@@ -294,6 +304,10 @@ services:
     volumes:
       - data:/var/www/FreshRSS/data
       - extensions:/var/www/FreshRSS/extensions
+      # Optional file providing custom global settings (used before a FreshRSS install)
+      - ./config.custom.php:/var/www/FreshRSS/data/config.custom.php
+      # Optional file providing custom user settings (used before a new user is created)
+      - ./config-user.custom.php:/var/www/FreshRSS/data/config-user.custom.php
     ports:
       # If you want to open a port 8080 on the local machine:
       - "8080:80"

+ 1 - 0
app/Controllers/statsController.php

@@ -17,6 +17,7 @@ class FreshRSS_stats_Controller extends FreshRSS_ActionController {
 
 		$this->_csp([
 			'default-src' => "'self'",
+			'img-src' => '* data:',
 			'style-src' => "'self' 'unsafe-inline'",
 		]);
 

+ 8 - 0
app/FreshRSS.php

@@ -32,6 +32,14 @@ class FreshRSS extends Minz_FrontController {
 			die($message);
 		}
 
+		if (FreshRSS_Context::$system_conf->logo_html != '') {
+			// Relax Content Security Policy to allow external images if a custom logo HTML is used
+			Minz_ActionController::_defaultCsp([
+				'default-src' => "'self'",
+				'img-src' => '* data:',
+			]);
+		}
+
 		// Load list of extensions and enable the "system" ones.
 		Minz_ExtensionManager::init();
 

+ 1 - 0
app/Models/SystemConfiguration.php

@@ -17,6 +17,7 @@
  * @property-read string $http_auth_auto_register_email_field
  * @property-read string $language
  * @property array<string,int> $limits
+ * @property-read string $logo_html
  * @property-read string $meta_description
  * @property-read bool $pubsubhubbub_enabled
  * @property-read string $salt

+ 8 - 0
app/install.php

@@ -145,6 +145,14 @@ function saveStep2() {
 			$config_array['auth_type'] = Minz_Session::param('auth_type');
 		}
 
+		$customConfigPath = DATA_PATH . '/config.custom.php';
+		if (file_exists($customConfigPath)) {
+			$customConfig = include($customConfigPath);
+			if (is_array($customConfig)) {
+				$config_array = array_merge($customConfig, $config_array);
+			}
+		}
+
 		@unlink(DATA_PATH . '/config.php');	//To avoid access-rights problems
 		file_put_contents(DATA_PATH . '/config.php', "<?php\n return " . var_export($config_array, true) . ";\n");
 

+ 7 - 1
app/layout/header.phtml

@@ -1,7 +1,13 @@
 <header class="header">
 	<div class="item title">
 		<a href="<?= _url('index', 'index') ?>">
-			<img class="logo" src="<?= _i('FreshRSS-logo', true) ?>" alt="" />
+			<?php if (FreshRSS_Context::$system_conf->logo_html == '') { ?>
+				<img class="logo" src="<?= _i('FreshRSS-logo', true) ?>" alt="FreshRSS" />
+			<?php
+				} else {
+					echo FreshRSS_Context::$system_conf->logo_html;
+				}
+			?>
 		</a>
 	</div>
 

+ 7 - 1
app/layout/simple.phtml

@@ -30,7 +30,13 @@
 	<div class="header">
 		<div class="item title">
 			<a href="<?= _url('index', 'index') ?>">
-				<img class="logo" src="<?= _i('FreshRSS-logo', true) ?>" alt="" />
+				<?php if (FreshRSS_Context::$system_conf->logo_html == '') { ?>
+					<img class="logo" src="<?= _i('FreshRSS-logo', true) ?>" alt="FreshRSS" />
+				<?php
+					} else {
+						echo FreshRSS_Context::$system_conf->logo_html;
+					}
+				?>
 			</a>
 		</div>
 

+ 6 - 0
cli/README.md

@@ -49,6 +49,8 @@ cd /usr/share/FreshRSS
 # Same parameters as for do-install.php. Used to update an existing installation.
 ```
 
+> ℹ️ More options for [the configuration of your instance](../config.default.php#L3-L5) may be set in `./data/config.custom.php` before the install process, or in `./data/config.php` after the install process.
+
 ### User
 
 ```sh
@@ -59,7 +61,11 @@ cd /usr/share/FreshRSS
 
 ./cli/update-user.php --user username [ ... ]
 # Same options as create-user.php, except --no_default_feeds which is only available for create-user.php
+```
 
+> ℹ️ More options for [the configuration of users](../config-user.default.php#L3-L5) may be set in `./data/config-user.custom.php` prior to creating new users, or in `./data/users/*/config.php` for existing users.
+
+```sh
 ./cli/actualize-user.php --user username
 # Fetch feeds for the specified user
 

+ 8 - 0
cli/do-install.php

@@ -46,6 +46,14 @@ $config = array(
 		'db' => FreshRSS_Context::$system_conf->db,
 	);
 
+$customConfigPath = DATA_PATH . '/config.custom.php';
+if (file_exists($customConfigPath)) {
+	$customConfig = include($customConfigPath);
+	if (is_array($customConfig)) {
+		$config = array_merge($customConfig, $config);
+	}
+}
+
 foreach ($params as $param) {
 	$param = rtrim($param, ':');
 	if (isset($options[$param])) {

+ 7 - 1
config.default.php

@@ -1,7 +1,8 @@
 <?php
 
 # Do not modify this file, which defines default values,
-# but edit `./data/config.php` instead, after the install process is completed.
+# but instead edit `./data/config.php` after the install process is completed,
+# or edit `./data/config.custom.php` before the install process.
 return array(
 
 	# Set to `development` to get additional error messages,
@@ -30,6 +31,11 @@ return array(
 	# Meta description used when `allow_robots` is true.
 	'meta_description' => '',
 
+	# Override logo of this FreshRSS instance in the Web user interface.
+	# It is rendered inside an <a>...</a> element and must be valid HTML or text.
+	# Example: '<img class="logo" src="https://example.net/Hello.png" alt="Logo Example" /> Hello'
+	'logo_html' => '',
+
 	# Name of the user that has administration rights.
 	'default_user' => '_',
 

+ 2 - 1
data/.gitignore

@@ -1,7 +1,8 @@
 .htpasswd
+config-user.custom.php
+config.custom.php
 config.php
 config.php.bak.php
-config-user.custom.php
 force-https.txt
 last_update.txt
 no-cache.txt

+ 4 - 1
docs/en/admins/03_Installation.md

@@ -16,7 +16,10 @@ Before you begin, make sure that you’ve read the [prerequisites](02_Prerequisi
 
 6. Using your supported web browser of choice, navigate to the address you’ve installed your server to complete the installation from the GUI.[^3]
 
-7. You can then customize [the configuration of your instance](https://github.com/FreshRSS/FreshRSS/blob/edge/config.default.php#L3-L4), [the default configuration for new users](https://github.com/FreshRSS/FreshRSS/blob/edge/config-user.default.php#L3-L5) or [the default set of feeds for new users](https://github.com/FreshRSS/FreshRSS/blob/edge/opml.default.xml#L2-L5).
+7. In configuration files, you can customize advanced settings:
+	* [the configuration of your instance](https://github.com/FreshRSS/FreshRSS/blob/edge/config.default.php#L3-L5) in `./data/config.custom.php` before the install process, or in `./data/config.php` after the install process;
+	* [the default configuration for new users](https://github.com/FreshRSS/FreshRSS/blob/edge/config-user.default.php#L3-L5) in `./data/config-user.custom.php`, or in `./data/users/*/config.php` for existing users;
+	* [the default set of feeds for new users](https://github.com/FreshRSS/FreshRSS/blob/edge/opml.default.xml#L2-L5) in `./data/opml.xml`.
 
 ---
 

+ 21 - 3
lib/Minz/ActionController.php

@@ -8,15 +8,22 @@
  * The Minz_ActionController class is a controller in the MVC paradigm
  */
 class Minz_ActionController {
-	protected $view;
-	private $csp_policies = array(
+
+	/** @var array<string,string> */
+	private static $csp_default = [
 		'default-src' => "'self'",
-	);
+	];
+
+	/** @var array<string,string> */
+	private $csp_policies;
+
+	protected $view;
 
 	// Gives the possibility to override the default View type.
 	public static $viewType = 'Minz_View';
 
 	public function __construct () {
+		$this->csp_policies = self::$csp_default;
 		if (class_exists(self::$viewType)) {
 			$this->view = new self::$viewType();
 		} else {
@@ -34,6 +41,17 @@ class Minz_ActionController {
 		return $this->view;
 	}
 
+	/**
+	 * Set default CSP policies.
+	 * @param array<string,string> $policies An array where keys are directives and values are sources.
+	 */
+	public static function _defaultCsp($policies) {
+		if (!isset($policies['default-src'])) {
+			Minz_Log::warning('Default CSP policy is not declared', ADMIN_LOG);
+		}
+		self::$csp_default = $policies;
+	}
+
 	/**
 	 * Set CSP policies.
 	 *