[FIX] Remove invalid settings at startup (#27653)

pull/27660/head
Kevin Aleman 3 years ago committed by GitHub
parent ecc06e804f
commit a3b8f16fcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      apps/meteor/client/views/admin/settings/Section.tsx
  2. 7
      apps/meteor/client/views/admin/settings/Setting.tsx
  3. 40
      apps/meteor/server/lib/settingsRegenerator.ts
  4. 1
      apps/meteor/server/startup/index.ts
  5. 11
      packages/core-typings/src/ISetting.ts

@ -1,4 +1,4 @@
import { isSettingColor } from '@rocket.chat/core-typings';
import { isSetting, isSettingColor } from '@rocket.chat/core-typings';
import { Accordion, Box, Button, FieldGroup } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
@ -84,9 +84,9 @@ function Section({ groupId, hasReset = true, sectionName, tabName = '', solo, he
)}
<FieldGroup>
{editableSettings.map((setting) => (
<Setting key={setting._id} settingId={setting._id} sectionChanged={changed} />
))}
{editableSettings.map(
(setting) => isSetting(setting) && <Setting key={setting._id} settingId={setting._id} sectionChanged={changed} />,
)}
{children}
</FieldGroup>

@ -1,5 +1,5 @@
import type { ISettingColor, SettingEditor, SettingValue } from '@rocket.chat/core-typings';
import { isSettingColor } from '@rocket.chat/core-typings';
import { isSettingColor, isSetting } from '@rocket.chat/core-typings';
import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks';
import { useSettingStructure, useTranslation, useAbsoluteUrl } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
@ -25,6 +25,11 @@ function Setting({ className = undefined, settingId, sectionChanged }: SettingPr
throw new Error(`Setting ${settingId} not found`);
}
// Checks if setting has at least required fields before doing anything
if (!isSetting(setting)) {
throw new Error(`Setting ${settingId} is not valid`);
}
const dispatch = useEditableSettingsDispatch();
const update = useDebouncedCallback(

@ -0,0 +1,40 @@
// Validates settings on DB are correct on structure
// And deletes invalid ones
import { Meteor } from 'meteor/meteor';
import { Settings } from '@rocket.chat/models';
import { Logger } from './logger/Logger';
// Validates settings on DB are correct on structure by matching the ones missing all the required fields
const logger = new Logger('SettingsRegenerator');
export async function settingsRegenerator() {
const invalidSettings = await Settings.find(
{
// Putting the $and explicit to ensure it's "intentional"
$and: [
{ value: { $exists: false } },
{ type: { $exists: false } },
{ public: { $exists: false } },
{ packageValue: { $exists: false } },
{ blocked: { $exists: false } },
{ sorter: { $exists: false } },
{ i18nLabel: { $exists: false } },
],
},
{ projection: { _id: 1 } },
).toArray();
if (invalidSettings.length > 0) {
logger.warn({
msg: 'Invalid settings found on DB. Deleting them.',
settings: invalidSettings.map(({ _id }) => _id),
});
await Settings.deleteMany({ _id: { $in: invalidSettings.map(({ _id }) => _id) } });
} else {
logger.info('No invalid settings found on DB.');
}
}
Meteor.startup(async () => {
await settingsRegenerator();
});

@ -9,6 +9,7 @@ import './coreApps';
import './presenceTroubleshoot';
import '../hooks';
import '../lib/rooms/roomTypes';
import '../lib/settingsRegenerator';
import { isRunningMs } from '../lib/isRunningMs';
// only starts network broker if running in micro services mode

@ -132,6 +132,17 @@ export interface ISettingDate extends ISettingBase {
value: Date;
}
// Checks if setting has at least the required properties
export const isSetting = (setting: any): setting is ISetting =>
'_id' in setting &&
'type' in setting &&
'public' in setting &&
'value' in setting &&
'packageValue' in setting &&
'blocked' in setting &&
'sorter' in setting &&
'i18nLabel' in setting;
export const isDateSetting = (setting: ISetting): setting is ISettingDate => setting.type === 'date';
export const isSettingEnterprise = (setting: ISettingBase): setting is ISettingEnterprise => setting.enterprise === true;

Loading…
Cancel
Save