()
| 1170 | |
| 1171 | |
| 1172 | export const reloadSettings = () => { |
| 1173 | const settingsParsed = parseSettings(settings?.settingsFilename, true); |
| 1174 | const credentials = parseSettings(settings.credentialsFilename, false); |
| 1175 | storeSettings(settingsParsed); |
| 1176 | storeSettings(credentials); |
| 1177 | |
| 1178 | // Emit a clear migration warning when the deprecated abiword setting is detected. |
| 1179 | if (settingsParsed && (settingsParsed as any).abiword != null) { |
| 1180 | logger.warn( |
| 1181 | 'The "abiword" setting is no longer supported and has been ignored. ' + |
| 1182 | 'Abiword import/export support has been removed. ' + |
| 1183 | 'Please install LibreOffice and set "soffice" to its executable path instead.' |
| 1184 | ); |
| 1185 | } |
| 1186 | |
| 1187 | // Deprecation shim: if the operator set the legacy boolean `disableIPlogging` |
| 1188 | // without also setting the new tri-state `ipLogging`, map the boolean over |
| 1189 | // once and emit a WARN. An explicitly-set `ipLogging` always wins. |
| 1190 | if (settingsParsed != null && 'disableIPlogging' in (settingsParsed as any) && |
| 1191 | !('ipLogging' in (settingsParsed as any))) { |
| 1192 | logger.warn( |
| 1193 | '`disableIPlogging` is deprecated; use `ipLogging: "anonymous"` ' + |
| 1194 | '(or "truncated" / "full") instead.'); |
| 1195 | settings.ipLogging = (settingsParsed as any).disableIPlogging ? 'anonymous' : 'full'; |
| 1196 | } |
| 1197 | |
| 1198 | // Validate `ipLogging`. anonymizeIp() would otherwise silently treat an |
| 1199 | // unknown value as "truncated" and ship partially-redacted IPs. |
| 1200 | const validIpLogging = ['full', 'truncated', 'anonymous']; |
| 1201 | if (!validIpLogging.includes(settings.ipLogging as any)) { |
| 1202 | logger.warn( |
| 1203 | `ipLogging="${settings.ipLogging}" is not one of ` + |
| 1204 | `${validIpLogging.join(', ')}; falling back to "anonymous".`); |
| 1205 | settings.ipLogging = 'anonymous'; |
| 1206 | } |
| 1207 | |
| 1208 | // Validate `privacyBanner.dismissal`. The client treats every value other |
| 1209 | // than the exact strings 'dismissible' and 'sticky' as "no special |
| 1210 | // handling", which silently degrades a misconfigured 'sticky' to a |
| 1211 | // dismissible-shaped notice (and vice versa). Coerce to the safer default |
| 1212 | // and warn so the operator sees the typo. |
| 1213 | const validDismissal = ['dismissible', 'sticky']; |
| 1214 | if (settings.privacyBanner != null |
| 1215 | && !validDismissal.includes(settings.privacyBanner.dismissal as any)) { |
| 1216 | logger.warn( |
| 1217 | `privacyBanner.dismissal="${settings.privacyBanner.dismissal}" is ` + |
| 1218 | `not one of ${validDismissal.join(', ')}; falling back to ` + |
| 1219 | `"dismissible".`); |
| 1220 | settings.privacyBanner.dismissal = 'dismissible'; |
| 1221 | } |
| 1222 | |
| 1223 | // Settings.json files generated before December 2021 used `false` as the |
| 1224 | // default for these string options. The client treats the boolean `false` |
| 1225 | // as a sentinel meaning "no enforced value", but the dispatch in |
| 1226 | // pad.ts:getParams() coerces the boolean to the string "false" before |
| 1227 | // applying it, which then propagates as the user's name and color and |
| 1228 | // triggers `malformed color: false` on the server (#7686). Normalize |
| 1229 | // legacy booleans to null at the boundary so downstream code sees the |
no test coverage detected