mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
feat: cleanup config entries
This commit is contained in:
@@ -3,7 +3,6 @@ version="3.11.0"
|
||||
extraOrigins="https://google.com,https://test.com"
|
||||
[local]
|
||||
[notifier]
|
||||
apikey="unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5"
|
||||
[remote]
|
||||
wanaccess="yes"
|
||||
wanport="8443"
|
||||
@@ -14,9 +13,9 @@ email="test@example.com"
|
||||
username="zspearmint"
|
||||
avatar="https://via.placeholder.com/200"
|
||||
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
|
||||
idtoken=""
|
||||
accesstoken=""
|
||||
idtoken=""
|
||||
refreshtoken=""
|
||||
dynamicRemoteAccessType="DISABLED"
|
||||
ssoSubIds=""
|
||||
[upc]
|
||||
apikey="unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810"
|
||||
|
||||
@@ -3,7 +3,6 @@ version="3.11.0"
|
||||
extraOrigins="https://google.com,https://test.com"
|
||||
[local]
|
||||
[notifier]
|
||||
apikey="unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5"
|
||||
[remote]
|
||||
wanaccess="yes"
|
||||
wanport="8443"
|
||||
@@ -14,12 +13,13 @@ email="test@example.com"
|
||||
username="zspearmint"
|
||||
avatar="https://via.placeholder.com/200"
|
||||
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
|
||||
idtoken=""
|
||||
accesstoken=""
|
||||
idtoken=""
|
||||
refreshtoken=""
|
||||
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"
|
||||
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]
|
||||
apikey="unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810"
|
||||
[connectionStatus]
|
||||
minigraph="PRE_INIT"
|
||||
upnpStatus=""
|
||||
|
||||
@@ -42,23 +42,3 @@ export const getWriteableConfig = <T extends ConfigType>(
|
||||
|
||||
return schema.parse(mergedConfig) as any; // Narrowing ensures correct typing
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if two configurations are equivalent by normalizing them through the Zod schema.
|
||||
*/
|
||||
export const areConfigsEquivalent = (
|
||||
newConfigFile: Partial<MyServersConfigMemory>, // Use Partial here for flexibility
|
||||
currentConfig: MyServersConfig
|
||||
): boolean => {
|
||||
// Parse and validate the new config file using the schema (with default values applied)
|
||||
const normalizedNewConfig = MyServersConfigSchema.parse({
|
||||
...currentConfig, // Use currentConfig as a baseline to fill missing fields
|
||||
...newConfigFile,
|
||||
});
|
||||
|
||||
// Get the writeable configuration for the current config
|
||||
const normalizedCurrentConfig = getWriteableConfig(currentConfig, 'flash');
|
||||
|
||||
// Compare the normalized configurations
|
||||
return isEqual(normalizedNewConfig, normalizedCurrentConfig);
|
||||
};
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
import { parseConfig } from '@app/core/utils/misc/parse-config';
|
||||
import {
|
||||
type MyServersConfig,
|
||||
type MyServersConfigMemory,
|
||||
} from '@app/types/my-servers-config';
|
||||
import {
|
||||
createAsyncThunk,
|
||||
createSlice,
|
||||
type PayloadAction,
|
||||
} from '@reduxjs/toolkit';
|
||||
import { access } from 'fs/promises';
|
||||
import merge from 'lodash/merge';
|
||||
import { FileLoadStatus } from '@app/store/types';
|
||||
import { F_OK } from 'constants';
|
||||
import { type RecursivePartial } from '@app/types';
|
||||
import { DynamicRemoteAccessType, MinigraphStatus, type Owner } from '@app/graphql/generated/api/types';
|
||||
import { type RootState } from '@app/store';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { logger } from '@app/core/log';
|
||||
import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status';
|
||||
import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer';
|
||||
import { writeFileSync } from 'fs';
|
||||
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
|
||||
import { PUBSUB_CHANNEL, pubsub } from '@app/core/pubsub';
|
||||
import { access } from 'fs/promises';
|
||||
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access';
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
import type { Owner } from '@app/graphql/generated/api/types';
|
||||
import { logger } from '@app/core/log';
|
||||
import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub';
|
||||
import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer';
|
||||
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
|
||||
import { parseConfig } from '@app/core/utils/misc/parse-config';
|
||||
import { NODE_ENV } from '@app/environment';
|
||||
import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types';
|
||||
import { GraphQLClient } from '@app/mothership/graphql-client';
|
||||
import { stopPingTimeoutJobs } from '@app/mothership/jobs/ping-timeout-jobs';
|
||||
import { type RootState } from '@app/store';
|
||||
import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status';
|
||||
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';
|
||||
|
||||
export type SliceState = {
|
||||
status: FileLoadStatus;
|
||||
@@ -51,7 +48,7 @@ export const initialState: SliceState = {
|
||||
refreshtoken: '',
|
||||
allowedOrigins: '',
|
||||
dynamicRemoteAccessType: DynamicRemoteAccessType.DISABLED,
|
||||
ssoSubIds: ''
|
||||
ssoSubIds: '',
|
||||
},
|
||||
local: {},
|
||||
api: {
|
||||
@@ -71,8 +68,8 @@ export const initialState: SliceState = {
|
||||
} as const;
|
||||
|
||||
export const loginUser = createAsyncThunk<
|
||||
Pick<MyServersConfig['remote'], 'email' | 'avatar' | 'username' | 'apikey'| 'localApiKey'>,
|
||||
Pick<MyServersConfig['remote'], 'email' | 'avatar' | 'username' | 'apikey'| 'localApiKey'>,
|
||||
Pick<MyServersConfig['remote'], 'email' | 'avatar' | 'username' | 'apikey' | 'localApiKey'>,
|
||||
Pick<MyServersConfig['remote'], 'email' | 'avatar' | 'username' | 'apikey' | 'localApiKey'>,
|
||||
{ state: RootState }
|
||||
>('config/login-user', async (userInfo) => {
|
||||
logger.info('Logging in user: %s', userInfo.username);
|
||||
@@ -84,29 +81,28 @@ export const loginUser = createAsyncThunk<
|
||||
return userInfo;
|
||||
});
|
||||
|
||||
export const logoutUser = createAsyncThunk<
|
||||
void,
|
||||
{ reason?: string },
|
||||
{ state: RootState }
|
||||
>('config/logout-user', async ({ reason }) => {
|
||||
logger.info('Logging out user: %s', reason ?? 'No reason provided');
|
||||
const { pubsub } = await import('@app/core/pubsub');
|
||||
export const logoutUser = createAsyncThunk<void, { reason?: string }, { state: RootState }>(
|
||||
'config/logout-user',
|
||||
async ({ reason }) => {
|
||||
logger.info('Logging out user: %s', reason ?? 'No reason provided');
|
||||
const { pubsub } = await import('@app/core/pubsub');
|
||||
|
||||
// Publish to servers endpoint
|
||||
await pubsub.publish(PUBSUB_CHANNEL.SERVERS, {
|
||||
servers: [],
|
||||
});
|
||||
// Publish to servers endpoint
|
||||
await pubsub.publish(PUBSUB_CHANNEL.SERVERS, {
|
||||
servers: [],
|
||||
});
|
||||
|
||||
const owner: Owner = {
|
||||
username: 'root',
|
||||
url: '',
|
||||
avatar: '',
|
||||
};
|
||||
// Publish to owner endpoint
|
||||
await pubsub.publish(PUBSUB_CHANNEL.OWNER, { owner });
|
||||
stopPingTimeoutJobs();
|
||||
await GraphQLClient.clearInstance();
|
||||
});
|
||||
const owner: Owner = {
|
||||
username: 'root',
|
||||
url: '',
|
||||
avatar: '',
|
||||
};
|
||||
// Publish to owner endpoint
|
||||
await pubsub.publish(PUBSUB_CHANNEL.OWNER, { owner });
|
||||
stopPingTimeoutJobs();
|
||||
await GraphQLClient.clearInstance();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Load the myservers.cfg into the store. Returns null if the state after loading doesn't change
|
||||
@@ -128,32 +124,6 @@ type LoadFailureConfigEqual = {
|
||||
};
|
||||
type ConfigRejectedValues = LoadFailureConfigEqual | LoadFailureWithConfig;
|
||||
|
||||
const generateApiKeysIfNotExistent = (
|
||||
file: RecursivePartial<MyServersConfig>
|
||||
): MyServersConfig => {
|
||||
const newConfigFile = merge(file, {
|
||||
upc: {
|
||||
apikey:
|
||||
file.upc?.apikey?.trim()?.length === 64
|
||||
? file.upc?.apikey
|
||||
: `unupc_${randomBytes(58).toString('hex')}`.substring(
|
||||
0,
|
||||
64
|
||||
),
|
||||
},
|
||||
notifier: {
|
||||
apikey:
|
||||
file.notifier?.apikey?.trim().length === 64
|
||||
? file.notifier?.apikey
|
||||
: `unnotify_${randomBytes(58).toString('hex')}`.substring(
|
||||
0,
|
||||
64
|
||||
),
|
||||
},
|
||||
}) as MyServersConfig;
|
||||
return newConfigFile;
|
||||
};
|
||||
|
||||
export const loadConfigFile = createAsyncThunk<
|
||||
MyServersConfig,
|
||||
string | undefined,
|
||||
@@ -161,71 +131,51 @@ export const loadConfigFile = createAsyncThunk<
|
||||
state: RootState;
|
||||
rejectValue: ConfigRejectedValues;
|
||||
}
|
||||
>(
|
||||
'config/load-config-file',
|
||||
async (filePath, { getState, rejectWithValue }) => {
|
||||
try {
|
||||
const { paths, config } = getState();
|
||||
>('config/load-config-file', async (filePath, { getState, rejectWithValue }) => {
|
||||
try {
|
||||
const { paths, config } = getState();
|
||||
|
||||
const path = filePath ?? paths['myservers-config'];
|
||||
const path = filePath ?? paths['myservers-config'];
|
||||
|
||||
const fileExists = await access(path, F_OK)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
if (!fileExists) {
|
||||
throw new Error('Config File Missing');
|
||||
}
|
||||
const fileExists = await access(path, F_OK)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
if (!fileExists) {
|
||||
throw new Error('Config File Missing');
|
||||
}
|
||||
|
||||
const file = fileExists
|
||||
? parseConfig<RecursivePartial<MyServersConfig>>({
|
||||
filePath: path,
|
||||
type: 'ini',
|
||||
})
|
||||
: {};
|
||||
const newConfigFile = getWriteableConfig(
|
||||
parseConfig<MyServersConfig>({ filePath: path, type: 'ini' }),
|
||||
'flash'
|
||||
);
|
||||
|
||||
const newConfigFile = generateApiKeysIfNotExistent(file);
|
||||
|
||||
const isNewlyLoadedConfigEqual = isEqual(
|
||||
getWriteableConfig(newConfigFile as SliceState, 'flash'),
|
||||
getWriteableConfig(config, 'flash')
|
||||
);
|
||||
if (isNewlyLoadedConfigEqual) {
|
||||
logger.warn(
|
||||
'Not loading config because it is the same as before'
|
||||
);
|
||||
return rejectWithValue({
|
||||
type: CONFIG_LOAD_ERROR.CONFIG_EQUAL,
|
||||
});
|
||||
}
|
||||
return newConfigFile;
|
||||
} catch (error: unknown) {
|
||||
logger.warn('Config file is corrupted with error: %o - recreating config', error);
|
||||
const config = getWriteableConfig(initialState, 'flash');
|
||||
const newConfig = generateApiKeysIfNotExistent(config);
|
||||
newConfig.remote.wanaccess = 'no';
|
||||
const serializedConfig = safelySerializeObjectToIni(newConfig);
|
||||
writeFileSync(
|
||||
getState().paths['myservers-config'],
|
||||
serializedConfig
|
||||
);
|
||||
const isNewlyLoadedConfigEqual = isEqual(newConfigFile, getWriteableConfig(config, 'flash'));
|
||||
if (isNewlyLoadedConfigEqual) {
|
||||
logger.warn('Not loading config because it is the same as before');
|
||||
return rejectWithValue({
|
||||
type: CONFIG_LOAD_ERROR.CONFIG_CORRUPTED,
|
||||
error:
|
||||
error instanceof Error ? error : new Error('Unknown Error'),
|
||||
config: newConfig,
|
||||
type: CONFIG_LOAD_ERROR.CONFIG_EQUAL,
|
||||
});
|
||||
}
|
||||
return newConfigFile;
|
||||
} catch (error: unknown) {
|
||||
logger.warn('Config file is corrupted with error: %o - recreating config', error);
|
||||
const newConfig = getWriteableConfig(initialState, 'flash');
|
||||
newConfig.remote.wanaccess = 'no';
|
||||
const serializedConfig = safelySerializeObjectToIni(newConfig);
|
||||
writeFileSync(getState().paths['myservers-config'], serializedConfig);
|
||||
return rejectWithValue({
|
||||
type: CONFIG_LOAD_ERROR.CONFIG_CORRUPTED,
|
||||
error: error instanceof Error ? error : new Error('Unknown Error'),
|
||||
config: newConfig,
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
export const config = createSlice({
|
||||
name: 'config',
|
||||
initialState,
|
||||
reducers: {
|
||||
updateUserConfig(
|
||||
state,
|
||||
action: PayloadAction<RecursivePartial<MyServersConfig>>
|
||||
) {
|
||||
updateUserConfig(state, action: PayloadAction<RecursivePartial<MyServersConfig>>) {
|
||||
return merge(state, action.payload);
|
||||
},
|
||||
updateAccessTokens(
|
||||
@@ -287,10 +237,7 @@ export const config = createSlice({
|
||||
state.status = FileLoadStatus.LOADED;
|
||||
break;
|
||||
case CONFIG_LOAD_ERROR.CONFIG_CORRUPTED:
|
||||
logger.debug(
|
||||
'Config File Load Failed - %o',
|
||||
action.payload.error
|
||||
);
|
||||
logger.debug('Config File Load Failed - %o', action.payload.error);
|
||||
merge(state, action.payload.config);
|
||||
state.status = FileLoadStatus.LOADED;
|
||||
break;
|
||||
@@ -333,8 +280,7 @@ export const config = createSlice({
|
||||
|
||||
builder.addCase(setupRemoteAccessThunk.fulfilled, (state, action) => {
|
||||
state.remote.wanaccess = action.payload.wanaccess;
|
||||
state.remote.dynamicRemoteAccessType =
|
||||
action.payload.dynamicRemoteAccessType;
|
||||
state.remote.dynamicRemoteAccessType = action.payload.dynamicRemoteAccessType;
|
||||
state.remote.wanport = action.payload.wanport;
|
||||
state.remote.upnpEnabled = action.payload.upnpEnabled;
|
||||
});
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
import { getters, store } from '@app/store';
|
||||
import { watch } from 'chokidar';
|
||||
import { loadConfigFile, logoutUser } from '@app/store/modules/config';
|
||||
import { logger } from '@app/core/log';
|
||||
import { existsSync, writeFileSync } from 'fs';
|
||||
|
||||
import { watch } from 'chokidar';
|
||||
|
||||
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 { CHOKIDAR_USEPOLLING, ENVIRONMENT } from '@app/environment';
|
||||
import { getters, store } from '@app/store';
|
||||
import { initialState, loadConfigFile, logoutUser } from '@app/store/modules/config';
|
||||
|
||||
export const setupConfigPathWatch = () => {
|
||||
const myServersConfigPath = getters.paths()?.['myservers-config'];
|
||||
if (myServersConfigPath) {
|
||||
logger.info('Watch Setup on Config Path: %s', myServersConfigPath);
|
||||
if (!existsSync(myServersConfigPath)) {
|
||||
writeFileSync(myServersConfigPath, '', 'utf-8');
|
||||
}
|
||||
const watcher = watch(myServersConfigPath, {
|
||||
persistent: true,
|
||||
ignoreInitial: false,
|
||||
usePolling: CHOKIDAR_USEPOLLING === true,
|
||||
}).on('change', async () => {
|
||||
await store.dispatch(loadConfigFile());
|
||||
}).on('unlink', async () => {
|
||||
watcher.close();
|
||||
setupConfigPathWatch();
|
||||
store.dispatch(logoutUser({ reason: 'Config File was Deleted'}))
|
||||
});
|
||||
} else {
|
||||
logger.error('[FATAL] Failed to setup watch on My Servers Config (Could Not Read Config Path)');
|
||||
}
|
||||
const myServersConfigPath = getters.paths()?.['myservers-config'];
|
||||
if (myServersConfigPath) {
|
||||
logger.info('Watch Setup on Config Path: %s', myServersConfigPath);
|
||||
if (!existsSync(myServersConfigPath)) {
|
||||
const config = safelySerializeObjectToIni(getWriteableConfig(initialState, 'flash'));
|
||||
writeFileSync(myServersConfigPath, config, 'utf-8');
|
||||
}
|
||||
const watcher = watch(myServersConfigPath, {
|
||||
persistent: true,
|
||||
ignoreInitial: false,
|
||||
usePolling: CHOKIDAR_USEPOLLING === true,
|
||||
})
|
||||
.on('change', async () => {
|
||||
await store.dispatch(loadConfigFile());
|
||||
})
|
||||
.on('unlink', async () => {
|
||||
const config = safelySerializeObjectToIni(getWriteableConfig(initialState, 'flash'));
|
||||
await writeFileSync(myServersConfigPath, config, 'utf-8');
|
||||
watcher.close();
|
||||
setupConfigPathWatch();
|
||||
store.dispatch(logoutUser({ reason: 'Config File was Deleted' }));
|
||||
});
|
||||
} else {
|
||||
logger.error('[FATAL] Failed to setup watch on My Servers Config (Could Not Read Config Path)');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,10 +8,6 @@ const ApiConfigSchema = z.object({
|
||||
extraOrigins: z.string(),
|
||||
});
|
||||
|
||||
const NotifierConfigSchema = z.object({
|
||||
apikey: z.string(),
|
||||
});
|
||||
|
||||
const RemoteConfigSchema = z.object({
|
||||
wanaccess: z.string(),
|
||||
wanport: z.string(),
|
||||
@@ -29,20 +25,16 @@ const RemoteConfigSchema = z.object({
|
||||
ssoSubIds: z.string(),
|
||||
});
|
||||
|
||||
const UpcConfigSchema = z.object({
|
||||
apikey: z.string(),
|
||||
});
|
||||
|
||||
const LocalConfigSchema = z.object({});
|
||||
|
||||
// Base config schema
|
||||
export const MyServersConfigSchema = z.object({
|
||||
api: ApiConfigSchema,
|
||||
local: LocalConfigSchema,
|
||||
notifier: NotifierConfigSchema,
|
||||
remote: RemoteConfigSchema,
|
||||
upc: UpcConfigSchema,
|
||||
});
|
||||
export const MyServersConfigSchema = z
|
||||
.object({
|
||||
api: ApiConfigSchema,
|
||||
local: LocalConfigSchema,
|
||||
remote: RemoteConfigSchema,
|
||||
})
|
||||
.strip();
|
||||
|
||||
// Memory config schema
|
||||
export const ConnectionStatusSchema = z.object({
|
||||
@@ -55,16 +47,8 @@ export const MyServersConfigMemorySchema = MyServersConfigSchema.extend({
|
||||
remote: RemoteConfigSchema.extend({
|
||||
allowedOrigins: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
// Memory config with mandatory hidden fields schema
|
||||
export const MyServersConfigMemoryWithMandatoryHiddenFieldsSchema = MyServersConfigMemorySchema.extend({
|
||||
connectionStatus: ConnectionStatusSchema,
|
||||
});
|
||||
}).strip();
|
||||
|
||||
// Infer and export types from Zod schemas
|
||||
export type MyServersConfig = z.infer<typeof MyServersConfigSchema>;
|
||||
export type MyServersConfigMemory = z.infer<typeof MyServersConfigMemorySchema>;
|
||||
export type MyServersConfigMemoryWithMandatoryHiddenFields = z.infer<
|
||||
typeof MyServersConfigMemoryWithMandatoryHiddenFieldsSchema
|
||||
>;
|
||||
|
||||
@@ -42,11 +42,11 @@ export class ValidateTokenCommand extends CommandRunner {
|
||||
let caughtError: null | unknown = null;
|
||||
let tokenPayload: null | JWTPayload = null;
|
||||
try {
|
||||
this.logger.debug('Attempting to validate token with local key');
|
||||
// this.logger.debug('Attempting to validate token with local key');
|
||||
tokenPayload = (await jwtVerify(token, this.JWKSOffline)).payload;
|
||||
} catch (error: unknown) {
|
||||
try {
|
||||
this.logger.debug('Local validation failed for key, trying remote validation');
|
||||
// this.logger.debug('Local validation failed for key, trying remote validation');
|
||||
tokenPayload = (await jwtVerify(token, this.JWKSOnline)).payload;
|
||||
} catch (error: unknown) {
|
||||
caughtError = error;
|
||||
|
||||
Reference in New Issue
Block a user