From a1b49f5fcfadf5a364a7421063d522685c76a4da Mon Sep 17 00:00:00 2001 From: Lars Kiesow <lkiesow@uos.de> Date: Sat, 21 Jan 2023 23:18:06 +0100 Subject: [PATCH 1/3] Reduce Fingerprinting As DieselTech#6997 pointed out in Matrix, it is a good idea to reduce fingerprinting by removing the `X-Powered-By` response header as pointed out by the Express security best practices: See http://expressjs.com/en/advanced/best-practice-security.html#reduce-fingerprinting --- server/Server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/Server.js b/server/Server.js index 3b9223da..de08318e 100644 --- a/server/Server.js +++ b/server/Server.js @@ -142,6 +142,7 @@ class Server { const app = express() const router = express.Router() app.use(global.RouterBasePath, router) + app.disable('x-powered-by') this.server = http.createServer(app) From 4f3029e5b2f13b69b5d1ea26bb257f4a9c510862 Mon Sep 17 00:00:00 2001 From: Tomazed <toma.zed@gmail.com> Date: Sun, 22 Jan 2023 00:39:23 +0100 Subject: [PATCH 2/3] Update fr.json Months and Days --- client/strings/fr.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/strings/fr.json b/client/strings/fr.json index a0f29fbc..f7ddd6ea 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -532,15 +532,15 @@ "MessageXLibraryIsEmpty": "La Bibliothèque {0} est vide!", "MessageYourAudiobookDurationIsLonger": "La durée de votre Livre Audio est plus longue que la durée trouvée", "MessageYourAudiobookDurationIsShorter": "La durée de votre Livre Audio est plus courte que la durée trouvée", - "MonthApr": "Apr", - "MonthAug": "Aug", - "MonthDec": "Dec", - "MonthFeb": "Feb", + "MonthApr": "Avr", + "MonthAug": "Aoû", + "MonthDec": "Déc", + "MonthFeb": "Fév", "MonthJan": "Jan", "MonthJul": "Jul", - "MonthJun": "Jun", + "MonthJun": "Jui", "MonthMar": "Mar", - "MonthMay": "May", + "MonthMay": "Mai", "MonthNov": "Nov", "MonthOct": "Oct", "MonthSep": "Sep", @@ -626,14 +626,14 @@ "ToastSocketFailedToConnect": "Échec de la connexion WebSocket", "ToastUserDeleteFailed": "Échec de la suppression de l'utilisateur", "ToastUserDeleteSuccess": "Utilisateur supprimé", - "WeekdayFri": "Fri", + "WeekdayFri": "Ven", "WeekdayFriday": "Vendredi", - "WeekdayMon": "Mon", + "WeekdayMon": "Lun", "WeekdayMonday": "Lundi", "WeekdaySaturday": "Samedi", "WeekdaySunday": "Dimanche", "WeekdayThursday": "Jeudi", "WeekdayTuesday": "Mardi", - "WeekdayWed": "Wed", + "WeekdayWed": "Mer", "WeekdayWednesday": "Mercredi" -} \ No newline at end of file +} From 274b0e48be527adb8ca75d9d8a133040bd0a0a76 Mon Sep 17 00:00:00 2001 From: Lars Kiesow <lkiesow@uos.de> Date: Sun, 22 Jan 2023 12:30:36 +0100 Subject: [PATCH 3/3] Skip AUDIOBOOKSHELF_UID/GID if undefined This patch slightly changes the behavior of the `AUDIOBOOKSHELF_UID` and `AUDIOBOOKSHELF_GID` options. Instead of defining a default user and group, trying to modify files and silently failing if the filesystem mode cannot be changed, this patch will just skip the entire process in the first place. If these options are defined, Audiobookshelf should behave exactly as before. If they are not defined, Audiobookshelf will now cause fewer file modifications (or less failures when trying to modify files). If this patch gets applied, it should probably be highlighted in the release notes. This usually shouldn't cause problems for migrations since the Docker guides explicitly configure the options and the package installations do not seem to use this at all, but there is still a change that it will and users should be aware of that. If a problem arises, users can easily fix the problem by either setting the permissions once manually to the audiobookshelf user or by simply defining the `AUDIOBOOKSHELF_UID/GID` options. --- index.js | 4 ++-- prod.js | 4 ++-- server/Server.js | 4 ++-- server/utils/filePerms.js | 10 +++++++++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 6105029b..585af22e 100644 --- a/index.js +++ b/index.js @@ -18,8 +18,8 @@ const PORT = process.env.PORT || 80 const HOST = process.env.HOST const CONFIG_PATH = process.env.CONFIG_PATH || '/config' const METADATA_PATH = process.env.METADATA_PATH || '/metadata' -const UID = process.env.AUDIOBOOKSHELF_UID || 99 -const GID = process.env.AUDIOBOOKSHELF_GID || 100 +const UID = process.env.AUDIOBOOKSHELF_UID +const GID = process.env.AUDIOBOOKSHELF_GID const SOURCE = process.env.SOURCE || 'docker' const ROUTER_BASE_PATH = process.env.ROUTER_BASE_PATH || '' diff --git a/prod.js b/prod.js index 57417033..de60b19d 100644 --- a/prod.js +++ b/prod.js @@ -23,8 +23,8 @@ const PORT = options.port || process.env.PORT || 3333 const HOST = options.host || process.env.HOST || "0.0.0.0" const CONFIG_PATH = inputConfig || process.env.CONFIG_PATH || Path.resolve('config') const METADATA_PATH = inputMetadata || process.env.METADATA_PATH || Path.resolve('metadata') -const UID = 99 -const GID = 100 +const UID = process.env.AUDIOBOOKSHELF_UID +const GID = process.env.AUDIOBOOKSHELF_GID const SOURCE = options.source || 'debian' const ROUTER_BASE_PATH = process.env.ROUTER_BASE_PATH || '' diff --git a/server/Server.js b/server/Server.js index 3b9223da..7a0a016e 100644 --- a/server/Server.js +++ b/server/Server.js @@ -43,8 +43,8 @@ class Server { this.Host = HOST global.Source = SOURCE global.isWin = process.platform === 'win32' - global.Uid = isNaN(UID) ? 0 : Number(UID) - global.Gid = isNaN(GID) ? 0 : Number(GID) + global.Uid = isNaN(UID) ? undefined : Number(UID) + global.Gid = isNaN(GID) ? undefined : Number(GID) global.ConfigPath = fileUtils.filePathToPOSIX(Path.normalize(CONFIG_PATH)) global.MetadataPath = fileUtils.filePathToPOSIX(Path.normalize(METADATA_PATH)) global.RouterBasePath = ROUTER_BASE_PATH diff --git a/server/utils/filePerms.js b/server/utils/filePerms.js index d875703e..c48b4261 100644 --- a/server/utils/filePerms.js +++ b/server/utils/filePerms.js @@ -91,7 +91,11 @@ module.exports.setDefault = (path, silent = false) => { const uid = global.Uid const gid = global.Gid return new Promise((resolve) => { - if (!silent) Logger.debug(`[FilePerms] Setting permission "${mode}" for uid ${uid} and gid ${gid} | "${path}"`) + if (isNaN(uid) || isNaN(gid)) { + if (!silent) Logger.debug('Not modifying permissions since no uid/gid is specified') + return resolve() + } + if (!silent) Logger.debug(`Setting permission "${mode}" for uid ${uid} and gid ${gid} | "${path}"`) chmodr(path, mode, uid, gid, resolve) }) } @@ -102,6 +106,10 @@ module.exports.setDefaultDirSync = (path, silent = false) => { const mode = 0o744 const uid = global.Uid const gid = global.Gid + if (isNaN(uid) || isNaN(gid)) { + if (!silent) Logger.debug('Not modifying permissions since no uid/gid is specified') + return true + } if (!silent) Logger.debug(`[FilePerms] Setting dir permission "${mode}" for uid ${uid} and gid ${gid} | "${path}"`) try { fs.chmodSync(path, mode)