@@ -58,7 +58,7 @@
|
||||
"@tippy.js/react": "^2.2.2",
|
||||
"@tommoor/remove-markdown": "^0.3.2",
|
||||
"autotrack": "^2.4.1",
|
||||
"aws-sdk": "^2.831.0",
|
||||
"aws-sdk": "^2.1044.0",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"babel-plugin-styled-components": "^1.11.1",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
|
||||
@@ -7,6 +7,7 @@ import accountProvisioner from "./accountProvisioner";
|
||||
jest.mock("../mailer");
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
putObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import documentPermanentDeleter from "./documentPermanentDeleter";
|
||||
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import fileOperationDeleter from "./fileOperationDeleter";
|
||||
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import teamCreator from "./teamCreator";
|
||||
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
putObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ import teamPermanentDeleter from "./teamPermanentDeleter";
|
||||
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ const app = webService();
|
||||
const server = new TestServer(app.callback());
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { format } from "date-fns";
|
||||
import Router from "koa-router";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { NotFoundError } from "@server/errors";
|
||||
@@ -6,10 +5,8 @@ import auth from "@server/middlewares/authentication";
|
||||
import { Attachment, Document, Event } from "@server/models";
|
||||
import policy from "@server/policies";
|
||||
import {
|
||||
makePolicy,
|
||||
getSignature,
|
||||
getPresignedPost,
|
||||
publicS3Endpoint,
|
||||
makeCredential,
|
||||
getSignedUrl,
|
||||
} from "@server/utils/s3";
|
||||
import { assertPresent } from "@server/validation";
|
||||
@@ -34,9 +31,7 @@ router.post("attachments.create", auth(), async (ctx) => {
|
||||
: "private";
|
||||
const bucket = acl === "public-read" ? "public" : "uploads";
|
||||
const key = `${bucket}/${user.id}/${s3Key}/${name}`;
|
||||
const credential = makeCredential();
|
||||
const longDate = format(new Date(), "yyyyMMdd'T'HHmmss'Z'");
|
||||
const policy = makePolicy(credential, longDate, acl, contentType);
|
||||
const presignedPost = await getPresignedPost(key, acl, contentType);
|
||||
const endpoint = publicS3Endpoint();
|
||||
const url = `${endpoint}/${key}`;
|
||||
|
||||
@@ -73,13 +68,7 @@ router.post("attachments.create", auth(), async (ctx) => {
|
||||
form: {
|
||||
"Cache-Control": "max-age=31557600",
|
||||
"Content-Type": contentType,
|
||||
acl,
|
||||
key,
|
||||
policy,
|
||||
"x-amz-algorithm": "AWS4-HMAC-SHA256",
|
||||
"x-amz-credential": credential,
|
||||
"x-amz-date": longDate,
|
||||
"x-amz-signature": getSignature(policy),
|
||||
...presignedPost.fields,
|
||||
},
|
||||
attachment: {
|
||||
documentId,
|
||||
|
||||
@@ -15,6 +15,7 @@ const app = webService();
|
||||
const server = new TestServer(app.callback());
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ const app = webService();
|
||||
const server = new TestServer(app.callback());
|
||||
jest.mock("aws-sdk", () => {
|
||||
const mS3 = {
|
||||
createPresignedPost: jest.fn(),
|
||||
deleteObject: jest.fn().mockReturnThis(),
|
||||
promise: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import crypto from "crypto";
|
||||
import util from "util";
|
||||
import AWS from "aws-sdk";
|
||||
import { addHours, format } from "date-fns";
|
||||
import fetch from "fetch-with-proxy";
|
||||
@@ -24,6 +25,10 @@ const s3 = new AWS.S3({
|
||||
new AWS.Endpoint(process.env.AWS_S3_UPLOAD_BUCKET_URL),
|
||||
signatureVersion: "v4",
|
||||
});
|
||||
const createPresignedPost = util.promisify<
|
||||
AWS.S3.PresignedPost.Params,
|
||||
AWS.S3.PresignedPost
|
||||
>(s3.createPresignedPost);
|
||||
|
||||
const hmac = (
|
||||
key: string | Buffer,
|
||||
@@ -93,6 +98,29 @@ export const getSignature = (policy: string) => {
|
||||
return signature;
|
||||
};
|
||||
|
||||
export const getPresignedPost = (
|
||||
key: string,
|
||||
acl: string,
|
||||
contentType = "image"
|
||||
) => {
|
||||
const params = {
|
||||
Bucket: process.env.AWS_S3_UPLOAD_BUCKET_NAME,
|
||||
Conditions: [
|
||||
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
|
||||
["content-length-range", 0, +process.env.AWS_S3_UPLOAD_MAX_SIZE],
|
||||
["starts-with", "$Content-Type", contentType],
|
||||
["starts-with", "$Cache-Control", ""],
|
||||
],
|
||||
Fields: {
|
||||
key,
|
||||
acl,
|
||||
},
|
||||
Expires: 3600,
|
||||
};
|
||||
|
||||
return createPresignedPost(params);
|
||||
};
|
||||
|
||||
export const publicS3Endpoint = (isServerUpload?: boolean) => {
|
||||
// lose trailing slash if there is one and convert fake-s3 url to localhost
|
||||
// for access outside of docker containers in local development
|
||||
|
||||
@@ -4060,10 +4060,10 @@ autotrack@^2.4.1:
|
||||
rollup-plugin-node-resolve "^3.0.0"
|
||||
source-map "^0.5.6"
|
||||
|
||||
aws-sdk@^2.831.0:
|
||||
version "2.831.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.831.0.tgz#02607cc911a2136e5aabe624c1282e821830aef2"
|
||||
integrity sha512-lrOjbGFpjk2xpESyUx2PGsTZgptCy5xycZazPeakNbFO19cOoxjHx3xyxOHsMCYb3pQwns35UvChQT60B4u6cw==
|
||||
aws-sdk@^2.1044.0:
|
||||
version "2.1044.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1044.0.tgz#0708eaf48daf8d961b414e698d84e8cd1f82c4ad"
|
||||
integrity sha512-n55uGUONQGXteGGG1QlZ1rKx447KSuV/x6jUGNf2nOl41qMI8ZgLUhNUt0uOtw3qJrCTanzCyR/JKBq2PMiqEQ==
|
||||
dependencies:
|
||||
buffer "4.9.2"
|
||||
events "1.1.1"
|
||||
|
||||
Reference in New Issue
Block a user