From 36243cd3bd06b18691ab920a971bdc257bbdf884 Mon Sep 17 00:00:00 2001 From: Aminejv Date: Tue, 3 Aug 2021 18:07:48 +0100 Subject: [PATCH 1/7] feat(sanizeUser): remove email and twitterId --- node_common/serializers.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/node_common/serializers.js b/node_common/serializers.js index 17ae21331..465444fc7 100644 --- a/node_common/serializers.js +++ b/node_common/serializers.js @@ -11,8 +11,6 @@ export const sanitizeUser = (entity) => { username: entity.username, slates: entity.slates, //NOTE(martina): this is not in the database. It is added after library: entity.library, //NOTE(martina): this is not in the database. It is added after - twitterId: entity.twitterId, - email: entity.email, data: { name: entity.data?.name, photo: entity.data?.photo, From 0b8c1b0d6390ff84c407a7ff6f1506a963e7ab94 Mon Sep 17 00:00:00 2001 From: Aminejv Date: Tue, 3 Aug 2021 18:08:26 +0100 Subject: [PATCH 2/7] feat(getSocial): remove following and followers --- pages/api/users/get-social.js | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/pages/api/users/get-social.js b/pages/api/users/get-social.js index 51108b9d9..2b349cdd5 100644 --- a/pages/api/users/get-social.js +++ b/pages/api/users/get-social.js @@ -1,8 +1,7 @@ import * as Data from "~/node_common/data"; -import * as Serializers from "~/node_common/serializers"; export default async (req, res) => { - let id = req.body.data.id; + let { id } = req.body.data; if (!id) { return res.status(404).send({ decorator: "SERVER_USER_SOCIAL_NO_USER_ID", error: true }); } @@ -21,38 +20,8 @@ export default async (req, res) => { .send({ decorator: "SERVER_USER_SOCIAL_SUBSCRIPTIONS_NOT_FOUND", error: true }); } - const following = await Data.getFollowingByUserId({ ownerId: id }); - - if (!following) { - return res - .status(404) - .send({ decorator: "SERVER_USER_SOCIAL_FOLLOWING_NOT_FOUND", error: true }); - } - - if (following.error) { - return res - .status(500) - .send({ decorator: "SERVER_USER_SOCIAL_FOLLOWING_NOT_FOUND", error: true }); - } - - const followers = await Data.getFollowersByUserId({ userId: id }); - - if (!followers) { - return res - .status(404) - .send({ decorator: "SERVER_USER_SOCIAL_FOLLOWERS_NOT_FOUND", error: true }); - } - - if (followers.error) { - return res - .status(500) - .send({ decorator: "SERVER_USER_SOCIAL_FOLLOWERS_NOT_FOUND", error: true }); - } - return res.status(200).send({ decorator: "SERVER_USER_SOCIAL", - following, - followers, subscriptions, }); }; From 2c9e7c4f000883be24402cca68c5891b89c81c9f Mon Sep 17 00:00:00 2001 From: Aminejv Date: Tue, 3 Aug 2021 18:09:35 +0100 Subject: [PATCH 3/7] feat(server.js): remove files from profile data --- server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server.js b/server.js index d19f8d96b..d773abff6 100644 --- a/server.js +++ b/server.js @@ -319,7 +319,6 @@ app.prepare().then(async () => { let user = await Data.getUserByUsername({ username, - includeFiles: true, sanitize: true, publicOnly: true, }); From 23fb81d013628995871681ea1c751a5157bc5e16 Mon Sep 17 00:00:00 2001 From: Aminejv Date: Tue, 3 Aug 2021 18:10:02 +0100 Subject: [PATCH 4/7] feat(profile): remove peers and files --- components/core/Profile.js | 369 ++----------------------------------- 1 file changed, 14 insertions(+), 355 deletions(-) diff --git a/components/core/Profile.js b/components/core/Profile.js index fe7d6e322..92bf316ea 100644 --- a/components/core/Profile.js +++ b/components/core/Profile.js @@ -3,25 +3,16 @@ import * as Constants from "~/common/constants"; import * as Strings from "~/common/strings"; import * as SVG from "~/common/svg"; import * as Actions from "~/common/actions"; -import * as Utilities from "~/common/utilities"; import * as Events from "~/common/custom-events"; -import * as Window from "~/common/window"; import * as Styles from "~/common/styles"; -import { useState } from "react"; import { Link } from "~/components/core/Link"; -import { GlobalCarousel } from "~/components/system/components/GlobalCarousel"; import { css } from "@emotion/react"; import { ButtonPrimary, ButtonSecondary } from "~/components/system/components/Buttons"; -import { TabGroup, SecondaryTabGroup } from "~/components/core/TabGroup"; -import { Boundary } from "~/components/system/components/fragments/Boundary"; -import { PopoverNavigation } from "~/components/system/components/PopoverNavigation"; -import { FileTypeGroup } from "~/components/core/FileTypeIcon"; +import { SecondaryTabGroup } from "~/components/core/TabGroup"; import { LoaderSpinner } from "~/components/system/components/Loaders"; import ProcessedText from "~/components/core/ProcessedText"; -import SlatePreviewBlocks from "~/components/core/SlatePreviewBlock"; -import DataView from "~/components/core/DataView"; import EmptyState from "~/components/core/EmptyState"; import ProfilePhoto from "~/components/core/ProfilePhoto"; import CollectionPreviewBlock from "~/components/core/CollectionPreviewBlock"; @@ -139,16 +130,6 @@ const STYLES_STAT = css` flex-shrink: 0; `; -const STYLES_EXPLORE = css` - font-size: ${Constants.typescale.lvl1}; - font-family: ${Constants.font.text}; - font-weight: 400; - margin: 64px auto 64px auto; - width: 120px; - padding-top: 16px; - border-top: 1px solid ${Constants.system.black}; -`; - const STYLES_BUTTON = css` margin-bottom: 32px; @@ -157,164 +138,12 @@ const STYLES_BUTTON = css` } `; -const STYLES_ITEM_BOX = css` - position: relative; - justify-self: end; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; - margin-right: 16px; - color: ${Constants.system.grayLight2}; - - @media (max-width: ${Constants.sizes.mobile}px) { - margin-right: 8px; - } -`; - -const STYLES_USER_ENTRY = css` - display: grid; - grid-template-columns: auto 1fr; - align-items: center; - font-size: ${Constants.typescale.lvl1}; - cursor: pointer; - border: 1px solid ${Constants.semantic.borderGrayLight}; - border-radius: 4px; - margin-bottom: 8px; - background-color: ${Constants.system.white}; -`; - -const STYLES_USER = css` - display: grid; - grid-template-columns: auto 1fr; - align-items: center; - margin: 16px; - color: ${Constants.system.blue}; - font-family: ${Constants.font.medium}; - font-size: ${Constants.typescale.lvl1}; - - @media (max-width: ${Constants.sizes.mobile}px) { - margin: 12px 16px; - } -`; - -const STYLES_DIRECTORY_PROFILE_IMAGE = css` - background-color: ${Constants.semantic.bgLight}; - background-size: cover; - background-position: 50% 50%; - height: 24px; - width: 24px; - margin-right: 16px; - border-radius: 4px; - position: relative; -`; - -const STYLES_DIRECTORY_STATUS_INDICATOR = css` - position: absolute; - bottom: 0; - right: 0; - width: 7px; - height: 7px; - border-radius: 50%; - border: 1.2px solid ${Constants.system.green}; - background-color: ${Constants.system.green}; -`; - -const STYLES_MESSAGE = css` - color: ${Constants.system.black}; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - - @media (max-width: 1000px) { - display: none; - } -`; - -const STYLES_DIRECTORY_NAME = css` - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -`; - // const STYLES_COPY_INPUT = css` // pointer-events: none; // position: absolute; // opacity: 0; // `; -function UserEntry({ user, button, onClick, message, checkStatus }) { - const isOnline = checkStatus({ id: user.id }); - - return ( -
-
-
- - {isOnline &&
} -
- - {user.data.name || `@${user.username}`} - {message ? {message} : null} - -
- {button} -
- ); -} - -function FilesPage({ - library, - user, - isOwner, - isMobile, - viewer, - onAction, - resources, - page, - tab = "grid", -}) { - return ( -
- {isMobile ? null : ( - , - value: { tab: "grid", subtab: "files" }, - }, - { - title: , - value: { tab: "table", subtab: "files" }, - }, - ]} - value={tab} - onAction={onAction} - style={{ margin: "0 0 24px 0" }} - /> - )} - {library.length ? ( - - ) : ( - - -
This user does not have any public files yet
-
- )} -
- ); -} - function CollectionsPage({ user, viewer, @@ -339,8 +168,8 @@ function CollectionsPage({
{ - e.stopPropagation(); - e.preventDefault(); - if (!id || selectedUser === id) { - setSelectedUser(null); - } else { - setSelectedUser(id); - } - }; - const followUser = async (e, id) => { - e.stopPropagation(); - e.preventDefault(); - selectUser(e, null); - if (!viewer) { - onLoginModal(); - return; - } - await Actions.createSubscription({ - userId: id, - }); - }; - - let peers = tab === "following" ? following : followers; - peers = peers.map((relation) => { - const following = !!( - viewer && - viewer.following.some((subscription) => { - return subscription.id === relation.id; - }).length - ); - let button = - !viewer || relation.id !== viewer?.id ? ( -
selectUser(e, relation.id)}> - - {selectedUser === relation.id ? ( - selectUser(e)} - > - followUser(e, relation.id), - }, - ], - ]} - /> - - ) : null} -
- ) : null; - - return ( - - - - ); - }); - - return ( -
- -
- {peers?.length ? ( - peers - ) : ( - - {fetched ? ( - - - {tab === "following" - ? `This user is not following anyone yet` - : `This user does not have any followers yet`} - - ) : ( - - )} - - )} -
-
- ); -} - export default class Profile extends React.Component { _ref = null; state = { contextMenu: null, subscriptions: [], - followers: [], - following: [], isFollowing: this.props.external || this.props.user.id === this.props.viewer?.id ? false @@ -506,10 +222,6 @@ export default class Profile extends React.Component { index: -1, }; - componentDidMount = () => { - this.fetchSocial(); - }; - componentDidUpdate = (prevProps) => { if (!this.state.fetched && this.props.page.params !== prevProps.page.params) { this.fetchSocial(); @@ -518,12 +230,9 @@ export default class Profile extends React.Component { fetchSocial = async () => { if (this.state.fetched) return; - if (this.props.page.params?.subtab !== "peers" && this.props.page.params?.tab !== "subscribed") - return; - let following, followers, subscriptions; + if (this.props.page.params?.tab !== "subscribed") return; + let subscriptions; if (this.props.user.id === this.props.viewer?.id) { - following = this.props.viewer?.following; - followers = this.props.viewer?.followers; subscriptions = this.props.viewer?.subscriptions; } else { const query = { id: this.props.user.id }; @@ -531,19 +240,15 @@ export default class Profile extends React.Component { if (Events.hasError(response)) { return; } - following = response.following; - followers = response.followers; subscriptions = response.subscriptions; } this.setState({ - following: following, - followers: followers, subscriptions: subscriptions, fetched: true, }); }; - _handleHide = (e) => { + _handleHide = () => { this.setState({ contextMenu: null }); }; @@ -582,33 +287,14 @@ export default class Profile extends React.Component { }; render() { - let subtab = this.props.page.params?.subtab - ? this.props.page.params?.subtab - : this.props.page.params?.cid - ? "files" - : "collections"; let tab = this.props.page.params?.tab; - let library = this.props.user.library; - let isOwner = this.props.isOwner; - let user = this.props.user; + let { user, isOwner } = this.props; + let { fileCount } = user; const showStatusIndicator = this.props.isAuthenticated; return (
- this.setState({ index })} - />
@@ -650,7 +336,7 @@ export default class Profile extends React.Component {
- {library.length}{" "} + {fileCount}{" "} Files
@@ -665,39 +351,12 @@ export default class Profile extends React.Component {
- - {subtab === "files" ? ( - - ) : null} - {subtab === "collections" ? ( - - ) : null} - {subtab === "peers" ? ( - - ) : null}
); From cb697088b03e625b68bf75f4fd15d187eefc855f Mon Sep 17 00:00:00 2001 From: Martina Date: Wed, 4 Aug 2021 17:55:03 -0700 Subject: [PATCH 5/7] remove visibility toggle in sidebar --- components/core/CarouselSidebar.js | 131 ----------------------------- 1 file changed, 131 deletions(-) diff --git a/components/core/CarouselSidebar.js b/components/core/CarouselSidebar.js index 2c3151493..c97cca38f 100644 --- a/components/core/CarouselSidebar.js +++ b/components/core/CarouselSidebar.js @@ -518,51 +518,6 @@ class CarouselSidebar extends React.Component { this.props.onNext(); }; - _handleToggleVisibility = async (e) => { - if (this.props.external || !this.props.isOwner || !this.props.viewer) return; - const isPublic = this.props.file.isPublic; - const slateIsPublic = this.props.data?.isPublic; - let selected = cloneDeep(this.state.selected); - - const slateIds = Object.entries(this.state.selected) - .filter((entry) => entry[1]) - .map((entry) => entry[0]); - const publicSlateIds = []; - const publicSlateNames = []; - for (let slate of this.props.viewer.slates) { - if (slate.isPublic && slateIds.includes(slate.id)) { - publicSlateNames.push(slate.data.name); - publicSlateIds.push(slate.id); - selected[slate.id] = false; - } - } - if (publicSlateNames.length) { - const slateNames = publicSlateNames.join(", "); - const message = `Making this file link-viewing only will remove it from the following public collections: ${slateNames}. Do you wish to continue?`; - if (!window.confirm(message)) { - return; - } - } - - if (this.props.carouselType === "SLATE" && slateIsPublic) { - const slateId = this.props.data.id; - let slates = cloneDeep(this.props.viewer.slates); - for (let slate of slates) { - if (slate.id === slateId) { - slate.objects = slate.objects.filter((obj) => obj.id !== this.props.file.id); - break; - } - } - this.props.onAction({ type: "UPDATE_VIEWER", viewer: { slates } }); - } - - let response = await Actions.toggleFilePrivacy({ ...this.props.file, isPublic: !isPublic }); - Events.hasError(response); - if (isPublic) { - this.setState({ selected }); - } - }; - render() { const isPublic = this.props.file.isPublic; const file = this.props.file; @@ -822,74 +777,6 @@ class CarouselSidebar extends React.Component { ); } - let privacy; - if (editingAllowed) { - privacy = ( -
- - Visibility - - - {isPublic - ? `This ${ - isLink ? "link" : "file" - } is currently visible to everyone and searchable within Slate. It may appear in activity feeds and explore.` - : isLink - ? "This link is only visible to you" - : "This file is only visible to those with the link."} - - - - Public -
- ), - }, - { - value: false, - label: ( -
- - Link-viewing only -
- ), - }, - ]} - dark={true} - style={{ marginTop: 12 }} - labelStyle={{ fontFamily: Constants.font.medium }} - selected={isPublic} - onChange={this._handleToggleVisibility} - /> - {!isPublic && !isLink && ( - - )} -
- ); - } - return ( <> {this.state.modalShow && ( @@ -913,7 +800,6 @@ class CarouselSidebar extends React.Component {
{elements}
{actions}
- {privacy} {uploadCoverImage} {!this.props.external && this.props.viewer && ( <> @@ -967,20 +853,3 @@ class CarouselSidebar extends React.Component { } export default withTheme(CarouselSidebar); - -{ - /* <> -
- Visibility -
-
-
{isVisible ? "Everyone" : "Link only"}
- -
-
- {isVisible - ? "This file is currently visible to everyone and searchable within Slate. It may appear in activity feeds and explore." - : "This file is currently not visible to others unless they have the link."} -
- */ -} From c86a738266a7c9dbc979c27b948f99e128a99983 Mon Sep 17 00:00:00 2001 From: Martina Date: Fri, 6 Aug 2021 18:13:45 -0700 Subject: [PATCH 6/7] modified backend to recalculate file privacy upon add/remove from public collection --- common/actions.js | 8 ---- components/sidebars/SidebarCreateSlate.js | 4 +- node_common/data/index.js | 6 +-- .../data/methods/recalc-file-privacy.js | 42 +++++++++++++++++++ ...privacy.js => update-file-privacy[dep].js} | 0 ...-public.js => update-files-public[dep].js} | 0 node_common/utilities.js | 34 +++++++++++++++ pages/api/slates/delete.js | 15 +------ pages/api/slates/remove-file.js | 15 +------ pages/api/slates/update.js | 26 ++---------- pages/api/v2/update-collection.js | 24 +---------- pages/api/v2/update-file.js | 19 --------- 12 files changed, 89 insertions(+), 104 deletions(-) create mode 100644 node_common/data/methods/recalc-file-privacy.js rename node_common/data/methods/{update-file-privacy.js => update-file-privacy[dep].js} (100%) rename node_common/data/methods/{update-files-public.js => update-files-public[dep].js} (100%) diff --git a/common/actions.js b/common/actions.js index 77a683141..c57d0832c 100644 --- a/common/actions.js +++ b/common/actions.js @@ -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`, { diff --git a/components/sidebars/SidebarCreateSlate.js b/components/sidebars/SidebarCreateSlate.js index a05d7c47d..160d14a56 100644 --- a/components/sidebars/SidebarCreateSlate.js +++ b/components/sidebars/SidebarCreateSlate.js @@ -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. { + 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", + }; + }, + }); +}; diff --git a/node_common/data/methods/update-file-privacy.js b/node_common/data/methods/update-file-privacy[dep].js similarity index 100% rename from node_common/data/methods/update-file-privacy.js rename to node_common/data/methods/update-file-privacy[dep].js diff --git a/node_common/data/methods/update-files-public.js b/node_common/data/methods/update-files-public[dep].js similarity index 100% rename from node_common/data/methods/update-files-public.js rename to node_common/data/methods/update-files-public[dep].js diff --git a/node_common/utilities.js b/node_common/utilities.js index 50acc8891..91ae6164e 100644 --- a/node_common/utilities.js +++ b/node_common/utilities.js @@ -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; +}; diff --git a/pages/api/slates/delete.js b/pages/api/slates/delete.js index ac1e979a4..ba3295dd2 100644 --- a/pages/api/slates/delete.js +++ b/pages/api/slates/delete.js @@ -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 }); diff --git a/pages/api/slates/remove-file.js b/pages/api/slates/remove-file.js index ddd04e233..11a7c71c4 100644 --- a/pages/api/slates/remove-file.js +++ b/pages/api/slates/remove-file.js @@ -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 }); diff --git a/pages/api/slates/update.js b/pages/api/slates/update.js index 114eb26b9..bbe0dcbce 100644 --- a/pages/api/slates/update.js +++ b/pages/api/slates/update.js @@ -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"); } diff --git a/pages/api/v2/update-collection.js b/pages/api/v2/update-collection.js index eb1ec5ecc..3f678856e 100644 --- a/pages/api/v2/update-collection.js +++ b/pages/api/v2/update-collection.js @@ -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"); } diff --git a/pages/api/v2/update-file.js b/pages/api/v2/update-file.js index cf91976e1..0b915f8c1 100644 --- a/pages/api/v2/update-file.js +++ b/pages/api/v2/update-file.js @@ -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) { From ee410ba042deb335b4e264a6eedfbfeabb4681a1 Mon Sep 17 00:00:00 2001 From: Martina Date: Fri, 6 Aug 2021 18:43:47 -0700 Subject: [PATCH 7/7] adding forgotten privacy update upon save copy and add to collection --- pages/api/data/save-copy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/api/data/save-copy.js b/pages/api/data/save-copy.js index 0ba4d6b8e..0219fe6fb 100644 --- a/pages/api/data/save-copy.js +++ b/pages/api/data/save-copy.js @@ -108,6 +108,7 @@ export default async (req, res) => { } if (slate?.isPublic) { + Utilities.addToPublicCollectionUpdatePrivacy({ files: filesToAddToSlate }); SearchManager.updateFile(createdFiles, "ADD"); } ViewerManager.hydratePartial(id, { library: true, slates: slate ? true : false });