101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import type { UserAttachmentStorageConfig } from "@/lib/boss-data";
|
|
import { encryptStorageSecret } from "@/lib/boss-storage-secrets";
|
|
|
|
export interface AttachmentStorageConfigPatch {
|
|
mode?: UserAttachmentStorageConfig["mode"];
|
|
ossProvider?: UserAttachmentStorageConfig["ossProvider"];
|
|
aliyunOss?: {
|
|
enabled?: boolean;
|
|
accessKeyId?: string;
|
|
accessKeySecret?: string;
|
|
bucket?: string;
|
|
endpoint?: string;
|
|
region?: string;
|
|
prefix?: string;
|
|
};
|
|
}
|
|
|
|
function trimText(value: string | undefined) {
|
|
return value?.trim() ?? "";
|
|
}
|
|
|
|
function normalizePrefix(prefix: string | undefined, fallback?: string) {
|
|
const candidate = prefix?.trim() || fallback?.trim() || "boss/";
|
|
return candidate || "boss/";
|
|
}
|
|
|
|
function buildAliyunOssBaseConfig(existing?: UserAttachmentStorageConfig["aliyunOss"]) {
|
|
return {
|
|
enabled: existing?.enabled ?? false,
|
|
accessKeyId: existing?.accessKeyId ?? "",
|
|
accessKeySecretEncrypted: existing?.accessKeySecretEncrypted ?? "",
|
|
bucket: existing?.bucket ?? "",
|
|
endpoint: existing?.endpoint ?? "",
|
|
region: existing?.region ?? "",
|
|
prefix: existing?.prefix ?? "boss/",
|
|
};
|
|
}
|
|
|
|
export async function applyAttachmentStorageConfigPatch(
|
|
existing: UserAttachmentStorageConfig,
|
|
patch: AttachmentStorageConfigPatch,
|
|
): Promise<UserAttachmentStorageConfig> {
|
|
const mode = patch.mode ?? existing.mode;
|
|
const effectiveOssProvider =
|
|
mode === "oss" ? patch.ossProvider ?? existing.ossProvider ?? "aliyun_oss" : existing.ossProvider;
|
|
|
|
const nextAliyun = buildAliyunOssBaseConfig(existing.aliyunOss);
|
|
if (patch.aliyunOss) {
|
|
if (patch.aliyunOss.enabled !== undefined) {
|
|
nextAliyun.enabled = patch.aliyunOss.enabled;
|
|
}
|
|
if (patch.aliyunOss.accessKeyId !== undefined) {
|
|
nextAliyun.accessKeyId = trimText(patch.aliyunOss.accessKeyId);
|
|
}
|
|
if (patch.aliyunOss.bucket !== undefined) {
|
|
nextAliyun.bucket = trimText(patch.aliyunOss.bucket);
|
|
}
|
|
if (patch.aliyunOss.endpoint !== undefined) {
|
|
nextAliyun.endpoint = trimText(patch.aliyunOss.endpoint);
|
|
}
|
|
if (patch.aliyunOss.region !== undefined) {
|
|
nextAliyun.region = trimText(patch.aliyunOss.region);
|
|
}
|
|
if (patch.aliyunOss.prefix !== undefined) {
|
|
nextAliyun.prefix = normalizePrefix(patch.aliyunOss.prefix, nextAliyun.prefix);
|
|
}
|
|
if (patch.aliyunOss.accessKeySecret !== undefined) {
|
|
nextAliyun.accessKeySecretEncrypted = await encryptStorageSecret(
|
|
patch.aliyunOss.accessKeySecret,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (mode === "oss") {
|
|
if (effectiveOssProvider !== "aliyun_oss") {
|
|
throw new Error("ALIYUN_OSS_PROVIDER_REQUIRED");
|
|
}
|
|
if (
|
|
!nextAliyun.accessKeyId ||
|
|
!nextAliyun.accessKeySecretEncrypted ||
|
|
!nextAliyun.bucket ||
|
|
!nextAliyun.endpoint ||
|
|
!nextAliyun.region
|
|
) {
|
|
throw new Error("ALIYUN_OSS_CONFIG_INCOMPLETE");
|
|
}
|
|
nextAliyun.enabled = true;
|
|
}
|
|
|
|
return {
|
|
account: existing.account,
|
|
mode,
|
|
ossProvider: effectiveOssProvider,
|
|
aliyunOss: nextAliyun,
|
|
updatedAt: new Date().toISOString(),
|
|
validatedAt: patch.mode !== undefined || patch.ossProvider !== undefined || patch.aliyunOss
|
|
? undefined
|
|
: existing.validatedAt,
|
|
};
|
|
}
|