Allow file access not in Attachments table (#5876)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,14 +1,19 @@
|
||||
import JWT from "jsonwebtoken";
|
||||
import Router from "koa-router";
|
||||
import mime from "mime-types";
|
||||
import env from "@server/env";
|
||||
import { ValidationError } from "@server/errors";
|
||||
import { AuthenticationError, ValidationError } from "@server/errors";
|
||||
import auth from "@server/middlewares/authentication";
|
||||
import multipart from "@server/middlewares/multipart";
|
||||
import { rateLimiter } from "@server/middlewares/rateLimiter";
|
||||
import validate from "@server/middlewares/validate";
|
||||
import { Attachment } from "@server/models";
|
||||
import AttachmentHelper from "@server/models/helpers/AttachmentHelper";
|
||||
import { authorize } from "@server/policies";
|
||||
import FileStorage from "@server/storage/files";
|
||||
import { APIContext } from "@server/types";
|
||||
import { RateLimiterStrategy } from "@server/utils/RateLimiter";
|
||||
import { getJWTPayload } from "@server/utils/jwt";
|
||||
import { createRootDirForLocalStorage } from "../utils";
|
||||
import * as T from "./schema";
|
||||
|
||||
@@ -27,7 +32,10 @@ router.post(
|
||||
const { key } = ctx.input.body;
|
||||
const file = ctx.input.file;
|
||||
|
||||
const attachment = await Attachment.findByKey(key);
|
||||
const attachment = await Attachment.findOne({
|
||||
where: { key },
|
||||
rejectOnEmpty: true,
|
||||
});
|
||||
|
||||
if (attachment.isPrivate) {
|
||||
authorize(actor, "createAttachment", actor.team);
|
||||
@@ -46,26 +54,60 @@ router.get(
|
||||
auth({ optional: true }),
|
||||
validate(T.FilesGetSchema),
|
||||
async (ctx: APIContext<T.FilesGetReq>) => {
|
||||
const { key, sig } = ctx.input.query;
|
||||
const actor = ctx.state.auth.user;
|
||||
let attachment: Attachment | null;
|
||||
const key = getKeyFromContext(ctx);
|
||||
const isSignedRequest = !!ctx.input.query.sig;
|
||||
const { isPublicBucket, fileName } = AttachmentHelper.parseKey(key);
|
||||
const skipAuthorize = isPublicBucket || isSignedRequest;
|
||||
const cacheHeader = "max-age=604800, immutable";
|
||||
|
||||
if (key) {
|
||||
attachment = await Attachment.findByKey(key);
|
||||
|
||||
if (attachment.isPrivate) {
|
||||
authorize(actor, "read", attachment);
|
||||
}
|
||||
} else if (sig) {
|
||||
attachment = await Attachment.findBySignature(sig);
|
||||
if (skipAuthorize) {
|
||||
ctx.set("Cache-Control", cacheHeader);
|
||||
ctx.set(
|
||||
"Content-Type",
|
||||
(fileName ? mime.lookup(fileName) : undefined) ||
|
||||
"application/octet-stream"
|
||||
);
|
||||
ctx.attachment(fileName);
|
||||
ctx.body = FileStorage.getFileStream(key);
|
||||
} else {
|
||||
throw ValidationError("Must provide either key or signature");
|
||||
}
|
||||
const attachment = await Attachment.findOne({
|
||||
where: { key },
|
||||
rejectOnEmpty: true,
|
||||
});
|
||||
authorize(actor, "read", attachment);
|
||||
|
||||
ctx.set("Content-Type", attachment.contentType);
|
||||
ctx.attachment(attachment.name);
|
||||
ctx.body = attachment.stream;
|
||||
ctx.set("Cache-Control", cacheHeader);
|
||||
ctx.set("Content-Type", attachment.contentType);
|
||||
ctx.attachment(attachment.name);
|
||||
ctx.body = attachment.stream;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function getKeyFromContext(ctx: APIContext<T.FilesGetReq>): string {
|
||||
const { key, sig } = ctx.input.query;
|
||||
if (sig) {
|
||||
const payload = getJWTPayload(sig);
|
||||
|
||||
if (payload.type !== "attachment") {
|
||||
throw AuthenticationError("Invalid signature");
|
||||
}
|
||||
|
||||
try {
|
||||
JWT.verify(sig, env.SECRET_KEY);
|
||||
} catch (err) {
|
||||
throw AuthenticationError("Invalid signature");
|
||||
}
|
||||
|
||||
return payload.key as string;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
return key;
|
||||
}
|
||||
|
||||
throw ValidationError("Must provide either key or sig parameter");
|
||||
}
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user