feat: only write config when a specific config update action occurs

This commit is contained in:
Eli Bosley
2025-01-19 19:07:21 -05:00
parent 27049d9d91
commit 29ca5829ff
6 changed files with 45 additions and 71 deletions

View File

@@ -2,20 +2,18 @@
version="3.11.0"
extraOrigins="https://google.com,https://test.com"
[local]
[notifier]
[remote]
wanaccess="yes"
wanport="8443"
upnpEnabled="no"
apikey="_______________________BIG_API_KEY_HERE_________________________"
apikey="unraid_SfxcHvPqI5MIUE51KHJCb5m21QbIZeowqN3XT4QFHLJm0NQ2ZHAqUuMKW"
localApiKey="_______________________LOCAL_API_KEY_HERE_________________________"
email="test@example.com"
username="zspearmint"
avatar="https://via.placeholder.com/200"
email="ekbosley@gmail.com"
username="Hi"
avatar=""
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
accesstoken=""
idtoken=""
refreshtoken=""
dynamicRemoteAccessType="DISABLED"
ssoSubIds=""
[upc]

View File

@@ -2,16 +2,15 @@
version="3.11.0"
extraOrigins="https://google.com,https://test.com"
[local]
[notifier]
[remote]
wanaccess="yes"
wanport="8443"
upnpEnabled="no"
apikey="_______________________BIG_API_KEY_HERE_________________________"
apikey="unraid_SfxcHvPqI5MIUE51KHJCb5m21QbIZeowqN3XT4QFHLJm0NQ2ZHAqUuMKW"
localApiKey="_______________________LOCAL_API_KEY_HERE_________________________"
email="test@example.com"
username="zspearmint"
avatar="https://via.placeholder.com/200"
email=""
username="Hi"
avatar=""
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
accesstoken=""
idtoken=""
@@ -19,7 +18,6 @@ refreshtoken=""
dynamicRemoteAccessType="DISABLED"
ssoSubIds=""
allowedOrigins="/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, http://localhost:8080, https://localhost:4443, https://tower.local:4443, https://192.168.1.150:4443, https://tower:4443, https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443, https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443, https://10-252-0-1.hash.myunraid.net:4443, https://10-252-1-1.hash.myunraid.net:4443, https://10-253-3-1.hash.myunraid.net:4443, https://10-253-4-1.hash.myunraid.net:4443, https://10-253-5-1.hash.myunraid.net:4443, https://10-100-0-1.hash.myunraid.net:4443, https://10-100-0-2.hash.myunraid.net:4443, https://10-123-1-2.hash.myunraid.net:4443, https://221-123-121-112.hash.myunraid.net:4443, https://google.com, https://test.com, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000, https://studio.apollographql.com"
[upc]
[connectionStatus]
minigraph="PRE_INIT"
minigraph="ERROR_RETRYING"
upnpStatus=""

View File

@@ -1,66 +1,22 @@
import { startAppListening } from '@app/store/listeners/listener-middleware';
import { isEqual } from 'lodash-es';
import { logger } from '@app/core/log';
import {
type ConfigType,
getWriteableConfig,
} from '@app/core/utils/files/config-file-normalizer';
import {
loadConfigFile,
loginUser,
logoutUser,
} from '@app/store/modules/config';
import { FileLoadStatus } from '@app/store/types';
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
import { isFulfilled } from '@reduxjs/toolkit';
import { environment } from '@app/environment';
import { writeFileSync } from 'fs';
const actionIsLoginOrLogout = isFulfilled(logoutUser, loginUser);
import type { ConfigType } from '@app/core/utils/files/config-file-normalizer';
import { logger } from '@app/core/log';
import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer';
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
import { startAppListening } from '@app/store/listeners/listener-middleware';
import { configUpdateActionsFlash, configUpdateActionsMemory } from '@app/store/modules/config';
export const enableConfigFileListener = (mode: ConfigType) => () =>
startAppListening({
predicate(action, currentState, previousState) {
if (!environment.IS_MAIN_PROCESS) {
return false;
}
if (currentState.config.status === FileLoadStatus.LOADED) {
const oldFlashConfig = previousState?.config.api.version
? getWriteableConfig(previousState.config, mode)
: null;
const newFlashConfig = getWriteableConfig(
currentState.config,
mode
);
if (
!isEqual(oldFlashConfig, newFlashConfig) &&
action.type !== loadConfigFile.fulfilled.type &&
action.type !== loadConfigFile.rejected.type
) {
return true;
}
if (actionIsLoginOrLogout(action) && mode === 'memory') {
logger.trace(
'Logout / Login Action Encountered, writing memory config'
);
return true;
}
}
return false;
},
matcher: mode === 'flash' ? configUpdateActionsFlash : configUpdateActionsMemory,
async effect(_, { getState }) {
const { paths, config } = getState();
const pathToWrite =
mode === 'flash'
? paths['myservers-config']
: paths['myservers-config-states'];
mode === 'flash' ? paths['myservers-config'] : paths['myservers-config-states'];
const writeableConfig = getWriteableConfig(config, mode);
const serializedConfig =
safelySerializeObjectToIni(writeableConfig);
const serializedConfig = safelySerializeObjectToIni(writeableConfig);
logger.debug('Writing updated config to %s', pathToWrite);
writeFileSync(pathToWrite, serializedConfig);
},

View File

@@ -4,7 +4,7 @@ import { writeFileSync } from 'fs';
import { access } from 'fs/promises';
import type { PayloadAction } from '@reduxjs/toolkit';
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { createAsyncThunk, createSlice, isAnyOf } from '@reduxjs/toolkit';
import { isEqual } from 'lodash-es';
import merge from 'lodash/merge';
@@ -24,6 +24,7 @@ import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access';
import { FileLoadStatus } from '@app/store/types';
import { type RecursivePartial } from '@app/types';
import { type MyServersConfig, type MyServersConfigMemory } from '@app/types/my-servers-config';
import { isFulfilled } from '@app/utils';
export type SliceState = {
status: FileLoadStatus;
@@ -291,4 +292,24 @@ export const {
setWanAccess,
} = actions;
/**
* Actions that should trigger a flash write
*/
export const configUpdateActionsFlash = isAnyOf(
updateUserConfig,
updateAccessTokens,
updateAllowedOrigins,
setUpnpState,
setWanPortToValue,
setWanAccess,
setupRemoteAccessThunk.fulfilled,
logoutUser.fulfilled,
loginUser.fulfilled
);
/**
* Actions that should trigger a memory write
*/
export const configUpdateActionsMemory = isAnyOf(configUpdateActionsFlash, setGraphqlConnectionStatus);
export const configReducer = reducer;

View File

@@ -22,7 +22,8 @@ export const setupConfigPathWatch = () => {
ignoreInitial: false,
usePolling: CHOKIDAR_USEPOLLING === true,
})
.on('change', async () => {
.on('change', async (change) => {
logger.trace('Config File Changed, Reloading Config %s', change);
await store.dispatch(loadConfigFile());
})
.on('unlink', async () => {

View File

@@ -35,14 +35,14 @@ export class ServerHeaderStrategy extends PassportStrategy(Strategy, 'server-htt
try {
const user = await this.authService.validateApiKeyCasbin(key);
this.logger.debug('API key validation successful', {
this.logger.debug('API key validation successful %o', {
userId: user?.id,
roles: user?.roles,
});
return user;
} catch (error) {
this.logger.error('API key validation failed', {
this.logger.error('API key validation failed %o', {
errorType: error instanceof Error ? error.constructor.name : 'Unknown',
message: error instanceof Error ? error.message : 'Unknown error',
});