Merge branch 'main' of github.com:is-a-dev/register into feat/support-aaaa-records

This commit is contained in:
Akshay Nair
2023-09-17 21:55:21 +05:30
12 changed files with 210 additions and 70 deletions
+1
View File
@@ -1,3 +1,4 @@
node_modules/
*.env.production
*.log
is-a-dev-cert/
+2 -1
View File
@@ -6,6 +6,7 @@
"email": "phenax5@gmail.com"
},
"record": {
"URL": "https://phenax.github.io"
"URL": "https://phenax.github.io",
"TXT": [ "Hello there!", "It's me, Akshay" ]
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"owner": {
"username": "MrBogdanYT",
"email": "hysbskyblockgod@gmail.com"
},
"record": {
"A": ["217.174.245.249"],
"MX": ["hosts.is-a.dev"],
"TXT": "v=spf1 a mx ip4:217.174.245.249 ~all"
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"owner": {
"username": "DenDanskeMine",
"email": "christianhrose@outlook.dk"
},
"record": {
"A": ["217.174.245.249"],
"MX": ["hosts.is-a.dev"],
"TXT": "v=spf1 a mx ip4:217.174.245.249 ~all"
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"owner": {
"username": "NoahPrm",
"email": "noah.parmentier@icloud.com"
},
"record": {
"A": ["185.143.241.106"]
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"owner": {
"username": "npc-123",
"email": "aziznasrul85@gmail.com"
},
"record": {
"A": ["217.174.245.249"],
"MX": ["hosts.is-a.dev"],
"TXT": "v=spf1 a mx ip4:217.174.245.249 ~all"
}
}
+4 -3
View File
@@ -3,8 +3,9 @@
"username": "saumonarcenciel",
"email": "viala38000@gmail.com"
},
"record": {
"A": ["185.143.241.106"]
"A": ["217.174.245.249"],
"MX": ["hosts.is-a.dev"],
"TXT": "v=spf1 a mx ip4:217.174.245.249 ~all"
}
}
}
+4 -2
View File
@@ -6,10 +6,12 @@ echo "AUTH ::[$CERTBOT_VALIDATION]::[$CERTBOT_TOKEN]::[$CERTBOT_REMAINING_CHALLE
echo "[$CERTBOT_DOMAIN]";
sleep 1;
./scripts/certbot.sh acme_txt "$CERTBOT_VALIDATION";
sleep $((5*60));
echo "Going to sleep for a few minutes...";
# TODO: Check if $CERTBOT_VALIDATION == $(./scripts/certbot.sh get-acme)?
sleep $((3*60));
./scripts/certbot.sh check;
+5 -2
View File
@@ -18,7 +18,6 @@ generate_certificate() {
-m 'phenax5@gmail.com' \
-d '*.is-a.dev,is-a.dev' \
--agree-tos \
--dry-run \
$(if_dry_run "--dry-run" "");
echo "+-----------------------------------------------+";
@@ -68,10 +67,14 @@ update_acme_txt_record() {
reset_acme() {
sleep 1;
update_record remove TXT '_acme-challenge' '';
update_record remove TXT '_acme-challenge' '';
}
get_acme() { dig +noall +answer _acme-challenge.is-a.dev TXT | awk '{print $5}'; }
case "$1" in
check) echo "TXT record:: $(dig +noall +answer _acme-challenge.is-a.dev TXT | awk '{print $5}')" ;;
check) echo "TXT record:: $(get_acme)" ;;
get-acme) get_acme ;;
cert) generate_certificate ;;
acme_txt) update_acme_txt_record "$2" ;;
reset) reset_acme ;;
+148 -59
View File
@@ -1,9 +1,18 @@
const R = require('ramda');
const { toHostList, registerDomains } = require('../scripts/register-domains');
const { TTL, DOMAIN_DOMAIN } = require('../utils/constants');
const { getDomainService } = require('../utils/domain-service');
const R = require('ramda')
const { toHostList, registerDomains } = require('../scripts/register-domains')
const { TTL, DOMAIN_DOMAIN } = require('../utils/constants')
const { getDomainService } = require('../utils/domain-service')
const getCpanel = ({ zone, addZone, removeZone, redir, addRedir, removeRedir } = {}) => ({
const getCpanel = ({
zone,
addZone,
removeZone,
redir,
addRedir,
removeRedir,
addEmail,
removeEmail,
} = {}) => ({
zone: {
fetch: (_) => zone(),
add: (rec) => addZone(rec),
@@ -18,7 +27,7 @@ const getCpanel = ({ zone, addZone, removeZone, redir, addRedir, removeRedir } =
add: (rec) => addEmail(rec),
remove: (rec) => removeEmail(rec),
},
});
})
describe('toHostList', () => {
it('should flatten domain data to list of hosts (without https)', () => {
@@ -27,7 +36,7 @@ describe('toHostList', () => {
{ name: 'foobar', record: { CNAME: 'v.io' } },
{ name: 'xx', record: { A: ['1.2.3.4', '5.6.3.2', '1.2.31.1'] } },
{ name: 'xx', record: { CNAME: 'foobar.com', MX: ['as.com', 'f.com'] } },
]);
])
expect(res).toEqual([
{ name: 'akshay', type: 'CNAME', address: 'phenax.github.io', ttl: TTL },
@@ -38,83 +47,163 @@ describe('toHostList', () => {
{ name: 'xx', type: 'CNAME', address: 'foobar.com', ttl: TTL },
{ name: 'xx', type: 'MX', address: 'as.com', priority: 20, ttl: TTL },
{ name: 'xx', type: 'MX', address: 'f.com', priority: 21, ttl: TTL },
]);
});
});
])
})
})
describe('registerDomains', () => {
const addZone = jest.fn(async () => ({}));
const removeZone = jest.fn(async () => ({}));
const addRedir = jest.fn(async () => ({}));
const removeRedir = jest.fn(async () => ({}));
const addEmail = jest.fn(async () => ({}));
const removeEmail = jest.fn(async () => ({}));
const addZone = jest.fn(async () => ({}))
const removeZone = jest.fn(async () => ({}))
const addRedir = jest.fn(async () => ({}))
const removeRedir = jest.fn(async () => ({}))
const addEmail = jest.fn(async () => ({}))
const removeEmail = jest.fn(async () => ({}))
const mockDS = ({ zones, redirections }) => getDomainService({
cpanel: getCpanel({
zone: async () => zones,
redir: async () => redirections,
addZone,
addEmail,
addRedir,
removeZone,
removeRedir,
removeEmail,
const mockDS = ({ zones, redirections }) =>
getDomainService({
cpanel: getCpanel({
zone: async () => zones,
redir: async () => redirections,
addZone,
addEmail,
addRedir,
removeZone,
removeRedir,
removeEmail,
}),
})
});
beforeEach(() => {
addZone.mockClear();
removeZone.mockClear();
addRedir.mockClear();
removeRedir.mockClear();
addEmail.mockClear();
removeEmail.mockClear();
});
addZone.mockClear()
removeZone.mockClear()
addRedir.mockClear()
removeRedir.mockClear()
addEmail.mockClear()
removeEmail.mockClear()
})
it('should register the new set of hosts generated from domains list', async () => {
const localHosts = [
{ name: 'a', record: { CNAME: 'hello' } },
{ name: 'b', record: { CNAME: 'xaa' } },
];
]
const remoteHosts = [
{ line: 1, name: 'a', type: 'CNAME', address: 'hello' },
{ line: 2, name: 'b', type: 'CNAME', address: 'goo' },
{ line: 3, name: 'b', type: 'CNAME', address: 'xaa' },
];
const remoteRedirections = [];
]
const remoteRedirections = []
const domainService = mockDS({ zones: remoteHosts, redirections: remoteRedirections });
await registerDomains({ getDomains: async () => localHosts, domainService });
const domainService = mockDS({
zones: remoteHosts,
redirections: remoteRedirections,
})
await registerDomains({ getDomains: async () => localHosts, domainService })
expect(addZone).toHaveBeenCalledTimes(0);
expect(removeZone).toHaveBeenCalledTimes(1);
expect(addRedir).toHaveBeenCalledTimes(0);
expect(removeRedir).toHaveBeenCalledTimes(0);
});
expect(addZone).toHaveBeenCalledTimes(0)
expect(removeZone).toHaveBeenCalledTimes(1)
expect(addRedir).toHaveBeenCalledTimes(0)
expect(removeRedir).toHaveBeenCalledTimes(0)
})
it('should add the new set hosts', async () => {
const localHosts = [
{ name: 'a', record: { CNAME: 'boo', URL: 'z' } },
{ name: 'b', record: { CNAME: 'xaa', URL: 'x' } },
{ name: 'c', record: { CNAME: 'yello', URL: 'https://google.com' } },
];
{ name: 'a', record: { CNAME: 'boo' } },
{
name: 'b',
record: { A: ['1.1.1.1', '1.1.1.2'], MX: 'somemx', TXT: 'some txt' },
},
{ name: 'c', record: { URL: 'https://google.com' } },
{ name: 'd', record: { CNAME: 'foobar' } },
{ name: 'e', record: { A: ['2.2.2.2'], TXT: ['some', 'extra', 'txt'] } },
]
const remoteHosts = [
{ line: 1, name: 'a', type: 'CNAME', address: 'boo' },
{ line: 2, name: 'b', type: 'CNAME', address: 'xaa' },
];
{ line: 2, name: 'b', type: 'MX', address: 'othermx' },
{ line: 3, name: 'd', type: 'CNAME', address: 'foobaz' },
]
const remoteRedirections = [
{ domain: `b.${DOMAIN_DOMAIN}`, destination: 'x' },
{ domain: `a.${DOMAIN_DOMAIN}`, destination: 'y' },
];
]
const domainService = mockDS({ zones: remoteHosts, redirections: remoteRedirections });
await registerDomains({ getDomains: async () => localHosts, domainService });
const domainService = mockDS({
zones: remoteHosts,
redirections: remoteRedirections,
})
await registerDomains({ getDomains: async () => localHosts, domainService })
expect(addZone).toHaveBeenCalledTimes(1);
expect(removeZone).toHaveBeenCalledTimes(0);
expect(addRedir).toHaveBeenCalledTimes(2);
expect(removeRedir).toHaveBeenCalledTimes(1);
});
});
expect(addZone).toHaveBeenCalledTimes(8)
expect(addZone.mock.calls).toEqual([
[{ name: 'b', type: 'A', address: '1.1.1.1', line: undefined }],
[{ name: 'b', type: 'A', address: '1.1.1.2', line: undefined }],
[
{
name: 'b',
type: 'TXT',
address: 'some txt',
txtdata: 'some txt',
line: undefined,
},
],
[
{
name: 'd',
type: 'CNAME',
cname: 'foobar',
address: 'foobar',
line: undefined,
},
],
[{ name: 'e', type: 'A', address: '2.2.2.2', line: undefined }],
[
{
name: 'e',
type: 'TXT',
address: 'some',
txtdata: 'some',
line: undefined,
},
],
[
{
name: 'e',
type: 'TXT',
address: 'extra',
txtdata: 'extra',
line: undefined,
},
],
[
{
name: 'e',
type: 'TXT',
address: 'txt',
txtdata: 'txt',
line: undefined,
},
],
])
expect(removeZone).toHaveBeenCalledTimes(1)
expect(removeZone.mock.calls).toEqual([[{ line: 3 }]])
expect(addRedir).toHaveBeenCalledTimes(1)
expect(addRedir.mock.calls).toEqual([
[
{
domain: 'c.booboo.xyz',
redirect: 'https://google.com',
redirect_wildcard: 1,
redirect_www: 1,
type: 'permanent',
},
],
])
expect(addEmail).toHaveBeenCalledTimes(1)
expect(addEmail.mock.calls).toEqual([
[{ domain: 'b.is-a.dev', exchanger: 'somemx', priority: 20 }],
])
})
})
+1 -1
View File
@@ -54,7 +54,6 @@ describe('validateDomainData', () => {
{ ...defaultDomain, record: { CNAME: 'foobar.com', A: ['11.22.22.33'] } },
{ ...defaultDomain, record: { CNAME: 'foobar.com', MX: ['ALT4.ASPMX.L.GOOGLE.COM'] } },
...INVALID_NAMES.map(name => ({ ...defaultDomain, name })).slice(0, 1),
{ ...defaultDomain, record: { TXT: ['foobar wow nice!!!'] } },
{ ...defaultDomain, name: 'a.b' },
{ ...defaultDomain, name: 'ww2.baa' },
{ ...defaultDomain, name: 'help.baa' },
@@ -90,6 +89,7 @@ describe('validateDomainData', () => {
{ ...defaultDomain, name: '_github-challenge-phenax.akshay' },
{ ...defaultDomain, name: '_github-challenge-hello01-ga' },
{ ...defaultDomain, name: '_github-challenge-hello01_ga' },
{ ...defaultDomain, record: { TXT: ['foobar wow nice!!!', 'more text'] } },
{ ...defaultDomain, record: { AAAA: ['::1', '2001:db8:3333:4444:5555:6666:7777:8888'] } },
{ ...defaultDomain, record: { A: ['122.222.222.222'] } },
];
+2 -2
View File
@@ -2,7 +2,7 @@ const R = require('ramda');
const { VALID_RECORD_TYPES } = require('./constants');
const { or, and, validate, between, testRegex, withLengthEq, withLengthGte } = require('./helpers');
const INVALID_NAMES = require('./invalid-domains.json');
const { default: ipRegex } = require('ip-regex');
const ipRegex = require('ip-regex');
const isValidURL = and([R.is(String), testRegex(/^https?:\/\//ig)]);
@@ -82,7 +82,7 @@ const validateDomainData = validate({
[R.has('A'), validateARecord('A')],
[R.has('URL'), R.propSatisfies(isValidURL, 'URL')],
[R.has('MX'), validateMXRecord('MX')],
[R.has('TXT'), R.propSatisfies(R.is(String), 'TXT')],
[R.has('TXT'), R.propSatisfies(or([ R.is(String), R.is(Array) ]), 'TXT')],
[R.has('AAAA'), validateAAAARecord('AAAA')],
[R.T, R.T],
]),