157 lines
3.9 KiB
TypeScript
157 lines
3.9 KiB
TypeScript
import {
|
|
Controller,
|
|
Get,
|
|
Post,
|
|
Req,
|
|
Body,
|
|
Param,
|
|
HttpException,
|
|
Patch,
|
|
UseInterceptors,
|
|
UploadedFile,
|
|
} from '@nestjs/common';
|
|
import { KvService } from './kv.service';
|
|
import { Request } from 'express';
|
|
import { ApiQuery, ApiTags } from '@nestjs/swagger';
|
|
import { FileInterceptor } from '@nestjs/platform-express';
|
|
|
|
@Controller('kv')
|
|
@ApiTags('kv')
|
|
export class KvController {
|
|
constructor(private readonly kvService: KvService) { }
|
|
|
|
@Get(':namespace/:key/metadata')
|
|
@ApiQuery({ name: 'namespace', required: true })
|
|
@ApiQuery({ name: 'key', required: true })
|
|
async getMetadata(
|
|
@Param('namespace') namespace: string,
|
|
@Param('key') key: string,
|
|
@Req() request: Request,
|
|
): Promise<object> {
|
|
if (!request.headers['x-secret-key']) {
|
|
throw new HttpException("Missing 'X-Secret-Key' header", 403);
|
|
}
|
|
try {
|
|
return await this.kvService.queryObjectMetadata(
|
|
namespace,
|
|
key,
|
|
request.headers['x-secret-key'] as string,
|
|
);
|
|
} catch (e) {
|
|
throw new HttpException(e.message, 403);
|
|
}
|
|
}
|
|
|
|
@Get(':namespace/:key')
|
|
async get(
|
|
@Param('namespace') namespace: string,
|
|
@Param('key') key: string,
|
|
@Req() request: Request,
|
|
): Promise<string> {
|
|
if (request.headers['x-secret-key']) {
|
|
try {
|
|
return (
|
|
await this.kvService.getWithSecretKey(
|
|
namespace,
|
|
key,
|
|
request.headers['x-secret-key'] as string,
|
|
)
|
|
).toString();
|
|
} catch (e) {
|
|
throw new HttpException(e.message, 403);
|
|
}
|
|
}
|
|
try {
|
|
return (await this.kvService.get(namespace, key)).toString();
|
|
} catch (e) {
|
|
throw new HttpException(e.message, 403);
|
|
}
|
|
}
|
|
|
|
@Post(':namespace/:key')
|
|
@UseInterceptors(FileInterceptor('file'))
|
|
async create(
|
|
@Param('namespace') namespace: string,
|
|
@Param('key') key: string,
|
|
@Req() request: Request,
|
|
@Body() body: object | string,
|
|
@UploadedFile('file') file: Express.Multer.File,
|
|
) {
|
|
const secretKey =
|
|
(request.headers['x-secret-key'] as string | undefined) ?? '';
|
|
const publicFlag = request.headers['x-public'] === 'true';
|
|
if (secretKey) {
|
|
return await this.kvService.set(
|
|
namespace,
|
|
key,
|
|
file === undefined
|
|
? typeof body === 'object'
|
|
? Buffer.from(JSON.stringify(body))
|
|
: Buffer.from(body)
|
|
: file.buffer,
|
|
secretKey,
|
|
{
|
|
public: publicFlag,
|
|
mimeType:
|
|
file?.mimetype ?? request.headers['content-type'] ?? 'text/plain',
|
|
},
|
|
);
|
|
}
|
|
return 'No secret key provided within X-Secret-Key header';
|
|
}
|
|
|
|
@Post(':namespace/:key/share')
|
|
async share(
|
|
@Param('namespace') namespace: string,
|
|
@Param('key') key: string,
|
|
@Req() request: Request,
|
|
@Body() body: { expiry?: number },
|
|
) {
|
|
const secretKey =
|
|
(request.headers['x-secret-key'] as string | undefined) ?? '';
|
|
if (secretKey) {
|
|
return {
|
|
expiry: body.expiry,
|
|
namespace,
|
|
key,
|
|
url: await this.kvService.shareFile(
|
|
namespace,
|
|
key,
|
|
secretKey,
|
|
body.expiry,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
@Post(':namespace')
|
|
async claimNamespace(
|
|
@Param('namespace') namespace: string,
|
|
@Req() request: Request,
|
|
) {
|
|
try {
|
|
return await this.kvService.claimNamespace(namespace);
|
|
} catch (e) {
|
|
throw new HttpException(e.message, 403);
|
|
}
|
|
}
|
|
|
|
@Patch(':namespace/secretKey')
|
|
async rotateSecretKey(
|
|
@Param('namespace') namespace: string,
|
|
@Req() request: Request,
|
|
) {
|
|
if (!request.headers['x-secret-key']) {
|
|
throw new HttpException("Missing 'X-Secret-Key' header", 403);
|
|
}
|
|
try {
|
|
return await this.kvService.rotateSecretKey(
|
|
namespace,
|
|
request.headers['x-secret-key'] as string,
|
|
);
|
|
} catch (e) {
|
|
throw new HttpException(e.message, 403);
|
|
}
|
|
}
|
|
}
|