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)