File

src/cloud/cloudflare/cloudflare.service.ts

Index

Properties
Methods

Constructor

constructor(configService: ConfigService)
Parameters :
Name Type Optional
configService ConfigService No

Methods

Public Async bindNewWorkerRoute
bindNewWorkerRoute(worker: string, route: string, domain: string)
Parameters :
Name Type Optional
worker string No
route string No
domain string No
Returns : Promise<string>
Public Async createCname
createCname(cname: string, domain: string)
Parameters :
Name Type Optional
cname string No
domain string No
Private Async GET
GET(url: string)
Type parameters :
  • Resp
Parameters :
Name Type Optional
url string No
Returns : unknown
Private getDomainAccountId
getDomainAccountId(domain: string)
Parameters :
Name Type Optional
domain string No
Returns : string
Private Async POST
POST(url: string, body: Body)
Type parameters :
  • Body
  • Resp
Parameters :
Name Type Optional
url string No
body Body No
Returns : unknown
Private Async PUT
PUT(url: string, body: Body)
Type parameters :
  • Body
  • Resp
Parameters :
Name Type Optional
url string No
body Body No
Returns : unknown

Properties

Private Readonly httpService
Default value : new HttpService()
Private Readonly logger
Default value : new Logger(CloudflareService.name)
Private Readonly route
Type : string
import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { CloudflareApi } from '../../../types/cloudflare';
import * as Sentry from '@sentry/node';
import "@sentry/tracing";
type TupleIdReturn = { workerId: string; dnsId: string };

@Injectable()
export class CloudflareService {
  private readonly route: string;
  private readonly httpService = new HttpService();
  private readonly logger = new Logger(CloudflareService.name);
  constructor(private readonly configService: ConfigService) {
    this.route = `https://api.cloudflare.com/client/v4/zones`;
  }

  private async POST<Body, Resp>(url: string, body: Body) {
    const r = await this.httpService.post<Resp>(this.route + url, body, {
      headers: {
        'X-Auth-Email': this.configService.get('CF_EMAIL'),
        'X-Auth-Key': this.configService.get('CF_KEY'),
      },
    });
    return await r.toPromise();
  }

  private async PUT<Body, Resp>(url: string, body: Body) {
    const r = await this.httpService.put<Resp>(this.route + url, body, {
      headers: {
        'X-Auth-Email': this.configService.get('CF_EMAIL'),
        'X-Auth-Key': this.configService.get('CF_KEY'),
      },
    });
    return await r.toPromise();
  }
  private getDomainAccountId(domain: string): string {
    const idx = this.configService.get<string[]>('domains').indexOf(domain);
    return this.configService.get<string[]>('accountIds')[idx];
  }

  private async GET<Resp>(url: string) {
    const r = await this.httpService.get<Resp>(this.route + url, {
      headers: {
        'X-Auth-Email': this.configService.get('CF_EMAIL'),
        'X-Auth-Key': this.configService.get('CF_KEY'),
      },
    });
    return await r.toPromise();
  }

  public async bindNewWorkerRoute(
    worker: string,
    route: string,
    domain: string,
  ): Promise<string> {
    const r = await this.POST<
      CloudflareApi.NewWorkerRoute,
      CloudflareApi.GenericCfResp<{ id: string }>
    >(`/${this.getDomainAccountId(domain)}/workers/routes`, {
      pattern: route,
      script: worker,
    });
    return r.data.result.id;
  }

  public async createCname(
    cname: string,
    domain: string,
  ): Promise<TupleIdReturn> {
    this.logger.debug(`createCname args: ${cname}, domain: ${domain}`);
    try {
      const r = await this.POST<
        CloudflareApi.NewDns,
        CloudflareApi.GenericCfResp<{ id: string }>
      >(`/${this.getDomainAccountId(domain)}/dns_records`, {
        type: 'A',
        name: `${cname}.${domain}`,
        content: '192.0.2.1',
        ttl: 120,
        proxied: true,
      });
      const workerRouteId = await this.bindNewWorkerRoute(
        'n23h-cuscname-rdir-s2inq',
        `${cname}.${domain}/*`,
        domain,
      );
      return { dnsId: r.data.result.id, workerId: workerRouteId };
    } catch (err) {
      this.logger.error(
        'Cloudflare error returned',
        JSON.stringify(err as CloudflareApi.GenericCfResp),
      );
      Sentry.captureException(err);
      return { dnsId: 'inUse', workerId: 'inUse' };
    }
  }
}

results matching ""

    No results matching ""