feat: show alert/prompt when settings changes require restart (#2401)

* fix: correct 'StatusChecker' typo

* feat: add restart required check to StatusChecker

* fix(perms): remove MANAGE_SETTINGS permission

* fix: allow alert to be dismissed

* fix(lang): add missing string in SettingsServices

* fix(frontend): fix modal icon border

* fix(frontend): un-dismiss alert if setting reverted not require server restart

* fix(backend): restart flag only needs to track main settings

* fix: rebase issue

* refactor: appease Prettier

* refactor: swap settings badge order

* fix: type import for MainSettings

* test: add cypress test for restart prompt
This commit is contained in:
TheCatLady
2022-08-16 09:58:11 -07:00
committed by GitHub
parent 70dc4c4b3b
commit f3e56da3b7
40 changed files with 239 additions and 140 deletions

View File

@@ -31,6 +31,7 @@ import { getSettings } from './lib/settings';
import logger from './logger';
import routes from './routes';
import { getAppVersion } from './utils/appVersion';
import restartFlag from './utils/restartFlag';
const API_SPEC_PATH = path.join(__dirname, '../overseerr-api.yml');
@@ -53,6 +54,7 @@ app
// Load Settings
const settings = getSettings().load();
restartFlag.initializeSettings(settings.main);
// Migrate library types
if (

View File

@@ -56,4 +56,5 @@ export interface StatusResponse {
commitTag: string;
updateAvailable: boolean;
commitsBehind: number;
restartRequired: boolean;
}

View File

@@ -1,7 +1,6 @@
export enum Permission {
NONE = 0,
ADMIN = 2,
MANAGE_SETTINGS = 4,
MANAGE_USERS = 8,
MANAGE_REQUESTS = 16,
REQUEST = 32,

View File

@@ -14,6 +14,7 @@ import { mapProductionCompany } from '../models/Movie';
import { mapNetwork } from '../models/Tv';
import { appDataPath, appDataStatus } from '../utils/appDataVolume';
import { getAppVersion, getCommitTag } from '../utils/appVersion';
import restartFlag from '../utils/restartFlag';
import { isPerson } from '../utils/typeHelpers';
import authRoutes from './auth';
import collectionRoutes from './collection';
@@ -78,6 +79,7 @@ router.get<unknown, StatusResponse>('/status', async (req, res) => {
commitTag: getCommitTag(),
updateAvailable,
commitsBehind,
restartRequired: restartFlag.isSet(),
});
});
@@ -100,11 +102,7 @@ router.get('/settings/public', async (req, res) => {
return res.status(200).json(settings.fullPublicSettings);
}
});
router.use(
'/settings',
isAuthenticated(Permission.MANAGE_SETTINGS),
settingsRoutes
);
router.use('/settings', isAuthenticated(Permission.ADMIN), settingsRoutes);
router.use('/search', isAuthenticated(), searchRoutes);
router.use('/discover', isAuthenticated(), discoverRoutes);
router.use('/request', isAuthenticated(), requestRoutes);

View File

@@ -258,12 +258,7 @@ export const canMakePermissionsChange = (
user?: User
): boolean =>
// Only let the owner grant admin privileges
!(hasPermission(Permission.ADMIN, permissions) && user?.id !== 1) ||
// Only let users with the manage settings permission, grant the same permission
!(
hasPermission(Permission.MANAGE_SETTINGS, permissions) &&
!hasPermission(Permission.MANAGE_SETTINGS, user?.permissions ?? 0)
);
!(hasPermission(Permission.ADMIN, permissions) && user?.id !== 1);
router.put<
Record<string, never>,

View File

@@ -0,0 +1,23 @@
import type { MainSettings } from '../lib/settings';
import { getSettings } from '../lib/settings';
class RestartFlag {
private settings: MainSettings;
public initializeSettings(settings: MainSettings): void {
this.settings = { ...settings };
}
public isSet(): boolean {
const settings = getSettings().main;
return (
this.settings.csrfProtection !== settings.csrfProtection ||
this.settings.trustProxy !== settings.trustProxy
);
}
}
const restartFlag = new RestartFlag();
export default restartFlag;