mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
feat: only write config when a specific config update action occurs
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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=""
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user