feat(views): add unique constraint to filterBySource for each user

This commit is contained in:
Aminejv 2022-09-14 14:18:51 +01:00
parent f576dd7376
commit 95287d322f
4 changed files with 37 additions and 6 deletions

View File

@ -111,6 +111,7 @@ import createSurvey from "~/node_common/data/methods/create-survey";
// Views // Views
import getViewById from "~/node_common/data/methods/get-view-by-id"; import getViewById from "~/node_common/data/methods/get-view-by-id";
import getViewsByUserId from "~/node_common/data/methods/get-views-by-user-id"; import getViewsByUserId from "~/node_common/data/methods/get-views-by-user-id";
import getViewByUserIdAndSource from "~/node_common/data/methods/get-view-by-user-id-and-source";
import createView from "~/node_common/data/methods/create-view"; import createView from "~/node_common/data/methods/create-view";
import deleViewById from "~/node_common/data/methods/delete-view-by-id"; import deleViewById from "~/node_common/data/methods/delete-view-by-id";
@ -200,6 +201,7 @@ export {
createSurvey, createSurvey,
//NOTE(amine): Views //NOTE(amine): Views
getViewsByUserId, getViewsByUserId,
getViewByUserIdAndSource,
getViewById, getViewById,
createView, createView,
deleViewById, deleViewById,

View File

@ -0,0 +1,22 @@
import { runQuery } from "~/node_common/data/utilities";
export default async ({ ownerId, filterBySource }) => {
return await runQuery({
label: "GET_VIEW_BY_USER_ID_AND_SOURCE",
queryFn: async (DB) => {
const query = await DB.select("*").from("views").where({ ownerId, filterBySource }).first();
if (!query || query.error) {
return null;
}
return JSON.parse(JSON.stringify(query));
},
errorFn: async (e) => {
return {
error: true,
decorator: "GET_VIEW_BY_USER_ID_AND_SOURCE",
};
},
});
};

View File

@ -9,6 +9,11 @@ export default async (req, res) => {
return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_NOT_ALLOWED", error: true }); return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_NOT_ALLOWED", error: true });
} }
const userInfo = await RequestUtilities.checkAuthorizationInternal(req, res);
if (!userInfo) {
return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_NOT_ALLOWED", error: true });
}
const name = req?.body?.data?.name; const name = req?.body?.data?.name;
const filterBySource = req?.body?.data?.filterBySource; const filterBySource = req?.body?.data?.filterBySource;
const filterBySlateId = req?.body?.data?.filterBySlateId; const filterBySlateId = req?.body?.data?.filterBySlateId;
@ -18,12 +23,19 @@ export default async (req, res) => {
return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_INVALID_DATA", error: true }); return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_INVALID_DATA", error: true });
} }
const { id } = userInfo;
if (filterBySource) { if (filterBySource) {
try { try {
new URL(filterBySource); new URL(filterBySource);
} catch (e) { } catch (e) {
return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_INVALID_DATA", error: true }); return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_INVALID_DATA", error: true });
} }
const existingView = await Data.getViewByUserIdAndSource({ ownerId: id, filterBySource });
if (existingView) {
return res.status(403).send({ decorator: "SERVER_CREATE_VIEW_INVALID_DATA", error: true });
}
} }
if (filterBySlateId) { if (filterBySlateId) {
@ -33,11 +45,6 @@ export default async (req, res) => {
} }
} }
const userInfo = await RequestUtilities.checkAuthorizationInternal(req, res);
if (!userInfo) return;
const { id } = userInfo;
const response = await Data.createView({ const response = await Data.createView({
ownerId: id, ownerId: id,
name, name,

View File

@ -221,7 +221,7 @@ const createViewsTable = createTableIfNotExists("views", function (table) {
table.string("name").notNullable(); table.string("name").notNullable();
table.timestamp("createdAt").notNullable().defaultTo(db.raw("now()")); table.timestamp("createdAt").notNullable().defaultTo(db.raw("now()"));
table.string("filterBySource").unique().nullable(); table.string("filterBySource").nullable();
table.uuid("filterBySlateId").references("id").inTable("slates").unique().nullable(); table.uuid("filterBySlateId").references("id").inTable("slates").unique().nullable();
table.jsonb("metadata").notNullable().defaultTo(JSON.stringify({})); table.jsonb("metadata").notNullable().defaultTo(JSON.stringify({}));
}); });