core: fix crash due to unsanitized sort options (#5324)

Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
This commit is contained in:
Muhammad Ali
2024-05-04 23:26:58 +05:00
committed by GitHub
parent 8a9848634c
commit 159ce97e42
3 changed files with 66 additions and 6 deletions

View File

@@ -331,6 +331,39 @@ describe("format reminder time", () => {
}); });
}); });
test("sorting reminders by dateEdited shouldn't throw", () =>
databaseTest().then(async (db) => {
await db.reminders.add({
recurringMode: "day",
date: new Date(0).setHours(14),
mode: "repeat",
title: "Random reminder"
});
await expect(
db.reminders.all.ids({
groupBy: "default",
sortBy: "dateEdited",
sortDirection: "desc"
})
).resolves.toBeDefined();
await expect(
db.reminders.all.groups({
groupBy: "default",
sortBy: "dateEdited",
sortDirection: "desc"
})
).resolves.toBeDefined();
await expect(
db.reminders.all
.grouped({
groupBy: "default",
sortBy: "dateEdited",
sortDirection: "desc"
})
.then((g) => g.item(0))
).resolves.toBeDefined();
}));
async function compareReminder(reminder) { async function compareReminder(reminder) {
const db = await databaseTest(); const db = await databaseTest();
const id = await db.reminders.add(reminder); const id = await db.reminders.add(reminder);

View File

@@ -134,11 +134,7 @@ export class Settings implements ICollection {
} }
getGroupOptions(key: GroupingKey) { getGroupOptions(key: GroupingKey) {
const options = this.get(`groupOptions:${key}`); return this.get(`groupOptions:${key}`);
// TODO: remove this check
if (key === "tags" && options.sortBy === "dateEdited")
options.sortBy = "dateModified";
return options;
} }
setGroupOptions(key: GroupingKey, groupOptions: GroupOptions) { setGroupOptions(key: GroupingKey, groupOptions: GroupOptions) {

View File

@@ -443,6 +443,7 @@ export class FilteredSelector<T extends Item> {
} }
async grouped(options: GroupOptions) { async grouped(options: GroupOptions) {
sanitizeSortOptions(this.type, options);
const count = await this.count(); const count = await this.count();
return new VirtualizedGrouping<T>( return new VirtualizedGrouping<T>(
count, count,
@@ -466,6 +467,8 @@ export class FilteredSelector<T extends Item> {
} }
async groups(options: GroupOptions) { async groups(options: GroupOptions) {
sanitizeSortOptions(this.type, options);
const fields: Array< const fields: Array<
| AnyColumnWithTable<DatabaseSchema, keyof DatabaseSchema> | AnyColumnWithTable<DatabaseSchema, keyof DatabaseSchema>
| AnyColumn<DatabaseSchema, keyof DatabaseSchema> | AnyColumn<DatabaseSchema, keyof DatabaseSchema>
@@ -558,6 +561,8 @@ export class FilteredSelector<T extends Item> {
options: GroupOptions | SortOptions, options: GroupOptions | SortOptions,
hasDueDate?: boolean hasDueDate?: boolean
) { ) {
sanitizeSortOptions(this.type, options);
const sortBy: Set<SortOptions["sortBy"]> = new Set(); const sortBy: Set<SortOptions["sortBy"]> = new Set();
if (isGroupOptions(options)) { if (isGroupOptions(options)) {
if (options.groupBy === "abc") sortBy.add("title"); if (options.groupBy === "abc") sortBy.add("title");
@@ -612,7 +617,6 @@ export class FilteredSelector<T extends Item> {
); );
} }
} }
return qb; return qb;
}; };
} }
@@ -634,3 +638,30 @@ function isSortByDate(options: SortOptions | GroupOptions) {
options.sortBy === "dueDate" options.sortBy === "dueDate"
); );
} }
const BASE_FIELDS: SortOptions["sortBy"][] = ["dateCreated", "dateModified"];
const VALID_SORT_OPTIONS: Record<
keyof DatabaseSchema,
SortOptions["sortBy"][]
> = {
reminders: ["dueDate", "title"],
tags: ["title"],
attachments: ["filename", "dateUploaded", "size"],
colors: ["title"],
notebooks: ["title"],
notes: ["title"],
content: [],
notehistory: [],
relations: [],
sessioncontent: [],
settings: [],
shortcuts: [],
vaults: []
};
function sanitizeSortOptions(type: keyof DatabaseSchema, options: SortOptions) {
const validFields = [...VALID_SORT_OPTIONS[type], ...BASE_FIELDS];
if (!validFields.includes(options.sortBy)) options.sortBy = validFields[0];
return options;
}