Skip to content

Commit

Permalink
Fix duplicates v1 txt records (#24)
Browse files Browse the repository at this point in the history
* fix duplicate txt record

* remove provider from readme and sample env

* use cloudflare api to search instead of doh
  • Loading branch information
chdwlch authored Jul 16, 2024
1 parent 0a50893 commit c79bfb9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 102 deletions.
6 changes: 0 additions & 6 deletions .env.local.sample
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# Digital Ocean personal access token
DO_TOKEN="abcd1234"

# CloudFlare API Token
CF_TOKEN="abcd1234"
CF_DOMAIN_ID="abcd1234"

# DNS Provider (digitalocean, cloudflare), use cloudflare for DNSSEC
PROVIDER="cloudflare"

# Must be the root domain, not a subdomain, e.g. "example.com" and not "subdomain.example.com"
DOMAIN="12cash.dev"

Expand Down
7 changes: 1 addition & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,7 @@ You can use this tool with Cloudflare or Digital OCean DNS. However, if you want

- Setup your domain with DNSSEC - [Docs](https://developers.cloudflare.com/dns/dnssec/)
- Create an API token in Cloudflare, giving it access to your domain name
- In the .env file, set `PROVIDER="cloudflare"` and add your Cloudflare API token and domain ID (which you can find by clicking on your domain name in Cloudflare and scrolling down the page)

### Digital Ocean

- Create a personal access token on Digital Ocean and add it to .env.local
- In the .env file, set `PROVIDER="digitalocean"` and add your Digital Ocean API token
- In the .env file, add your Cloudflare API token and domain ID (which you can find by clicking on your domain name in Cloudflare and scrolling down the page)

### Running the Dev Server

Expand Down
137 changes: 47 additions & 90 deletions src/app/record/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { Content } from "next/font/google";
import { NextRequest, NextResponse } from "next/server";
const axios = require("axios").default;



export async function POST(req: NextRequest) {
let localPart: string, bolt12: string;

Expand All @@ -27,106 +24,66 @@ export async function POST(req: NextRequest) {

// Begin assembling DNS name
const fullName = process.env.NETWORK
? localPart + ".user._bitcoin-payment." + process.env.NETWORK
: localPart + ".user._bitcoin-payment";

// Digital Ocean
if(process.env.PROVIDER !== "cloudflare") {
const DO_URL = `https://api.digitalocean.com/v2/domains/${process.env.DOMAIN}/records`;
const config = {
headers: { Authorization: `Bearer ${process.env.DO_TOKEN}` },
};
? `${localPart}.user._bitcoin-payment.${process.env.NETWORK}.${process.env.DOMAIN}`
: `${localPart}.user._bitcoin-payment.${process.env.DOMAIN}`;


const queryParams = `?type=TXT&name=${fullName}.${process.env.DOMAIN}`;
const query = `${DO_URL}${queryParams}`;

try {
const res = await axios.get(query, config);
console.debug("query res.data", res.data);
console.debug("query res.data.domain_records", res.data.domain_records);
if (
res.data.domain_records.length !== 0 &&
res.data.domain_records[0].name === localPart
) {
return NextResponse.json({ message: "Name is taken." }, { status: 409 });
}
} catch (error: any) {
console.error("error", error);
return NextResponse.json(
{
message: "Failed to create Paycode.",
},
{ status: 400 }
);
}

const data = {
type: "TXT",
name: fullName,
data: "bitcoin:?lno=" + bolt12,
priority: null,
port: null,
ttl: 1800,
weight: null,
flags: null,
tag: null,
};

try {
const res = await axios.post(DO_URL, data, config);
console.debug(res.data);
} catch (error: any) {
const CF_URL = `https://api.cloudflare.com/client/v4/zones/${process.env.CF_DOMAIN_ID}/dns_records?name=${fullName}&type=TXT`;
// First check to see if this record name already exists
try {
const res = await axios.get(CF_URL, {
headers: {
Content_Type: "application/json",
Authorization: `Bearer ${process.env.CF_TOKEN}`,
},
});
if (res.data.result.length > 0) {
return NextResponse.json(
{ message: "Failed to create Paycode." },
{ status: 400 }
{ message: "Name is already taken." },
{ status: 409 }
);
}

} catch (e: any) {
return NextResponse.json(
{ message: "Bolt12 Address Created" },
{ status: 201 }
{ message: "Failed to lookup paycode." },
{ status: 400 }
);
}
// Cloudflare
else {
const CF_URL = `https://api.cloudflare.com/client/v4/zones/${process.env.CF_DOMAIN_ID}/dns_records/`;

const config = {
method: "POST",
headers: {
Content_Type: "application/json",
Authorization: `Bearer ${process.env.CF_TOKEN}`
}
};

const data = {
content: "bitcoin:?lno=" + bolt12,
name: `${fullName}.${process.env.DOMAIN}`,
proxied: false,
type: "TXT",
comment: "Twelve Cash User DNS Update",
ttl: 3600
};
const config = {
method: "POST",
headers: {
Content_Type: "application/json",
Authorization: `Bearer ${process.env.CF_TOKEN}`,
},
};

try {
const res = await axios.post(CF_URL, data, config);
console.debug(res.data);
} catch (error: any) {
let message = "Failed to create Paycode."
if(error.response.data.errors[0].code === 81058) {
message = "Name is already taken."
}
const data = {
content: "bitcoin:?lno=" + bolt12,
name: fullName,
proxied: false,
type: "TXT",
comment: "Twelve Cash User DNS Update",
ttl: 3600,
};

try {
const res = await axios.post(CF_URL, data, config);
console.debug(res.data);
} catch (error: any) {
if (error.response.data.errors[0].code === 81058) {
return NextResponse.json(

{ message: message },
{ status: 400 }
{ message: "Name is already taken." },
{ status: 409 }
);
}

return NextResponse.json(
{ message: "Bolt12 Address Created" },
{ status: 201 }
{ message: "Failed to create Paycode." },
{ status: 400 }
);
}

return NextResponse.json(
{ message: "Bolt12 Address Created" },
{ status: 201 }
);
}

0 comments on commit c79bfb9

Please sign in to comment.