mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-05-12 02:20:12 +08:00
feat: add s3 attachment (#291)
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
"wrangler": "^3.57.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.588.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.588.0",
|
||||
"hono": "^4.3.9",
|
||||
"mimetext": "^3.0.24",
|
||||
"postal-mime": "^2.2.5",
|
||||
|
||||
1240
worker/pnpm-lock.yaml
generated
1240
worker/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ import { Hono } from 'hono'
|
||||
import { getDomains, getPasswords, getBooleanValue } from './utils';
|
||||
import { CONSTANTS } from './constants';
|
||||
import { HonoCustomType } from './types';
|
||||
import { isS3Enabled } from './mails_api/s3_attachment';
|
||||
|
||||
const api = new Hono<HonoCustomType>
|
||||
|
||||
@@ -27,6 +28,7 @@ api.get('/open_api/settings', async (c) => {
|
||||
"copyright": c.env.COPYRIGHT,
|
||||
"cfTurnstileSiteKey": c.env.CF_TURNSTILE_SITE_KEY,
|
||||
"enableWebhook": getBooleanValue(c.env.ENABLE_WEBHOOK),
|
||||
"isS3Enabled": isS3Enabled(c),
|
||||
"version": CONSTANTS.VERSION,
|
||||
});
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import { newAddress, handleListQuery, deleteAddressWithData } from '../common'
|
||||
import { CONSTANTS } from '../constants'
|
||||
import auto_reply from './auto_reply'
|
||||
import webhook_settings from './webhook_settings';
|
||||
import s3_attachment from './s3_attachment';
|
||||
|
||||
export const api = new Hono<HonoCustomType>()
|
||||
|
||||
@@ -14,6 +15,9 @@ api.post('/api/auto_reply', auto_reply.saveAutoReply)
|
||||
api.get('/api/webhook/settings', webhook_settings.getWebhookSettings)
|
||||
api.post('/api/webhook/settings', webhook_settings.saveWebhookSettings)
|
||||
api.post('/api/webhook/test', webhook_settings.testWebhookSettings)
|
||||
api.get('/api/attachment/list', s3_attachment.list)
|
||||
api.post('/api/attachment/put_url', s3_attachment.getSignedPutUrl)
|
||||
api.post('/api/attachment/get_url', s3_attachment.getSignedGetUrl)
|
||||
|
||||
api.get('/api/mails', async (c) => {
|
||||
const { address } = c.get("jwtPayload")
|
||||
|
||||
84
worker/src/mails_api/s3_attachment.ts
Normal file
84
worker/src/mails_api/s3_attachment.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { HonoCustomType } from "../types";
|
||||
import { Context } from "hono";
|
||||
import {
|
||||
S3Client,
|
||||
ListObjectsV2Command,
|
||||
GetObjectCommand,
|
||||
PutObjectCommand
|
||||
} from "@aws-sdk/client-s3";
|
||||
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
||||
|
||||
export const isS3Enabled = (c: Context<HonoCustomType>) => {
|
||||
return !(!c.env.S3_ENDPOINT ||
|
||||
!c.env.S3_ACCESS_KEY_ID ||
|
||||
!c.env.S3_SECRET_ACCESS_KEY ||
|
||||
!c.env.S3_BUCKET);
|
||||
}
|
||||
|
||||
const getS3Client = (c: Context<HonoCustomType>) => {
|
||||
if (
|
||||
!c.env.S3_ENDPOINT ||
|
||||
!c.env.S3_ACCESS_KEY_ID ||
|
||||
!c.env.S3_SECRET_ACCESS_KEY ||
|
||||
!c.env.S3_BUCKET
|
||||
) {
|
||||
throw new Error("S3 config is not set");
|
||||
}
|
||||
return new S3Client({
|
||||
region: "auto",
|
||||
endpoint: c.env.S3_ENDPOINT,
|
||||
credentials: {
|
||||
accessKeyId: c.env.S3_ACCESS_KEY_ID,
|
||||
secretAccessKey: c.env.S3_SECRET_ACCESS_KEY,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
getSignedGetUrl: async (c: Context<HonoCustomType>) => {
|
||||
const { address } = c.get("jwtPayload")
|
||||
const { key } = await c.req.json()
|
||||
const client = getS3Client(c);
|
||||
const url = await getSignedUrl(
|
||||
client,
|
||||
new GetObjectCommand({
|
||||
Bucket: c.env.S3_BUCKET,
|
||||
Key: `${address}/${key}`
|
||||
}),
|
||||
{ expiresIn: c.env.S3_URL_EXPIRES || 360 }
|
||||
);
|
||||
return c.json({ url });
|
||||
},
|
||||
getSignedPutUrl: async (c: Context<HonoCustomType>) => {
|
||||
const { address } = c.get("jwtPayload")
|
||||
const { key } = await c.req.json()
|
||||
const client = getS3Client(c);
|
||||
const url = await getSignedUrl(
|
||||
client,
|
||||
new PutObjectCommand({
|
||||
Bucket: c.env.S3_BUCKET,
|
||||
Key: `${address}/${key}`
|
||||
}),
|
||||
{ expiresIn: c.env.S3_URL_EXPIRES || 360 }
|
||||
);
|
||||
return c.json({ url });
|
||||
},
|
||||
list: async (c: Context<HonoCustomType>) => {
|
||||
const { address } = c.get("jwtPayload")
|
||||
const client = getS3Client(c);
|
||||
const data = await client.send(
|
||||
new ListObjectsV2Command({
|
||||
Bucket: c.env.S3_BUCKET,
|
||||
Prefix: `${address}/`
|
||||
})
|
||||
);
|
||||
return c.json(
|
||||
{
|
||||
results: data?.Contents
|
||||
?.map((v) => v.Key?.replace(`${address}/`, ""))
|
||||
?.filter(k => k)
|
||||
?.map((k) => ({ key: k }))
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
7
worker/src/types.d.ts
vendored
7
worker/src/types.d.ts
vendored
@@ -23,6 +23,13 @@ export type Bindings = {
|
||||
COPYRIGHT: string | undefined
|
||||
FORWARD_ADDRESS_LIST: string | string[] | undefined
|
||||
|
||||
// s3 config
|
||||
S3_ENDPOINT: string | undefined
|
||||
S3_ACCESS_KEY_ID: string | undefined
|
||||
S3_SECRET_ACCESS_KEY: string | undefined
|
||||
S3_BUCKET: string | undefined
|
||||
S3_URL_EXPIRES: number | undefined
|
||||
|
||||
// dkim
|
||||
DKIM_SELECTOR: string | undefined
|
||||
DKIM_PRIVATE_KEY: string | undefined
|
||||
|
||||
Reference in New Issue
Block a user