From 88acf86941260b6066f99eaf209ddef377794125 Mon Sep 17 00:00:00 2001 From: Root Date: Wed, 13 Mar 2024 02:13:41 +0100 Subject: [PATCH] Revert disable post import for security reasons --- .../processors/db/import-firefish-post.ts | 36 ++++++++++ .../queue/processors/db/import-masto-post.ts | 72 +++++++++++++++++++ .../server/api/endpoints/i/import-posts.ts | 15 +++- .../src/pages/settings/import-export.vue | 28 ++++++++ 4 files changed, 149 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/queue/processors/db/import-firefish-post.ts b/packages/backend/src/queue/processors/db/import-firefish-post.ts index c7a6fd7f0..504cf9e50 100644 --- a/packages/backend/src/queue/processors/db/import-firefish-post.ts +++ b/packages/backend/src/queue/processors/db/import-firefish-post.ts @@ -11,5 +11,41 @@ export async function importCkPost( job: Bull.Job, done: any, ): Promise { + const user = await Users.findOneBy({ id: job.data.user.id }); + if (user == null) { + done(); + return; + } + const post = job.data.post; + if (post.replyId != null) { + done(); + return; + } + if (post.renoteId != null) { + done(); + return; + } + if (post.visibility !== "public") { + done(); + return; + } + const { text, cw, localOnly, createdAt } = Post.parse(post); + const note = await create(user, { + createdAt: createdAt, + files: undefined, + poll: undefined, + text: text || undefined, + reply: null, + renote: null, + cw: cw, + localOnly, + visibility: "hidden", + visibleUsers: [], + channel: null, + apMentions: new Array(0), + apHashtags: undefined, + apEmojis: undefined, + }); + logger.succ("Imported"); done(); } diff --git a/packages/backend/src/queue/processors/db/import-masto-post.ts b/packages/backend/src/queue/processors/db/import-masto-post.ts index c6ac7346b..bbab4ece3 100644 --- a/packages/backend/src/queue/processors/db/import-masto-post.ts +++ b/packages/backend/src/queue/processors/db/import-masto-post.ts @@ -15,5 +15,77 @@ export async function importMastoPost( job: Bull.Job, done: any, ): Promise { + const user = await Users.findOneBy({ id: job.data.user.id }); + if (user == null) { + done(); + return; + } + const post = job.data.post; + let reply: Note | null = null; + job.progress(20); + if (post.object.inReplyTo != null) { + reply = await resolveNote(post.object.inReplyTo); + } + job.progress(40); + if (post.directMessage) { + done(); + return; + } + if (job.data.signatureCheck) { + if (!post.signature) { + done(); + return; + } + } + job.progress(60); + let text; + try { + text = await htmlToMfm(post.object.content, post.object.tag); + } catch (e) { + throw e; + } + job.progress(80); + + let files: DriveFile[] = (post.object.attachment || []) + .map((x: any) => x?.driveFile) + .filter((x: any) => x); + + if (files.length == 0) { + const urls = post.object.attachment + .map((x: any) => x.url) + .filter((x: String) => x.startsWith("http")); + files = []; + for (const url of urls) { + try { + const file = await uploadFromUrl({ + url: url, + user: user, + }); + files.push(file); + } catch (e) { + logger.error(`Skipped adding file to drive: ${url}`); + } + } + } + + const note = await create(user, { + createdAt: new Date(post.object.published), + files: files.length == 0 ? undefined : files, + poll: undefined, + text: text || undefined, + reply, + renote: null, + cw: post.object.sensitive ? post.object.summary : undefined, + localOnly: false, + visibility: "hidden", + visibleUsers: [], + channel: null, + apMentions: new Array(0), + apHashtags: undefined, + apEmojis: undefined, + }); + job.progress(100); done(); + + logger.succ("Imported"); } diff --git a/packages/backend/src/server/api/endpoints/i/import-posts.ts b/packages/backend/src/server/api/endpoints/i/import-posts.ts index a4cfa4101..3adba0514 100644 --- a/packages/backend/src/server/api/endpoints/i/import-posts.ts +++ b/packages/backend/src/server/api/endpoints/i/import-posts.ts @@ -1,6 +1,9 @@ import define from "../../define.js"; +import { createImportPostsJob } from "@/queue/index.js"; import { ApiError } from "../../error.js"; +import { DriveFiles } from "@/models/index.js"; import { DAY } from "@/const.js"; +import { fetchMeta } from "@/misc/fetch-meta.js"; export const meta = { secure: true, @@ -23,7 +26,7 @@ export const meta = { }, importsDisabled: { - message: "Post imports are disabled for security reasons.", + message: "Post imports are disabled.", code: "IMPORTS_DISABLED", id: " bc9227e4-fb82-11ed-be56-0242ac120002", }, @@ -40,5 +43,13 @@ export const paramDef = { } as const; export default define(meta, paramDef, async (ps, user) => { - throw new ApiError(meta.errors.importsDisabled); + const file = await DriveFiles.findOneBy({ id: ps.fileId }); + + const instanceMeta = await fetchMeta(); + if (instanceMeta.experimentalFeatures?.postImports === false) + throw new ApiError(meta.errors.importsDisabled); + + if (file == null) throw new ApiError(meta.errors.noSuchFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + createImportPostsJob(user, file.id, ps.signatureCheck); }); diff --git a/packages/client/src/pages/settings/import-export.vue b/packages/client/src/pages/settings/import-export.vue index 8ffe50ebf..836daea36 100644 --- a/packages/client/src/pages/settings/import-export.vue +++ b/packages/client/src/pages/settings/import-export.vue @@ -16,6 +16,24 @@ {{ i18n.ts.export }} + + + + + + + + + {{ i18n.ts.import }} +