/
aliyun-web.ts
100 lines (92 loc) · 3.27 KB
/
aliyun-web.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { IAliyunConfig, IPicGo } from "../../types"
import crypto from "crypto"
import mime from "mime-types"
import { IBuildInEvent } from "../../utils/enums"
import { ILocalesKey } from "../../i18n/zh-CN"
import { AxiosRequestConfig } from "axios"
import { base64ToBuffer, safeParse } from "../../utils/common"
// generate OSS signature
const generateSignature = (options: IAliyunConfig, fileName: string): string => {
const date = new Date().toUTCString()
const mimeType = mime.lookup(fileName)
if (!mimeType) throw Error(`No mime type found for file ${fileName}`)
const signString = `PUT\n\n${mimeType}\n${date}\n/${options.bucket}/${options.path}${fileName}`
const signature = crypto.createHmac("sha1", options.accessKeySecret).update(signString).digest("base64")
return `OSS ${options.accessKeyId}:${signature}`
}
const postOptions = (
options: IAliyunConfig,
fileName: string,
signature: string,
image: Buffer
): AxiosRequestConfig => {
const xCorsHeaders = {
Host: `${options.bucket}.${options.area}.aliyuncs.com`,
Date: new Date().toUTCString(),
}
return {
method: "PUT",
url: `https://${options.bucket}.${options.area}.aliyuncs.com/${encodeURI(options.path)}${encodeURI(fileName)}`,
headers: {
Authorization: signature,
"Content-Type": mime.lookup(fileName),
"x-cors-headers": JSON.stringify(xCorsHeaders),
},
data: image,
resolveWithFullResponse: true,
} as AxiosRequestConfig
}
const handleWeb = async (ctx: IPicGo): Promise<IPicGo> => {
const aliYunOptions = ctx.getConfig<IAliyunConfig>("picBed.aliyun")
if (!aliYunOptions) {
throw new Error("Can't find aliYun OSS config")
}
const imgList = ctx.output
const customUrl = aliYunOptions.customUrl
const path = aliYunOptions.path
for (const img of imgList) {
if (img.fileName) {
let image = img.buffer
if (!image && img.base64Image) {
image = base64ToBuffer(img.base64Image)
}
if (!image) {
ctx.log.error("Can not find image buffer")
throw new Error("Can not find image buffer")
}
try {
const signature = generateSignature(aliYunOptions, img.fileName)
const options = postOptions(aliYunOptions, img.fileName, signature, image)
const res: any = await ctx.request(options)
const body = safeParse<any>(res)
if (body.statusCode === 200) {
delete img.base64Image
delete img.buffer
const optionUrl = aliYunOptions.options || ""
if (customUrl) {
img.imgUrl = `${customUrl}/${path}${img.fileName}${optionUrl}`
} else {
img.imgUrl = `https://${aliYunOptions.bucket}.${aliYunOptions.area}.aliyuncs.com/${path}${img.fileName}${optionUrl}`
}
} else {
throw new Error("Upload failed")
}
} catch (e: any) {
let errMsg: any
if (e?.statusCode) {
errMsg = e.response?.body ?? e.stack ?? "unknown error"
} else {
errMsg = e.toString()
}
ctx.log.error(errMsg)
ctx.emit(IBuildInEvent.NOTIFICATION, {
title: ctx.i18n.translate<ILocalesKey>("UPLOAD_FAILED"),
body: ctx.i18n.translate<ILocalesKey>("CHECK_SETTINGS"),
})
throw errMsg
}
}
}
return ctx
}
export { handleWeb }