Skip to content

Commit

Permalink
Write cloudflare CRUD services
Browse files Browse the repository at this point in the history
  • Loading branch information
yash22arora committed Jun 30, 2024
1 parent 152c991 commit a9cc250
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 24 deletions.
27 changes: 3 additions & 24 deletions server/src/api/routes/subdomain.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import express, { NextFunction, Response } from "express";
import { axiosInstance } from "../../axios";
import { decrypt } from "../../utils/utils";
import { ReservedRecord } from "../models/record";
import { Domain } from "../models/domain";
import { SubdomainCheckRequest } from "./types";
import { cloudflareService } from "../services/cloudflare";

const router = express.Router();

Expand All @@ -29,7 +28,7 @@ router.get(
}

const restrictedSubdomains = [
// "www",
"www",
// "api",
// "app",
// "mail",
Expand Down Expand Up @@ -85,7 +84,7 @@ router.get(
available: false,
});
} else {
const subdomainList = await getSubdomainList(
const subdomainList = await cloudflareService.getSubdomainList(
domain.cfZoneID,
domain.cfAuthToken
);
Expand All @@ -103,24 +102,4 @@ router.get(
}
);

const getSubdomainList = async (cfZoneID: string, cfAuthToken: string) => {
const subdomainList: string[] = [];
await axiosInstance
.get(`/${cfZoneID}/dns_records`, {
headers: {
Authorization: `Bearer ${decrypt(cfAuthToken)}`,
},
})
.then((response) => {
response.data.result.forEach((record: { name: string }) => {
subdomainList.push(record.name);
});
})
.catch((error: any) => {
console.log(error);
});

return subdomainList;
};

export default router;
126 changes: 126 additions & 0 deletions server/src/api/services/cloudflare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Record } from "../models/record";
import { CreateRecordRequest } from "../routes/types";
import { TRecordUpdateConfig } from "../../utils/types";
import { Domain } from "../models/domain";
import { axiosInstance } from "../../axios";
import { decrypt } from "../../utils/utils";

export const cloudflareService = {
createRecord: async (
record: CreateRecordRequest["body"],
ownerID: string
) => {
try {
const domain = await Domain.findOne({ _id: record.domainID }).then(
(res) => res
);

if (!domain) {
throw new Error("Domain not found");
}

const cf_resp = await axiosInstance //TODO: dynamically add zone id and auth token for each domain
.post(
`/${domain.cfZoneID}/dns_records`,
{
type: record.type,
name: record.name,
content: record.content,
ttl: 1,
proxied: false,
comment: `ServDomain: Created by ${ownerID} for ${record.planID} plan`,
},
{
headers: {
Authorization: `Bearer ${decrypt(domain.cfAuthToken)}`,
},
}
)
.then((resp) => resp.data);

return cf_resp;
} catch (err) {
console.log(err);
return err;
}
},
getSubdomainList: async (cfZoneID: string, cfAuthToken: string) => {
const subdomainList: string[] = [];
try {
await axiosInstance
.get(`/${cfZoneID}/dns_records`, {
headers: {
Authorization: `Bearer ${decrypt(cfAuthToken)}`,
},
})
.then((response) => {
response.data.result.forEach((record: { name: string }) => {
subdomainList.push(record.name);
});
});
return subdomainList;
} catch (error: any) {
console.error(error);
return error;
}
},
deleteRecord: async (recordID: string) => {
try {
const record = await Record.findOne({ _id: recordID }).then((res) => res);
const domain = await Domain.findOne({ _id: record?.domainID }).then(
(res) => res
);

if (!record || !domain) {
throw new Error("Record or Domain not found");
}

const cf_resp = await axiosInstance
.delete(`/${domain.cfZoneID}/dns_records/${record.cloudflareID}`, {
headers: {
Authorization: `Bearer ${decrypt(domain.cfAuthToken)}`,
},
})
.then((resp) => resp.data);

return cf_resp;
} catch (err) {
console.log(err);
return err;
}
},
updateRecord: async (recordID: string, recordConfig: TRecordUpdateConfig) => {
try {
const record = await Record.findOne({ _id: recordID }).then((res) => res);
const domain = await Domain.findOne({ _id: record?.domainID }).then(
(res) => res
);

if (!record || !domain) {
throw new Error("Record or Domain not found");
}

const cf_resp = await axiosInstance
.put(
`/${domain.cfZoneID}/dns_records/${record.cloudflareID}`,
{
type: recordConfig.type || record.type,
content: recordConfig.content || record.content,
ttl: recordConfig.ttl || record.ttl,
proxied: recordConfig.proxied || record.proxied,
},
{
headers: {
Authorization: `Bearer ${decrypt(domain.cfAuthToken)}`,
},
}
)
.then((resp) => resp.data);

return cf_resp;
} catch (err) {
console.log(err);
return err;
}
},
};
7 changes: 7 additions & 0 deletions server/src/utils/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,10 @@ export type TPlanStatus =
| "expired"
| "cancelled"
| "overdue";

export type TRecordUpdateConfig = {
content?: string;
proxied?: boolean;
ttl?: number;
type?: TRecordType;
};

0 comments on commit a9cc250

Please sign in to comment.