mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-25 18:13:10 +03:00
modified backend to recalculate file privacy upon add/remove from public collection
This commit is contained in:
parent
cb697088b0
commit
c86a738266
@ -404,14 +404,6 @@ export const updateFile = async (data) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const toggleFilePrivacy = async (data) => {
|
||||
await Websockets.checkWebsocket();
|
||||
return await returnJSON(`/api/data/toggle-privacy`, {
|
||||
...DEFAULT_OPTIONS,
|
||||
body: JSON.stringify({ data }),
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteFiles = async (data) => {
|
||||
await Websockets.checkWebsocket();
|
||||
return await returnJSON(`/api/data/delete`, {
|
||||
|
@ -210,8 +210,8 @@ export default class SidebarCreateSlate extends React.Component {
|
||||
marginTop: 12,
|
||||
}}
|
||||
>
|
||||
All collections are public by default. This means they can be discovered and seen by
|
||||
anyone on the internet. If you make it private, only you will be able to see it.
|
||||
Public collections can be discovered and seen by anyone on the internet. If you make it
|
||||
private, only you will be able to see it.
|
||||
</System.P1>
|
||||
<RadioGroup
|
||||
name="isPublic"
|
||||
|
@ -25,9 +25,8 @@ import getFilesByUserId from "~/node_common/data/methods/get-files-by-user-id";
|
||||
import deleteFilesByIds from "~/node_common/data/methods/delete-files-by-ids";
|
||||
import deleteFilesByUserId from "~/node_common/data/methods/delete-files-by-user-id";
|
||||
import updateFileById from "~/node_common/data/methods/update-file-by-id";
|
||||
import updateFilePrivacy from "~/node_common/data/methods/update-file-privacy";
|
||||
import updateFilesPublic from "~/node_common/data/methods/update-files-public";
|
||||
import incrementFileSavecount from "~/node_common/data/methods/increment-file-savecount";
|
||||
import recalcFilePrivacy from "~/node_common/data/methods/recalc-file-privacy";
|
||||
|
||||
// NOTE(martina):
|
||||
// Like postgres queries
|
||||
@ -121,9 +120,8 @@ export {
|
||||
deleteFilesByIds,
|
||||
deleteFilesByUserId,
|
||||
updateFileById,
|
||||
updateFilePrivacy,
|
||||
updateFilesPublic,
|
||||
incrementFileSavecount,
|
||||
recalcFilePrivacy,
|
||||
// NOTE(martina): Like postgres queries
|
||||
createLike,
|
||||
deleteLikeByFile,
|
||||
|
42
node_common/data/methods/recalc-file-privacy.js
Normal file
42
node_common/data/methods/recalc-file-privacy.js
Normal file
@ -0,0 +1,42 @@
|
||||
import { runQuery } from "~/node_common/data/utilities";
|
||||
|
||||
export default async ({ fileId }) => {
|
||||
return await runQuery({
|
||||
label: "RECALC_FILE_PRIVACY",
|
||||
queryFn: async (DB) => {
|
||||
const slateIds = `(SELECT ?? FROM ?? WHERE ?? = ?)`;
|
||||
const slateIdsFields = ["slateId", "slate_files", "fileId", fileId];
|
||||
|
||||
const filePrivacy = `(SELECT EXISTS (SELECT * FROM ?? JOIN ?? ON ?? = ?? WHERE ?? = ?))`;
|
||||
const filePrivacyFields = [
|
||||
"slates",
|
||||
"slate_ids",
|
||||
"slates.id",
|
||||
"slate_ids.slateId",
|
||||
"isPublic",
|
||||
true,
|
||||
];
|
||||
|
||||
const update = `UPDATE ?? SET ?? = ${filePrivacy} WHERE ?? = ?`;
|
||||
const updateFields = ["files", "isPublic", ...filePrivacyFields, "id", fileId];
|
||||
|
||||
const updatedFile = await DB.raw(`WITH ?? AS ${slateIds} ${update} RETURNING *`, [
|
||||
"slate_ids",
|
||||
...slateIdsFields,
|
||||
...updateFields,
|
||||
]);
|
||||
let rows = updatedFile.rows;
|
||||
if (rows?.length) {
|
||||
return rows.first();
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
errorFn: async (e) => {
|
||||
return {
|
||||
error: true,
|
||||
decorator: "RECALC_FILE_PRIVACY",
|
||||
};
|
||||
},
|
||||
});
|
||||
};
|
@ -6,6 +6,8 @@ import * as Social from "~/node_common/social";
|
||||
import * as Logging from "~/common/logging";
|
||||
import * as ArrayUtilities from "~/node_common/array-utilities";
|
||||
import * as Monitor from "~/node_common/monitor";
|
||||
import * as Arrays from "~/common/arrays";
|
||||
import * as SearchManager from "~/node_common/managers/search";
|
||||
|
||||
import crypto from "crypto";
|
||||
import JWT from "jsonwebtoken";
|
||||
@ -285,3 +287,35 @@ export const addToSlate = async ({ slate, files, user, saveCopy = false }) => {
|
||||
|
||||
return { added: response.length };
|
||||
};
|
||||
|
||||
export const removeFromPublicCollectionUpdatePrivacy = async ({ files }) => {
|
||||
let targetFiles = Arrays.filterPublic(files);
|
||||
let madePrivate = [];
|
||||
for (let file of targetFiles) {
|
||||
let updatedFile = await Data.recalcFilePrivacy({ fileId: file.id });
|
||||
if (!updatedFile) continue;
|
||||
if (file.isPublic && !updatedFile.isPublic) {
|
||||
madePrivate.push(updatedFile);
|
||||
}
|
||||
}
|
||||
if (madePrivate.length) {
|
||||
SearchManager.updateFile(madePrivate, "REMOVE");
|
||||
}
|
||||
return madePrivate;
|
||||
};
|
||||
|
||||
export const addToPublicCollectionUpdatePrivacy = async ({ files }) => {
|
||||
let targetFiles = Arrays.filterPrivate(files);
|
||||
let madePublic = [];
|
||||
for (let file of targetFiles) {
|
||||
let updatedFile = await Data.recalcFilePrivacy({ fileId: file.id });
|
||||
if (!updatedFile) continue;
|
||||
if (!file.isPublic && updatedFile.isPublic) {
|
||||
madePublic.push(updatedFile);
|
||||
}
|
||||
}
|
||||
if (madePublic.length) {
|
||||
SearchManager.updateFile(madePublic, "ADD");
|
||||
}
|
||||
return madePublic;
|
||||
};
|
||||
|
@ -35,20 +35,7 @@ export default async (req, res) => {
|
||||
SearchManager.updateSlate(slate, "REMOVE");
|
||||
|
||||
if (slate.isPublic) {
|
||||
//NOTE(martina): if any of the files in it are now private (because they are no longer in any public slates) remove them from search
|
||||
const files = slate.objects;
|
||||
|
||||
const publicFiles = await Data.getFilesByIds({
|
||||
ids: files.map((file) => file.id),
|
||||
publicOnly: true,
|
||||
});
|
||||
const publicIds = publicFiles.map((file) => file.id);
|
||||
|
||||
let privateFiles = files.filter((file) => !publicIds.includes(file.id));
|
||||
|
||||
if (privateFiles.length) {
|
||||
SearchManager.updateFile(privateFiles, "REMOVE");
|
||||
}
|
||||
Utilities.removeFromPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
}
|
||||
|
||||
return res.status(200).send({ decorator: "SERVER_DELETE_SLATE", error: false });
|
||||
|
@ -20,7 +20,7 @@ export default async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const slate = await Data.getSlateById({ id: req.body.data.slateId });
|
||||
const slate = await Data.getSlateById({ id: req.body.data.slateId, includeFiles: true });
|
||||
|
||||
if (!slate) {
|
||||
return res.status(404).send({
|
||||
@ -46,18 +46,7 @@ export default async (req, res) => {
|
||||
}
|
||||
|
||||
if (slate.isPublic) {
|
||||
const publicFiles = await Data.getFilesByIds({ ids: fileIds, publicOnly: true });
|
||||
const publicIds = publicFiles.map((file) => file.id);
|
||||
|
||||
let privateFiles = fileIds
|
||||
.filter((id) => !publicIds.includes(id))
|
||||
.map((id) => {
|
||||
return { id };
|
||||
});
|
||||
|
||||
if (privateFiles.length) {
|
||||
SearchManager.updateFile(privateFiles, "REMOVE");
|
||||
}
|
||||
Utilities.removeFromPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
}
|
||||
|
||||
ViewerManager.hydratePartial(id, { slates: true });
|
||||
|
@ -48,28 +48,6 @@ export default async (req, res) => {
|
||||
.status(500)
|
||||
.send({ decorator: "SERVER_UPDATE_SLATE_UPDATE_PRIVACY_FAILED", error: true });
|
||||
}
|
||||
|
||||
if (!updates.isPublic) {
|
||||
//NOTE(martina): if any of the files in it are now private (because they are no longer in any public slates) remove them from search
|
||||
const files = slate.objects;
|
||||
|
||||
const publicFiles = await Data.getFilesByIds({
|
||||
ids: files.map((file) => file.id),
|
||||
publicOnly: true,
|
||||
});
|
||||
const publicIds = publicFiles.map((file) => file.id);
|
||||
|
||||
let privateFiles = files.filter((file) => !publicIds.includes(file.id));
|
||||
|
||||
if (privateFiles.length) {
|
||||
SearchManager.updateFile(privateFiles, "REMOVE");
|
||||
}
|
||||
} else {
|
||||
//NOTE(martina): make sure all the now-public files are in search if they weren't already
|
||||
const files = slate.objects;
|
||||
|
||||
SearchManager.updateFile(files, "ADD");
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.data.name && updates.data.name !== slate.data.name) {
|
||||
@ -111,8 +89,12 @@ export default async (req, res) => {
|
||||
|
||||
if (slate.isPublic && !updates.isPublic) {
|
||||
SearchManager.updateSlate(response, "REMOVE");
|
||||
|
||||
Utilities.removeFromPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
} else if (!slate.isPublic && updates.isPublic) {
|
||||
SearchManager.updateSlate(response, "ADD");
|
||||
|
||||
Utilities.addToPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
} else {
|
||||
SearchManager.updateSlate(response, "EDIT");
|
||||
}
|
||||
|
@ -59,28 +59,6 @@ export default async (req, res) => {
|
||||
if (privacyResponse.error) {
|
||||
return res.status(500).send({ decorator: "UPDATE_COLLECTION_PRIVACY_FAILED", error: true });
|
||||
}
|
||||
|
||||
if (!updates.isPublic) {
|
||||
//NOTE(martina): if any of the files in it are now private (because they are no longer in any public slates) remove them from search
|
||||
const files = slate.objects;
|
||||
|
||||
const publicFiles = await Data.getFilesByIds({
|
||||
ids: files.map((file) => file.id),
|
||||
publicOnly: true,
|
||||
});
|
||||
const publicIds = publicFiles.map((file) => file.id);
|
||||
|
||||
let privateFiles = files.filter((file) => !publicIds.includes(file.id));
|
||||
|
||||
if (privateFiles.length) {
|
||||
SearchManager.updateFile(privateFiles, "REMOVE");
|
||||
}
|
||||
} else {
|
||||
//NOTE(martina): make sure all the now-public files are in search if they weren't already
|
||||
const files = slate.objects;
|
||||
|
||||
SearchManager.updateFile(files, "ADD");
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.data.name && updates.data.name !== slate.data.name) {
|
||||
@ -118,8 +96,10 @@ export default async (req, res) => {
|
||||
|
||||
if (slate.isPublic && !updates.isPublic) {
|
||||
SearchManager.updateSlate(updatedSlate, "REMOVE");
|
||||
Utilities.removeFromPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
} else if (!slate.isPublic && updates.isPublic) {
|
||||
SearchManager.updateSlate(updatedSlate, "ADD");
|
||||
Utilities.addToPublicCollectionUpdatePrivacy({ files: slate.objects });
|
||||
} else {
|
||||
SearchManager.updateSlate(updatedSlate, "EDIT");
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ export default async (req, res) => {
|
||||
//NOTE(martina): cleans the input to remove fields they should not be changing like ownerId, createdAt, filename, size, type etc.
|
||||
let updates = {
|
||||
id: req.body.data.id,
|
||||
isPublic: req.body.data.isPublic,
|
||||
data: {
|
||||
name: req.body.data.data?.name,
|
||||
body: req.body.data.data?.body,
|
||||
@ -34,24 +33,6 @@ export default async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof updates.isPublic !== "undefined" && updates.isPublic !== file.isPublic) {
|
||||
let response = await Data.updateFilePrivacy({
|
||||
ownerId: file.ownerId,
|
||||
id: updates.id,
|
||||
isPublic: updates.isPublic,
|
||||
});
|
||||
|
||||
if (!response || response.error) {
|
||||
return res.status(500).send({ decorator: "UPDATE_FILE_PRIVACY_FAILED", error: true });
|
||||
}
|
||||
|
||||
if (response.isPublic) {
|
||||
SearchManager.updateFile(response, "ADD");
|
||||
} else {
|
||||
SearchManager.updateFile(response, "REMOVE");
|
||||
}
|
||||
}
|
||||
|
||||
let response = await Data.updateFileById(updates);
|
||||
|
||||
if (!response || response.error) {
|
||||
|
Loading…
Reference in New Issue
Block a user