* feat: add card attachment schema * feat: setup s3 util funcs * feat: add attachments router and repo funcs * feat: add upload button * feat: add thumbnails and attachment viewer * feat: add download and delete button * feat: add file viewer and downloads * feat: update compose and readme * chore: build lang * feat: display attachments on public boards * chore: update compiled translations
54 lines
1.1 KiB
TypeScript
54 lines
1.1 KiB
TypeScript
import {
|
|
GetObjectCommand,
|
|
PutObjectCommand,
|
|
S3Client,
|
|
} from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
|
|
export function createS3Client() {
|
|
return new S3Client({
|
|
region: process.env.S3_REGION ?? "",
|
|
endpoint: process.env.S3_ENDPOINT ?? "",
|
|
forcePathStyle: process.env.S3_FORCE_PATH_STYLE === "true",
|
|
credentials: {
|
|
accessKeyId: process.env.S3_ACCESS_KEY_ID ?? "",
|
|
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY ?? "",
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function generateUploadUrl(
|
|
bucket: string,
|
|
key: string,
|
|
contentType: string,
|
|
expiresIn = 3600,
|
|
) {
|
|
const client = createS3Client();
|
|
return getSignedUrl(
|
|
client,
|
|
new PutObjectCommand({
|
|
Bucket: bucket,
|
|
Key: key,
|
|
ContentType: contentType,
|
|
// Don't set ACL for private files
|
|
}),
|
|
{ expiresIn },
|
|
);
|
|
}
|
|
|
|
export async function generateDownloadUrl(
|
|
bucket: string,
|
|
key: string,
|
|
expiresIn = 3600,
|
|
) {
|
|
const client = createS3Client();
|
|
return getSignedUrl(
|
|
client,
|
|
new GetObjectCommand({
|
|
Bucket: bucket,
|
|
Key: key,
|
|
}),
|
|
{ expiresIn },
|
|
);
|
|
}
|