179 lines
5.8 KiB
TypeScript
179 lines
5.8 KiB
TypeScript
import * as plugins from './cloudflare.plugins.js';
|
|
import { logger } from './cloudflare.logger.js';
|
|
|
|
/**
|
|
* Adapter class that implements IConvenientDnsProvider interface
|
|
* Delegates to RecordManager and ZoneManager internally for clean architecture
|
|
* This allows third-party modules to use the standard DNS provider interface
|
|
*/
|
|
export class ConvenientDnsProvider implements plugins.tsclass.network.IConvenientDnsProvider {
|
|
/**
|
|
* The convenience property is required by IConvenientDnsProvider interface
|
|
* It returns this instance to maintain interface compatibility
|
|
*/
|
|
public convenience = this;
|
|
|
|
constructor(private cfAccount: any) {}
|
|
|
|
/**
|
|
* Creates a new DNS record
|
|
* @param domainNameArg - The domain name for the record
|
|
* @param typeArg - The DNS record type
|
|
* @param contentArg - The record content (IP address, CNAME target, etc.)
|
|
* @param ttlArg - Time to live in seconds (default: 1 = automatic)
|
|
* @returns Created record as raw API object
|
|
*/
|
|
public async createRecord(
|
|
domainNameArg: string,
|
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
|
contentArg: string,
|
|
ttlArg: number = 1,
|
|
): Promise<any> {
|
|
const record = await this.cfAccount.recordManager.createRecord(
|
|
domainNameArg,
|
|
typeArg,
|
|
contentArg,
|
|
ttlArg,
|
|
);
|
|
// Return raw API object format for interface compatibility
|
|
return this.recordToApiObject(record);
|
|
}
|
|
|
|
/**
|
|
* Updates an existing DNS record, or creates it if it doesn't exist
|
|
* @param domainNameArg - The domain name
|
|
* @param typeArg - The DNS record type
|
|
* @param contentArg - The new record content
|
|
* @param ttlArg - Time to live in seconds (default: 1 = automatic)
|
|
* @returns Updated record as raw API object
|
|
*/
|
|
public async updateRecord(
|
|
domainNameArg: string,
|
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
|
contentArg: string,
|
|
ttlArg: number = 1,
|
|
): Promise<any> {
|
|
const record = await this.cfAccount.recordManager.updateRecord(
|
|
domainNameArg,
|
|
typeArg,
|
|
contentArg,
|
|
ttlArg,
|
|
);
|
|
return this.recordToApiObject(record);
|
|
}
|
|
|
|
/**
|
|
* Removes a DNS record
|
|
* @param domainNameArg - The domain name
|
|
* @param typeArg - The DNS record type
|
|
*/
|
|
public async removeRecord(
|
|
domainNameArg: string,
|
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
|
): Promise<any> {
|
|
await this.cfAccount.recordManager.deleteRecord(domainNameArg, typeArg);
|
|
}
|
|
|
|
/**
|
|
* Gets a specific DNS record by domain and type
|
|
* @param domainNameArg - The domain name
|
|
* @param typeArg - The DNS record type
|
|
* @returns Record as raw API object or undefined if not found
|
|
*/
|
|
public async getRecord(
|
|
domainNameArg: string,
|
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
|
): Promise<any | undefined> {
|
|
const record = await this.cfAccount.recordManager.getRecord(domainNameArg, typeArg);
|
|
return record ? this.recordToApiObject(record) : undefined;
|
|
}
|
|
|
|
/**
|
|
* Lists all DNS records for a domain
|
|
* @param domainNameArg - The domain name to list records for
|
|
* @returns Array of records as raw API objects
|
|
*/
|
|
public async listRecords(domainNameArg: string): Promise<any[]> {
|
|
const records = await this.cfAccount.recordManager.listRecords(domainNameArg);
|
|
return records.map((record: any) => this.recordToApiObject(record));
|
|
}
|
|
|
|
/**
|
|
* Removes all DNS records of a specific type for a domain
|
|
* @param domainNameArg - The domain name
|
|
* @param typeArg - The DNS record type to clean
|
|
*/
|
|
public async cleanRecord(
|
|
domainNameArg: string,
|
|
typeArg: plugins.tsclass.network.TDnsRecordType,
|
|
): Promise<void> {
|
|
await this.cfAccount.recordManager.cleanRecords(domainNameArg, typeArg);
|
|
}
|
|
|
|
/**
|
|
* Determines whether the given domain can be managed by this account
|
|
* @param domainName - Full domain name to check (e.g., "sub.example.com")
|
|
* @returns True if the zone for the domain exists in the account, false otherwise
|
|
*/
|
|
public async isDomainSupported(domainName: string): Promise<boolean> {
|
|
try {
|
|
// Parse out the apex/zone name from the full domain
|
|
const domain = new plugins.smartstring.Domain(domainName);
|
|
// List zones filtered by the zone name
|
|
const zones = await this.cfAccount.zoneManager.listZones(domain.zoneName);
|
|
// If any zone matches, we can manage this domain
|
|
return Array.isArray(zones) && zones.length > 0;
|
|
} catch (error) {
|
|
logger.log('error', `Error checking domain support for ${domainName}: ${error.message}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets an ACME DNS challenge for domain verification
|
|
* @param dnsChallenge - The DNS challenge object
|
|
*/
|
|
public async acmeSetDnsChallenge(
|
|
dnsChallenge: plugins.tsclass.network.IDnsChallenge,
|
|
): Promise<void> {
|
|
await this.cfAccount.recordManager.cleanRecords(dnsChallenge.hostName, 'TXT');
|
|
await this.cfAccount.recordManager.createRecord(
|
|
dnsChallenge.hostName,
|
|
'TXT',
|
|
dnsChallenge.challenge,
|
|
120,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Removes an ACME DNS challenge
|
|
* @param dnsChallenge - The DNS challenge object
|
|
*/
|
|
public async acmeRemoveDnsChallenge(
|
|
dnsChallenge: plugins.tsclass.network.IDnsChallenge,
|
|
): Promise<void> {
|
|
await this.cfAccount.recordManager.deleteRecord(dnsChallenge.hostName, 'TXT');
|
|
}
|
|
|
|
/**
|
|
* Helper method to convert CloudflareRecord instance to raw API object format
|
|
* This ensures compatibility with the IConvenientDnsProvider interface
|
|
*/
|
|
private recordToApiObject(record: any): any {
|
|
return {
|
|
id: record.id,
|
|
type: record.type,
|
|
name: record.name,
|
|
content: record.content,
|
|
proxiable: record.proxiable,
|
|
proxied: record.proxied,
|
|
ttl: record.ttl,
|
|
locked: record.locked,
|
|
zone_id: record.zone_id,
|
|
zone_name: record.zone_name,
|
|
created_on: record.created_on,
|
|
modified_on: record.modified_on,
|
|
};
|
|
}
|
|
}
|