52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import * as Joi from 'joi';
|
|
import { AbstractActionHandler, Format } from '../abstract-action.handler';
|
|
import { Action } from '../action.enum';
|
|
import { RequestContext } from '../_context/request.context';
|
|
import { S3Service } from './s3.service';
|
|
|
|
type QueryParams = {
|
|
Bucket: string;
|
|
Body?: string;
|
|
};
|
|
|
|
@Injectable()
|
|
export class PutBucketTaggingHandler extends AbstractActionHandler<QueryParams> {
|
|
constructor(private readonly s3Service: S3Service) {
|
|
super();
|
|
}
|
|
|
|
format = Format.Xml;
|
|
action = Action.S3PutBucketTagging;
|
|
validator = Joi.object<QueryParams, true>({
|
|
Bucket: Joi.string().required(),
|
|
Body: Joi.string().optional(),
|
|
});
|
|
|
|
protected async handle({ Bucket, Body }: QueryParams, { awsProperties }: RequestContext) {
|
|
// Parse XML body to extract tags
|
|
const tags: Record<string, string> = {};
|
|
|
|
if (Body) {
|
|
// Decode from base64
|
|
const xmlBody = Buffer.from(Body, 'base64').toString('utf-8');
|
|
|
|
// Simple XML parsing for AWS S3 tagging format: <Tagging><TagSet><Tag><Key>...</Key><Value>...</Value></Tag>...</TagSet></Tagging>
|
|
const tagMatches = xmlBody.matchAll(/<Tag>\s*<Key>(.*?)<\/Key>\s*<Value>(.*?)<\/Value>\s*<\/Tag>/gs);
|
|
|
|
for (const match of tagMatches) {
|
|
const key = match[1].trim();
|
|
const value = match[2].trim();
|
|
if (key) {
|
|
tags[key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
await this.s3Service.putBucketTagging(Bucket, tags);
|
|
|
|
// PutBucketTagging returns no content on success
|
|
return {};
|
|
}
|
|
}
|