fix: Links to attachments do not work in emailed notifications (#5935)
This commit is contained in:
@@ -19,9 +19,7 @@ import {
|
||||
import attachmentCreator from "@server/commands/attachmentCreator";
|
||||
import { parser, schema } from "@server/editor";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import type Document from "@server/models/Document";
|
||||
import type Revision from "@server/models/Revision";
|
||||
import User from "@server/models/User";
|
||||
import { Document, Revision, User } from "@server/models";
|
||||
import FileStorage from "@server/storage/files";
|
||||
import diff from "@server/utils/diff";
|
||||
import parseAttachmentIds from "@server/utils/parseAttachmentIds";
|
||||
@@ -112,10 +110,19 @@ export default class DocumentHelper {
|
||||
centered: options?.centered,
|
||||
});
|
||||
|
||||
if (options?.signedUrls && "teamId" in document) {
|
||||
if (options?.signedUrls) {
|
||||
const teamId =
|
||||
document instanceof Document
|
||||
? document.teamId
|
||||
: (await document.$get("document"))?.teamId;
|
||||
|
||||
if (!teamId) {
|
||||
return output;
|
||||
}
|
||||
|
||||
output = await DocumentHelper.attachmentsToSignedUrls(
|
||||
output,
|
||||
document.teamId,
|
||||
teamId,
|
||||
typeof options.signedUrls === "number" ? options.signedUrls : undefined
|
||||
);
|
||||
}
|
||||
@@ -145,10 +152,10 @@ export default class DocumentHelper {
|
||||
static async diff(
|
||||
before: Document | Revision | null,
|
||||
after: Revision,
|
||||
options?: HTMLOptions
|
||||
{ signedUrls, ...options }: HTMLOptions = {}
|
||||
) {
|
||||
if (!before) {
|
||||
return await DocumentHelper.toHTML(after, options);
|
||||
return await DocumentHelper.toHTML(after, { ...options, signedUrls });
|
||||
}
|
||||
|
||||
const beforeHTML = await DocumentHelper.toHTML(before, options);
|
||||
@@ -158,11 +165,27 @@ export default class DocumentHelper {
|
||||
|
||||
// Extract the content from the article tag and diff the HTML, we don't
|
||||
// care about the surrounding layout and stylesheets.
|
||||
const diffedContentAsHTML = diff(
|
||||
let diffedContentAsHTML = diff(
|
||||
beforeDOM.window.document.getElementsByTagName("article")[0].innerHTML,
|
||||
afterDOM.window.document.getElementsByTagName("article")[0].innerHTML
|
||||
);
|
||||
|
||||
// Sign only the URLS in the diffed content
|
||||
if (signedUrls) {
|
||||
const teamId =
|
||||
before instanceof Document
|
||||
? before.teamId
|
||||
: (await before.$get("document"))?.teamId;
|
||||
|
||||
if (teamId) {
|
||||
diffedContentAsHTML = await DocumentHelper.attachmentsToSignedUrls(
|
||||
diffedContentAsHTML,
|
||||
teamId,
|
||||
typeof signedUrls === "number" ? signedUrls : undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Inject the diffed content into the original document with styling and
|
||||
// serialize back to a string.
|
||||
const article = beforeDOM.window.document.querySelector("article");
|
||||
@@ -318,6 +341,7 @@ export default class DocumentHelper {
|
||||
expiresIn = 3000
|
||||
) {
|
||||
const attachmentIds = parseAttachmentIds(text);
|
||||
|
||||
await Promise.all(
|
||||
attachmentIds.map(async (id) => {
|
||||
const attachment = await Attachment.findOne({
|
||||
@@ -332,6 +356,7 @@ export default class DocumentHelper {
|
||||
attachment.key,
|
||||
expiresIn
|
||||
);
|
||||
|
||||
text = text.replace(
|
||||
new RegExp(escapeRegExp(attachment.redirectUrl), "g"),
|
||||
signedUrl
|
||||
|
||||
@@ -114,7 +114,7 @@ export default class LocalStorage extends BaseStorage {
|
||||
expiresIn,
|
||||
}
|
||||
);
|
||||
return Promise.resolve(`/api/files.get?sig=${sig}`);
|
||||
return Promise.resolve(`${env.URL}/api/files.get?sig=${sig}`);
|
||||
};
|
||||
|
||||
public getFileStream(key: string) {
|
||||
|
||||
@@ -249,6 +249,17 @@ const findAndReplaceStyle = () => css`
|
||||
}
|
||||
`;
|
||||
|
||||
const emailStyle = (props: Props) => css`
|
||||
.attachment {
|
||||
display: block;
|
||||
color: ${props.theme.text} !important;
|
||||
box-shadow: 0 0 0 1px ${props.theme.divider};
|
||||
white-space: nowrap;
|
||||
border-radius: 8px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
const style = (props: Props) => `
|
||||
flex-grow: ${props.grow ? 1 : 0};
|
||||
justify-content: start;
|
||||
@@ -1546,6 +1557,7 @@ const EditorContainer = styled.div<Props>`
|
||||
${codeMarkCursor}
|
||||
${codeBlockStyle}
|
||||
${findAndReplaceStyle}
|
||||
${emailStyle}
|
||||
`;
|
||||
|
||||
export default EditorContainer;
|
||||
|
||||
@@ -29,6 +29,7 @@ function isAttachment(token: Token) {
|
||||
// external (public share are pre-signed and this is a reasonable way of detecting them)
|
||||
href?.startsWith("/api/attachments.redirect") ||
|
||||
href?.startsWith("/api/files.get") ||
|
||||
href?.startsWith(`${env.URL}/api/files.get`) ||
|
||||
((href?.startsWith(env.AWS_S3_UPLOAD_BUCKET_URL) ||
|
||||
href?.startsWith(env.AWS_S3_ACCELERATE_URL)) &&
|
||||
href?.includes("X-Amz-Signature"))
|
||||
|
||||
Reference in New Issue
Block a user