gohorsejobs/backoffice/src/admin/cloudflare.service.ts

79 lines
2.6 KiB
TypeScript

import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom, catchError } from 'rxjs';
import { AxiosError } from 'axios';
@Injectable()
export class CloudflareService {
private readonly logger = new Logger(CloudflareService.name);
private readonly apiToken: string;
private readonly zoneId: string;
private readonly baseUrl = 'https://api.cloudflare.com/client/v4';
constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService,
) {
this.apiToken =
this.configService.get<string>('CLOUDFLARE_API_TOKEN') || '';
this.zoneId = this.configService.get<string>('CLOUDFLARE_ZONE_ID') || '';
if (!this.apiToken) {
this.logger.warn('CLOUDFLARE_API_TOKEN is not set');
}
}
private getHeaders() {
return {
Authorization: `Bearer ${this.apiToken}`,
'Content-Type': 'application/json',
};
}
async listZones(): Promise<any> {
const url = `${this.baseUrl}/zones`;
const response = await firstValueFrom(
this.httpService.get(url, { headers: this.getHeaders() }).pipe(
catchError((error: AxiosError) => {
this.logger.error(error.response?.data || error.message);
throw new HttpException(
'Failed to fetch Cloudflare zones',
HttpStatus.BAD_GATEWAY,
);
}),
),
);
return response.data;
}
async purgeCache(params: {
purge_everything?: boolean;
files?: string[];
tags?: string[];
hosts?: string[];
}): Promise<any> {
if (!this.zoneId) {
throw new HttpException(
'CLOUDFLARE_ZONE_ID is not configured',
HttpStatus.BAD_REQUEST,
);
}
const url = `${this.baseUrl}/zones/${this.zoneId}/purge_cache`;
const response = await firstValueFrom(
this.httpService.post(url, params, { headers: this.getHeaders() }).pipe(
catchError((error: AxiosError) => {
this.logger.error(error.response?.data || error.message);
throw new HttpException(
'Failed to purge Cloudflare cache',
HttpStatus.BAD_GATEWAY,
);
}),
),
);
return response.data;
}
}