From 384ad03ac110cee4b4a7f59ec031e1e0b1f144b9 Mon Sep 17 00:00:00 2001 From: Martina Date: Thu, 11 Nov 2021 14:10:53 -0800 Subject: [PATCH] edited previous endpoitns and added v3 endpoitns --- pages/api/v1/get-slate.js | 25 +--- pages/api/v1/get.js | 36 +----- pages/api/v1/update-slate.js | 18 +-- pages/api/v2/create-collection.js | 14 ++- pages/api/v2/create-link.js | 8 +- pages/api/v2/get-collection.js | 9 +- pages/api/v2/get.js | 10 +- pages/api/v2/update-collection.js | 22 ++-- pages/api/v2/update-file.js | 20 ++-- pages/api/v3/create-collection.js | 53 +++++++++ pages/api/v3/create-link.js | 145 ++++++++++++++++++++++++ pages/api/v3/get-collection.js | 42 +++++++ pages/api/{v2/get-user.js => v3/get.js} | 29 +++-- pages/api/v3/update-collection.js | 112 ++++++++++++++++++ pages/api/v3/update-file.js | 48 ++++++++ 15 files changed, 478 insertions(+), 113 deletions(-) create mode 100644 pages/api/v3/create-collection.js create mode 100644 pages/api/v3/create-link.js create mode 100644 pages/api/v3/get-collection.js rename pages/api/{v2/get-user.js => v3/get.js} (52%) create mode 100644 pages/api/v3/update-collection.js create mode 100644 pages/api/v3/update-file.js diff --git a/pages/api/v1/get-slate.js b/pages/api/v1/get-slate.js index 006110d9..d0d5bd30 100644 --- a/pages/api/v1/get-slate.js +++ b/pages/api/v1/get-slate.js @@ -1,8 +1,8 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; -import * as Powergate from "~/node_common/powergate"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -35,28 +35,7 @@ export default async (req, res) => { return res.status(400).send({ decorator: "SLATE_IS_PRIVATE", error: true }); } - //NOTE(martina): convert the new database structure to the old structure - let reformattedObjects = slate.objects.map((file) => { - return { - ...file, - ...file.data, - data: null, - url: Strings.getURLfromCID(file.cid), - }; - }); - - let reformattedSlate = { - id: slate.id, - updated_at: slate.updatedAt, - created_at: slate.createdAt, - slatename: slate.slatename, - data: { - name: slate.data.name, - public: slate.isPublic, - objects: reformattedObjects, - ownerId: slate.ownerId, - }, - }; + let reformattedSlate = Conversions.convertToV1Slate(slate); return res.status(200).send({ decorator: "V1_GET_SLATE", slate: reformattedSlate }); }; diff --git a/pages/api/v1/get.js b/pages/api/v1/get.js index bc8fd038..116cd816 100644 --- a/pages/api/v1/get.js +++ b/pages/api/v1/get.js @@ -1,22 +1,15 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; -import * as Powergate from "~/node_common/powergate"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); if (!userInfo) return; const { id, key, user } = userInfo; - let reformattedUser = { - username: user.username, - data: { - name: user.data.name, - photo: user.data.photo, - body: user.data.body, - }, - }; + let reformattedUser = Conversions.convertToV1User(user); let slates = await Data.getSlatesByUserId({ ownerId: user.id, @@ -38,30 +31,7 @@ export default async (req, res) => { }); } - let reformattedSlates = slates.map((slate) => { - let reformattedObjects = slate.objects.map((file) => { - return { - ...file, - ...file.data, - data: null, - url: Strings.getURLfromCID(file.cid), - }; - }); - - return { - id: slate.id, - updated_at: slate.updatedAt, - created_at: slate.createdAt, - slatename: slate.slatename, - url: `https://slate.host/${user.username}/${slate.slatename}`, - data: { - name: slate.data.name, - public: slate.isPublic, - objects: reformattedObjects, - ownerId: slate.ownerId, - }, - }; - }); + let reformattedSlates = slates.map((slate) => Conversions.convertToV1Slate(slate)); return res .status(200) diff --git a/pages/api/v1/update-slate.js b/pages/api/v1/update-slate.js index eaf2f127..21f1e9db 100644 --- a/pages/api/v1/update-slate.js +++ b/pages/api/v1/update-slate.js @@ -2,9 +2,11 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; import * as Validations from "~/common/validations"; -import SearchManager from "~/node_common/managers/search"; import * as ViewerManager from "~/node_common/managers/viewer"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -40,10 +42,8 @@ export default async (req, res) => { slatename: req.body.data.slatename, isPublic: req.body.data.data.public, updatedAt: new Date(), - data: { - name: req.body.data.data.name, - body: req.body.data.data.body, - }, + name: req.body.data.data.name, + body: req.body.data.data.body, }; if (typeof updates.isPublic !== "undefined" && slate.isPublic !== updates.isPublic) { @@ -73,8 +73,8 @@ export default async (req, res) => { SearchManager.updateFile(updatedFiles); } - if (updates.data.name && updates.data.name !== slate.data.name) { - if (!Validations.slatename(slate.data.name)) { + if (updates.name && updates.name !== slate.name) { + if (!Validations.slatename(slate.name)) { return res.status(400).send({ decorator: "UPDATE_SLATE_INVALID_NAME", error: true, @@ -82,7 +82,7 @@ export default async (req, res) => { } const existingSlate = await Data.getSlateByName({ - slatename: updates.data.name, + slatename: updates.name, ownerId: user.id, }); @@ -92,7 +92,7 @@ export default async (req, res) => { error: true, }); } else { - updates.slatename = Strings.createSlug(updates.data.name); + updates.slatename = Strings.createSlug(updates.name); } } diff --git a/pages/api/v2/create-collection.js b/pages/api/v2/create-collection.js index e7f68c25..f4fcbc03 100644 --- a/pages/api/v2/create-collection.js +++ b/pages/api/v2/create-collection.js @@ -2,9 +2,11 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; import * as ViewerManager from "~/node_common/managers/viewer"; -import SearchManager from "~/node_common/managers/search"; import * as Monitor from "~/node_common/monitor"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -31,10 +33,10 @@ export default async (req, res) => { const slate = await Data.createSlate({ ownerId: id, - slatename: Strings.createSlug(req.body.data.name), + slatename: Strings.createSlug(req.body.data.data.name), isPublic: req.body.data.isPublic, - name: req.body.data.name, - body: req.body.data.body, + name: req.body.data.data.name, + body: req.body.data.data.body, }); if (!slate || slate.error) { @@ -47,5 +49,7 @@ export default async (req, res) => { Monitor.createSlate({ user, slate }); - return res.status(200).send({ decorator: "CREATE_COLLECTION", slate }); + let reformattedSlate = Conversions.convertToV2Slate(slate); + + return res.status(200).send({ decorator: "CREATE_COLLECTION", slate: reformattedSlate }); }; diff --git a/pages/api/v2/create-link.js b/pages/api/v2/create-link.js index 0ccc5f26..fb47b11e 100644 --- a/pages/api/v2/create-link.js +++ b/pages/api/v2/create-link.js @@ -3,10 +3,12 @@ import * as Data from "~/node_common/data"; import * as LinkUtilities from "~/node_common/link-utilities"; import * as Strings from "~/common/strings"; import * as ViewerManager from "~/node_common/managers/viewer"; -import SearchManager from "~/node_common/managers/search"; import * as ArrayUtilities from "~/node_common/array-utilities"; import * as Monitor from "~/node_common/monitor"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -136,8 +138,10 @@ export default async (req, res) => { Monitor.upload({ user, files }); } + let reformattedFiles = filesToAddToSlate.map((file) => Conversions.convertToV2File(file)); + return res.status(200).send({ decorator, - data: filesToAddToSlate, + data: reformattedFiles, }); }; diff --git a/pages/api/v2/get-collection.js b/pages/api/v2/get-collection.js index 5a7f48ee..b2787778 100644 --- a/pages/api/v2/get-collection.js +++ b/pages/api/v2/get-collection.js @@ -1,8 +1,8 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; -import * as Powergate from "~/node_common/powergate"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -10,13 +10,12 @@ export default async (req, res) => { const { id, key, user } = userInfo; let slateId = req.body?.data?.id; - let slate; if (Strings.isEmpty(slateId)) { return res.status(400).send({ decorator: "NO_ID_PROVIDED", error: true }); } - slate = await Data.getSlateById({ id: slateId, includeFiles: true }); + let slate = await Data.getSlateById({ id: slateId, includeFiles: true }); if (!slate) { return res.status(404).send({ @@ -39,5 +38,7 @@ export default async (req, res) => { }); } - return res.status(200).send({ decorator: "GET_COLLECTION", collection: slate }); + let reformattedSlate = Conversions.convertToV2Slate(slate); + + return res.status(200).send({ decorator: "GET_COLLECTION", collection: reformattedSlate }); }; diff --git a/pages/api/v2/get.js b/pages/api/v2/get.js index 0f2852ef..d6c737e7 100644 --- a/pages/api/v2/get.js +++ b/pages/api/v2/get.js @@ -1,14 +1,16 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; -import * as Powergate from "~/node_common/powergate"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); if (!userInfo) return; const { id, key, user } = userInfo; + let reformattedUser = Conversions.convertToV2User(user); + let slates = await Data.getSlatesByUserId({ ownerId: id, includeFiles: true, @@ -33,5 +35,9 @@ export default async (req, res) => { return each; }); - return res.status(200).send({ decorator: "GET", user, collections: slates }); + let reformattedSlates = slates.map((slate) => Conversions.convertToV2Slate(slate)); + + return res + .status(200) + .send({ decorator: "GET", user: reformattedUser, collections: reformattedSlates }); }; diff --git a/pages/api/v2/update-collection.js b/pages/api/v2/update-collection.js index 8e5f5ce2..12693c95 100644 --- a/pages/api/v2/update-collection.js +++ b/pages/api/v2/update-collection.js @@ -1,9 +1,11 @@ import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; import * as Validations from "~/common/validations"; -import SearchManager from "~/node_common/managers/search"; import * as ViewerManager from "~/node_common/managers/viewer"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -39,10 +41,8 @@ export default async (req, res) => { id: req.body.data.id, updatedAt: new Date(), isPublic: req.body.data.isPublic, - data: { - name: req.body.data.data?.name, - body: req.body.data.data?.body, - }, + name: req.body.data.data?.name, + body: req.body.data.data?.body, }; if (typeof updates.isPublic !== "undefined" && slate.isPublic !== updates.isPublic) { @@ -61,8 +61,8 @@ export default async (req, res) => { } } - if (updates.data.name && updates.data.name !== slate.data.name) { - if (!Validations.slatename(slate.data.name)) { + if (updates.name && updates.name !== slate.name) { + if (!Validations.slatename(slate.name)) { return res.status(400).send({ decorator: "INVALID_COLLECTION_NAME", error: true, @@ -70,7 +70,7 @@ export default async (req, res) => { } const existingSlate = await Data.getSlateByName({ - slatename: updates.data.name, + slatename: updates.name, ownerId: user.id, }); @@ -80,7 +80,7 @@ export default async (req, res) => { error: true, }); } else { - updates.slatename = Strings.createSlug(updates.data.name); + updates.slatename = Strings.createSlug(updates.name); } } @@ -108,5 +108,7 @@ export default async (req, res) => { ViewerManager.hydratePartial(user.id, { slates: true }); - return res.status(200).send({ decorator: "UPDATE_COLLECTION", collection: updatedSlate }); + let reformattedSlate = Conversions.convertToV2Slate(updatedSlate); + + return res.status(200).send({ decorator: "UPDATE_COLLECTION", collection: reformattedSlate }); }; diff --git a/pages/api/v2/update-file.js b/pages/api/v2/update-file.js index 30e27f4c..233a5409 100644 --- a/pages/api/v2/update-file.js +++ b/pages/api/v2/update-file.js @@ -1,8 +1,10 @@ import * as Strings from "~/common/strings"; import * as Data from "~/node_common/data"; -import SearchManager from "~/node_common/managers/search"; import * as ViewerManager from "~/node_common/managers/viewer"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); @@ -16,10 +18,8 @@ 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, - data: { - name: req.body.data.data?.name, - body: req.body.data.data?.body, - }, + name: req.body.data.data?.name, + body: req.body.data.data?.body, }; const file = await Data.getFileById({ id: updates.id }); @@ -31,18 +31,20 @@ export default async (req, res) => { }); } - let response = await Data.updateFileById(updates); + let updatedFile = await Data.updateFileById(updates); - if (!response || response.error) { + if (!updatedFile || updatedFile.error) { return res.status(500).send({ decorator: "UPDATE_FILE_FAILED", error: true }); } - SearchManager.updateFile(response); + SearchManager.updateFile(updatedFile); ViewerManager.hydratePartial(user.id, { library: true, slates: true }); + let reformattedFile = Conversions.convertToV2File(updatedFile); + return res.status(200).send({ decorator: "UPDATE_FILE", - file: response, + file: reformattedFile, }); }; diff --git a/pages/api/v3/create-collection.js b/pages/api/v3/create-collection.js new file mode 100644 index 00000000..13bdd621 --- /dev/null +++ b/pages/api/v3/create-collection.js @@ -0,0 +1,53 @@ +import * as Utilities from "~/node_common/utilities"; +import * as Data from "~/node_common/data"; +import * as Strings from "~/common/strings"; +import * as ViewerManager from "~/node_common/managers/viewer"; +import * as Monitor from "~/node_common/monitor"; +import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; + +export default async (req, res) => { + const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); + if (!userInfo) return; + const { id, key, user } = userInfo; + + if (!req.body?.data?.name) { + return res.status(500).send({ + decorator: "MUST_PROVIDE_DATA", + error: true, + }); + } + + const slatename = Strings.createSlug(req.body.data.name); + + const existingSlate = await Data.getSlateByName({ + slatename, + ownerId: user.id, + }); + + if (existingSlate) { + return res.status(500).send({ decorator: "EXISTING_SLATE_NAME", error: true }); + } + + const slate = await Data.createSlate({ + ownerId: id, + slatename: Strings.createSlug(req.body.data.name), + isPublic: req.body.data.isPublic, + name: req.body.data.name, + body: req.body.data.body, + }); + + if (!slate || slate.error) { + return res.status(500).send({ decorator: "CREATE_COLLECTION_FAILED", error: true }); + } + + ViewerManager.hydratePartial(id, { slates: true }); + + SearchManager.indexSlate(slate); + + Monitor.createSlate({ user, slate }); + + return res.status(200).send({ decorator: "CREATE_COLLECTION", slate }); +}; diff --git a/pages/api/v3/create-link.js b/pages/api/v3/create-link.js new file mode 100644 index 00000000..8a046e1f --- /dev/null +++ b/pages/api/v3/create-link.js @@ -0,0 +1,145 @@ +import * as Utilities from "~/node_common/utilities"; +import * as Data from "~/node_common/data"; +import * as LinkUtilities from "~/node_common/link-utilities"; +import * as Strings from "~/common/strings"; +import * as ViewerManager from "~/node_common/managers/viewer"; +import * as ArrayUtilities from "~/node_common/array-utilities"; +import * as Monitor from "~/node_common/monitor"; +import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; + +export default async (req, res) => { + const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); + if (!userInfo) return; + const { id, key, user } = userInfo; + + let decorator = "SERVER_CREATE_LINK"; + const slateId = req.body.data.slate?.id; + let slate; + if (slateId) { + slate = await Data.getSlateById({ id: slateId }); + + if (!slate || slate.error) { + slate = null; + decorator = "SLATE_NOT_FOUND"; + } + } + + let urls; + if (req.body?.data?.url) { + urls = [req.body.data.url]; + } else if (req.body?.data?.urls) { + urls = req.body.data.urls; + } else { + return res.status(400).send({ decorator: "NO_LINK_PROVIDED", error: true }); + } + + let files = []; + for (let url of urls) { + const cid = await LinkUtilities.getCIDofString(url); + files.push({ cid, url }); + } + + let { duplicateFiles, filteredFiles } = await ArrayUtilities.removeDuplicateUserFiles({ + files, + user, + }); + + if (!filteredFiles?.length) { + return res.status(200).send({ decorator: "LINK_DUPLICATE", data: duplicateFiles }); + } + + files = []; + + for (let file of filteredFiles) { + const url = file.url; + const data = await LinkUtilities.fetchLinkData(url); + if (!data) { + continue; + } + + const filename = Strings.createSlug(data.title); + + const domain = LinkUtilities.getDomainFromURL(url); + + const html = await LinkUtilities.fetchEmbed(url); + + const iFrameAllowed = await LinkUtilities.testIframe(url); + + const newFile = { + filename, + cid: file.cid, + isLink: true, + url: file.url, + type: "link", + name: data.title, + body: data.description, + linkName: data.title, + linkBody: data.description, + linkSource: data.publisher, + linkAuthor: data.author, + linkImage: data.image?.url, + linkFavicon: data.logo?.url, + linkDomain: domain, + linkHtml: html, + linkIFrameAllowed: iFrameAllowed, + }; + + files.push(newFile); + } + + if (!files?.length) { + return res.status(400).send({ decorator: "SERVER_CREATE_LINK_INVALID_LINK", error: true }); + } + + if (slate?.isPublic) { + files = files.map((file) => { + return { ...file, isPublic: true }; + }); + } + + let createdFiles = []; + if (files?.length) { + createdFiles = (await Data.createFile({ owner: user, files })) || []; + + if (!createdFiles?.length) { + return res.status(404).send({ decorator: "SERVER_CREATE_LINK_FAILED", error: true }); + } + + if (createdFiles.error) { + return res.status(500).send({ decorator: createdFiles.decorator, error: createdFiles.error }); + } + } + + // for (let file of createdFiles) { + // LinkUtilities.uploadScreenshot(file, user); + // } + + let filesToAddToSlate = createdFiles.concat(duplicateFiles); //NOTE(martina): files that are already owned by the user are included in case they aren't yet in that specific slate + if (slate && filesToAddToSlate.length) { + const { decorator: returnedDecorator, added: addedToSlate } = await Utilities.addToSlate({ + slate, + files: filesToAddToSlate, + user, + }); + if (returnedDecorator) { + decorator = returnedDecorator; + } + added = addedToSlate; + } + + SearchManager.indexFile(createdFiles); + + ViewerManager.hydratePartial(id, { library: true, slates: slate ? true : false }); + + if (!slate) { + Monitor.upload({ user, files }); + } + + return res.status(200).send({ + decorator, + data: filesToAddToSlate, + }); +}; diff --git a/pages/api/v3/get-collection.js b/pages/api/v3/get-collection.js new file mode 100644 index 00000000..1ff8378b --- /dev/null +++ b/pages/api/v3/get-collection.js @@ -0,0 +1,42 @@ +import * as Utilities from "~/node_common/utilities"; +import * as Data from "~/node_common/data"; +import * as Strings from "~/common/strings"; +import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +export default async (req, res) => { + const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); + if (!userInfo) return; + const { id, key, user } = userInfo; + + let slateId = req.body?.data?.id; + + if (Strings.isEmpty(slateId)) { + return res.status(400).send({ decorator: "NO_ID_PROVIDED", error: true }); + } + + let slate = await Data.getSlateById({ id: slateId, includeFiles: true }); + + if (!slate) { + return res.status(404).send({ + decorator: "COLLECTION_NOT_FOUND", + error: true, + }); + } + + if (slate.error) { + return res.status(500).send({ + decorator: "ERROR_WHILE_LOCATING_COLLECTION", + error: true, + }); + } + + if (!slate.isPublic) { + return res.status(400).send({ + decorator: "COLLECTION_IS_PRIVATE", + error: true, + }); + } + + return res.status(200).send({ decorator: "GET_COLLECTION", collection: slate }); +}; diff --git a/pages/api/v2/get-user.js b/pages/api/v3/get.js similarity index 52% rename from pages/api/v2/get-user.js rename to pages/api/v3/get.js index 557d0bfc..a2d10b82 100644 --- a/pages/api/v2/get-user.js +++ b/pages/api/v3/get.js @@ -1,40 +1,37 @@ import * as Utilities from "~/node_common/utilities"; import * as Data from "~/node_common/data"; import * as Strings from "~/common/strings"; -import * as Powergate from "~/node_common/powergate"; import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; export default async (req, res) => { const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); if (!userInfo) return; const { id, key, user } = userInfo; - let userId = req.body?.data?.id; - - if (Strings.isEmpty(userId)) { - return res.status(400).send({ decorator: "NO_USER_ID_PROVIDED", error: true }); - } - - let targetUser = await Data.getUserById({ - id: userId, - sanitize: true, - publicOnly: true, + let slates = await Data.getSlatesByUserId({ + ownerId: id, includeFiles: true, }); - if (!targetUser) { + if (!slates) { return res.status(404).send({ - decorator: "USER_NOT_FOUND", + decorator: "COULD_NOT_FETCH_COLLECTIONS", error: true, }); } - if (targetUser.error) { + if (slates.error) { return res.status(500).send({ - decorator: "USER_NOT_FOUND", + decorator: "COULD_NOT_FETCH_COLLECTIONS", error: true, }); } - return res.status(200).send({ decorator: "GET_USER", user: targetUser }); + slates = slates.map((each) => { + each.data.url = `https://slate.host/${user.username}/${each.slatename}`; + return each; + }); + + return res.status(200).send({ decorator: "GET", user, collections: slates }); }; diff --git a/pages/api/v3/update-collection.js b/pages/api/v3/update-collection.js new file mode 100644 index 00000000..83d90a46 --- /dev/null +++ b/pages/api/v3/update-collection.js @@ -0,0 +1,112 @@ +import * as Data from "~/node_common/data"; +import * as Strings from "~/common/strings"; +import * as Validations from "~/common/validations"; +import * as ViewerManager from "~/node_common/managers/viewer"; +import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; + +export default async (req, res) => { + const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); + if (!userInfo) return; + const { id, key, user } = userInfo; + + if (!req.body?.data?.id) { + return res.status(500).send({ + decorator: "UPDATE_COLLECTION_MUST_PROVIDE_DATA", + error: true, + }); + } + + const slate = await Data.getSlateById({ id: req.body.data.id, includeFiles: true }); + + if (!slate) { + return res.status(404).send({ decorator: "COLLECTION_NOT_FOUND", error: true }); + } + + if (slate.error) { + return res.status(500).send({ decorator: "COLLECTION_NOT_FOUND", error: true }); + } + + if (slate.ownerId !== user.id) { + return res.status(400).send({ + decorator: "NOT_COLLECTION_OWNER_UPDATE_NOT_PERMITTED", + error: true, + }); + } + + //NOTE(martina): cleans the input to remove fields they should not be changing like ownerId, createdAt, etc. + let updates = { + id: req.body.data.id, + updatedAt: new Date(), + isPublic: req.body.data.isPublic, + name: req.body.data.name, + body: req.body.data.body, + }; + + if (typeof updates.isPublic !== "undefined" && slate.isPublic !== updates.isPublic) { + let privacyResponse = await Data.updateSlatePrivacy({ + ownerId: user.id, + id: updates.id, + isPublic: updates.isPublic, + }); + + if (!privacyResponse) { + return res.status(404).send({ decorator: "UPDATE_COLLECTION_PRIVACY_FAILED", error: true }); + } + + if (privacyResponse.error) { + return res.status(500).send({ decorator: "UPDATE_COLLECTION_PRIVACY_FAILED", error: true }); + } + } + + if (updates.name && updates.name !== slate.name) { + if (!Validations.slatename(slate.name)) { + return res.status(400).send({ + decorator: "INVALID_COLLECTION_NAME", + error: true, + }); + } + + const existingSlate = await Data.getSlateByName({ + slatename: updates.name, + ownerId: user.id, + }); + + if (existingSlate) { + return res.status(500).send({ + decorator: "COLLECTION_NAME_TAKEN", + error: true, + }); + } else { + updates.slatename = Strings.createSlug(updates.name); + } + } + + let updatedSlate = await Data.updateSlateById(updates); + + if (!updatedSlate) { + return res.status(404).send({ decorator: "UPDATE_COLLECTION_FAILED", error: true }); + } + + if (updatedSlate.error) { + return res.status(500).send({ decorator: "UPDATE_COLLECTION_FAILED", error: true }); + } + + let updatedFiles; + if (slate.isPublic && !updates.isPublic) { + updatedFiles = await Utilities.removeFromPublicCollectionUpdatePrivacy({ + files: slate.objects, + }); + } else if (!slate.isPublic && updates.isPublic) { + updatedFiles = await Utilities.addToPublicCollectionUpdatePrivacy({ files: slate.objects }); + } + SearchManager.updateFile(updatedFiles); + + SearchManager.updateSlate(updatedSlate); + + ViewerManager.hydratePartial(user.id, { slates: true }); + + return res.status(200).send({ decorator: "UPDATE_COLLECTION", collection: updatedSlate }); +}; diff --git a/pages/api/v3/update-file.js b/pages/api/v3/update-file.js new file mode 100644 index 00000000..f7537cbc --- /dev/null +++ b/pages/api/v3/update-file.js @@ -0,0 +1,48 @@ +import * as Strings from "~/common/strings"; +import * as Data from "~/node_common/data"; +import * as ViewerManager from "~/node_common/managers/viewer"; +import * as RequestUtilities from "~/node_common/request-utilities"; +import * as Conversions from "~/common/conversions"; + +import SearchManager from "~/node_common/managers/search"; + +export default async (req, res) => { + const userInfo = await RequestUtilities.checkAuthorizationExternal(req, res); + if (!userInfo) return; + const { id, key, user } = userInfo; + + if (!req.body?.data?.id) { + return res.status(500).send({ decorator: "NO_FILE_ID_PROVIDED", error: true }); + } + + //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, + name: req.body.data.name, + body: req.body.data.body, + }; + + const file = await Data.getFileById({ id: updates.id }); + + if (file.ownerId !== user.id) { + return res.status(400).send({ + decorator: "NOT_FILE_OWNER_UPDATE_NOT_PERMITTED", + error: true, + }); + } + + let response = await Data.updateFileById(updates); + + if (!response || response.error) { + return res.status(500).send({ decorator: "UPDATE_FILE_FAILED", error: true }); + } + + SearchManager.updateFile(response); + + ViewerManager.hydratePartial(user.id, { library: true, slates: true }); + + return res.status(200).send({ + decorator: "UPDATE_FILE", + file: response, + }); +};