chore(server): update sign domain description (#11407)
This commit is contained in:
@@ -352,13 +352,23 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The account id for the cloudflare r2 storage provider."
|
"description": "The account id for the cloudflare r2 storage provider."
|
||||||
},
|
},
|
||||||
"signDomain": {
|
"usePresignedURL": {
|
||||||
"type": "string",
|
"type": "object",
|
||||||
"description": "The presigned domain for the cloudflare r2 storage provider."
|
"description": "The presigned url config for the cloudflare r2 storage provider.",
|
||||||
},
|
"properties": {
|
||||||
"signKey": {
|
"enabled": {
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"description": "The presigned key for the cloudflare r2 storage provider."
|
"description": "Whether to use presigned url for the cloudflare r2 storage provider."
|
||||||
|
},
|
||||||
|
"urlPrefix": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned url prefix for the cloudflare r2 storage provider.\nsee https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/ to configure it.\nExample value: \"https://storage.example.com\"\nExample rule: is_timed_hmac_valid_v0(\"your_secret\", http.request.uri, 10800, http.request.timestamp.sec, 6)"
|
||||||
|
},
|
||||||
|
"signKey": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned key for the cloudflare r2 storage provider."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,13 +473,23 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The account id for the cloudflare r2 storage provider."
|
"description": "The account id for the cloudflare r2 storage provider."
|
||||||
},
|
},
|
||||||
"signDomain": {
|
"usePresignedURL": {
|
||||||
"type": "string",
|
"type": "object",
|
||||||
"description": "The presigned domain for the cloudflare r2 storage provider."
|
"description": "The presigned url config for the cloudflare r2 storage provider.",
|
||||||
},
|
"properties": {
|
||||||
"signKey": {
|
"enabled": {
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"description": "The presigned key for the cloudflare r2 storage provider."
|
"description": "Whether to use presigned url for the cloudflare r2 storage provider."
|
||||||
|
},
|
||||||
|
"urlPrefix": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned url prefix for the cloudflare r2 storage provider.\nsee https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/ to configure it.\nExample value: \"https://storage.example.com\"\nExample rule: is_timed_hmac_valid_v0(\"your_secret\", http.request.uri, 10800, http.request.timestamp.sec, 6)"
|
||||||
|
},
|
||||||
|
"signKey": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned key for the cloudflare r2 storage provider."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,13 +737,23 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The account id for the cloudflare r2 storage provider."
|
"description": "The account id for the cloudflare r2 storage provider."
|
||||||
},
|
},
|
||||||
"signDomain": {
|
"usePresignedURL": {
|
||||||
"type": "string",
|
"type": "object",
|
||||||
"description": "The presigned domain for the cloudflare r2 storage provider."
|
"description": "The presigned url config for the cloudflare r2 storage provider.",
|
||||||
},
|
"properties": {
|
||||||
"signKey": {
|
"enabled": {
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"description": "The presigned key for the cloudflare r2 storage provider."
|
"description": "Whether to use presigned url for the cloudflare r2 storage provider."
|
||||||
|
},
|
||||||
|
"urlPrefix": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned url prefix for the cloudflare r2 storage provider.\nsee https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/ to configure it.\nExample value: \"https://storage.example.com\"\nExample rule: is_timed_hmac_valid_v0(\"your_secret\", http.request.uri, 10800, http.request.timestamp.sec, 6)"
|
||||||
|
},
|
||||||
|
"signKey": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The presigned key for the cloudflare r2 storage provider."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,15 +105,27 @@ export const StorageJSONSchema: JSONSchema = {
|
|||||||
description:
|
description:
|
||||||
'The account id for the cloudflare r2 storage provider.',
|
'The account id for the cloudflare r2 storage provider.',
|
||||||
},
|
},
|
||||||
signDomain: {
|
usePresignedURL: {
|
||||||
type: 'string' as const,
|
type: 'object' as const,
|
||||||
description:
|
description:
|
||||||
'The presigned domain for the cloudflare r2 storage provider.',
|
'The presigned url config for the cloudflare r2 storage provider.',
|
||||||
},
|
properties: {
|
||||||
signKey: {
|
enabled: {
|
||||||
type: 'string' as const,
|
type: 'boolean' as const,
|
||||||
description:
|
description:
|
||||||
'The presigned key for the cloudflare r2 storage provider.',
|
'Whether to use presigned url for the cloudflare r2 storage provider.',
|
||||||
|
},
|
||||||
|
urlPrefix: {
|
||||||
|
type: 'string' as const,
|
||||||
|
description:
|
||||||
|
'The presigned url prefix for the cloudflare r2 storage provider.\nsee https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/ to configure it.\nExample value: "https://storage.example.com"\nExample rule: is_timed_hmac_valid_v0("your_secret", http.request.uri, 10800, http.request.timestamp.sec, 6)',
|
||||||
|
},
|
||||||
|
signKey: {
|
||||||
|
type: 'string' as const,
|
||||||
|
description:
|
||||||
|
'The presigned key for the cloudflare r2 storage provider.',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import { S3StorageConfig, S3StorageProvider } from './s3';
|
|||||||
|
|
||||||
export interface R2StorageConfig extends S3StorageConfig {
|
export interface R2StorageConfig extends S3StorageConfig {
|
||||||
accountId: string;
|
accountId: string;
|
||||||
// r2 public domain with verification
|
usePresignedURL?: {
|
||||||
// see https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/ to configure it
|
enabled: boolean;
|
||||||
// example rule: is_timed_hmac_valid_v0("your_secret", http.request.uri, 10800, http.request.timestamp.sec, 6)
|
urlPrefix?: string;
|
||||||
signDomain?: string;
|
signKey?: string;
|
||||||
signKey?: string;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class R2StorageProvider extends S3StorageProvider {
|
export class R2StorageProvider extends S3StorageProvider {
|
||||||
@@ -36,7 +36,7 @@ export class R2StorageProvider extends S3StorageProvider {
|
|||||||
bucket
|
bucket
|
||||||
);
|
);
|
||||||
this.logger = new Logger(`${R2StorageProvider.name}:${bucket}`);
|
this.logger = new Logger(`${R2StorageProvider.name}:${bucket}`);
|
||||||
this.key = this.encoder.encode(config.signKey);
|
this.key = this.encoder.encode(config.usePresignedURL?.signKey ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async signUrl(url: URL): Promise<string> {
|
private async signUrl(url: URL): Promise<string> {
|
||||||
@@ -67,10 +67,10 @@ export class R2StorageProvider extends S3StorageProvider {
|
|||||||
metadata?: GetObjectMetadata;
|
metadata?: GetObjectMetadata;
|
||||||
redirectUrl?: string;
|
redirectUrl?: string;
|
||||||
}> {
|
}> {
|
||||||
const { signDomain } = this.config;
|
const { usePresignedURL: { enabled, urlPrefix } = {} } = this.config;
|
||||||
if (signedUrl && signDomain) {
|
if (signedUrl && enabled && urlPrefix) {
|
||||||
const metadata = await this.head(key);
|
const metadata = await this.head(key);
|
||||||
const url = await this.signUrl(new URL(`/${key}`, signDomain));
|
const url = await this.signUrl(new URL(`/${key}`, urlPrefix));
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
return {
|
return {
|
||||||
redirectUrl: url.toString(),
|
redirectUrl: url.toString(),
|
||||||
@@ -82,7 +82,7 @@ export class R2StorageProvider extends S3StorageProvider {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// fallback to s3 presigned url if signDomain is not configured
|
// fallback to s3 get
|
||||||
return super.get(key, signDomain ? false : signedUrl);
|
return super.get(key, signedUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,24 +24,31 @@ import {
|
|||||||
} from './provider';
|
} from './provider';
|
||||||
import { autoMetadata, SIGNED_URL_EXPIRED, toBuffer } from './utils';
|
import { autoMetadata, SIGNED_URL_EXPIRED, toBuffer } from './utils';
|
||||||
|
|
||||||
export type S3StorageConfig = S3ClientConfig;
|
export interface S3StorageConfig extends S3ClientConfig {
|
||||||
|
usePresignedURL?: {
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class S3StorageProvider implements StorageProvider {
|
export class S3StorageProvider implements StorageProvider {
|
||||||
protected logger: Logger;
|
protected logger: Logger;
|
||||||
protected client: S3Client;
|
protected client: S3Client;
|
||||||
|
private readonly usePresignedURL: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: S3StorageConfig,
|
config: S3StorageConfig,
|
||||||
public readonly bucket: string
|
public readonly bucket: string
|
||||||
) {
|
) {
|
||||||
|
const { usePresignedURL, ...clientConfig } = config;
|
||||||
this.client = new S3Client({
|
this.client = new S3Client({
|
||||||
region: 'auto',
|
region: 'auto',
|
||||||
// s3 client uses keep-alive by default to accelerate requests, and max requests queue is 50.
|
// s3 client uses keep-alive by default to accelerate requests, and max requests queue is 50.
|
||||||
// If some of them are long holding or dead without response, the whole queue will block.
|
// If some of them are long holding or dead without response, the whole queue will block.
|
||||||
// By default no timeout is set for requests or connections, so we set them here.
|
// By default no timeout is set for requests or connections, so we set them here.
|
||||||
requestHandler: { requestTimeout: 60_000, connectionTimeout: 10_000 },
|
requestHandler: { requestTimeout: 60_000, connectionTimeout: 10_000 },
|
||||||
...config,
|
...clientConfig,
|
||||||
});
|
});
|
||||||
|
this.usePresignedURL = usePresignedURL?.enabled ?? false;
|
||||||
this.logger = new Logger(`${S3StorageProvider.name}:${bucket}`);
|
this.logger = new Logger(`${S3StorageProvider.name}:${bucket}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +129,7 @@ export class S3StorageProvider implements StorageProvider {
|
|||||||
Key: key,
|
Key: key,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (signedUrl) {
|
if (this.usePresignedURL && signedUrl) {
|
||||||
const metadata = await this.head(key);
|
const metadata = await this.head(key);
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
const url = await getSignedUrl(
|
const url = await getSignedUrl(
|
||||||
|
|||||||
Reference in New Issue
Block a user