From 408b542ae741faacfe35bfec27a309d8327c0dec Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Wed, 14 Oct 2020 18:38:17 +0530 Subject: [PATCH 1/2] Adds cname record validation --- tests/domain-utils.test.js | 2 ++ utils/domain.js | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/domain-utils.test.js b/tests/domain-utils.test.js index 8dfbbacb8..d3a1357f0 100644 --- a/tests/domain-utils.test.js +++ b/tests/domain-utils.test.js @@ -34,6 +34,8 @@ describe('validateDomainData', () => { { ...defaultDomain, owner: {}, }, { ...defaultDomain, owner: { username: 'hwelo', }, }, { ...defaultDomain, owner: { email: 'hwelo' }, }, + { ...defaultDomain, record: { CNAME: 'http://foobar.com' } }, + { ...defaultDomain, record: { CNAME: 'https://foobar.com' } }, ]; const validCases = [ diff --git a/utils/domain.js b/utils/domain.js index f7819f02a..e56c59fab 100644 --- a/utils/domain.js +++ b/utils/domain.js @@ -17,6 +17,7 @@ const getDomains = () => }))); const between = (min, max) => num => num >= min && num <= max; +const testRegex = regex => str => !!(str && str.match(regex)); const validate = pattern => data => R.compose( invalidPairs => invalidPairs.length ? { errors: invalidPairs, valid: false } : { errors: [], valid: true }, @@ -24,9 +25,10 @@ const validate = pattern => data => R.compose( R.toPairs, )(pattern); -const validateNameRecord = type => R.allPass([ - R.compose(R.equals(1), R.length, R.reject(R.equals('URL')), R.keys), +const validateCnameRecord = type => R.allPass([ R.propSatisfies(R.is(String), type), + R.compose(R.equals(1), R.length, R.reject(R.equals('URL')), R.keys), + R.propSatisfies(R.complement(testRegex(/^https?:\/\//ig)), type), ]); const validateDomainData = validate({ @@ -36,7 +38,7 @@ const validateDomainData = validate({ R.equals('@'), R.allPass([ R.compose(between(2, 100), R.length), - str => str && str.match(/^[a-z0-9\-]+$/ig), + testRegex(/^[a-z0-9\-]+$/g), ]) ]), }, @@ -54,12 +56,12 @@ const validateDomainData = validate({ ]), }, record: { - reason: 'Invalid record', + reason: 'Invalid record. CNAME records have to be a host name and A records has to be a list of ips', fn: R.allPass([ R.is(Object), R.compose(R.isEmpty, R.flip(R.difference)(VALID_RECORD_TYPES), R.keys), R.cond([ - [R.prop('CNAME'), validateNameRecord('CNAME')], + [R.prop('CNAME'), validateCnameRecord('CNAME')], [R.prop('A'), R.propSatisfies(R.is(Array), 'A')], [R.prop('URL'), R.propSatisfies(R.is(String), 'URL')], [R.T, R.T], From c242535a511231ea954c07a9d9a201ba6f518b8c Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Wed, 14 Oct 2020 18:43:27 +0530 Subject: [PATCH 2/2] improves a record validation --- tests/domain-utils.test.js | 2 ++ utils/domain.js | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/domain-utils.test.js b/tests/domain-utils.test.js index d3a1357f0..ad231b281 100644 --- a/tests/domain-utils.test.js +++ b/tests/domain-utils.test.js @@ -31,6 +31,8 @@ describe('validateDomainData', () => { })), { ...defaultDomain, record: { CNAME: 'sd', A: ['121,3213'] } }, { ...defaultDomain, record: { A: ['121', '12'], FOOBAR: ['sd'] } }, + { ...defaultDomain, record: { A: [] } }, + { ...defaultDomain, record: { A: ['11122'], URL: 'foobar' } }, { ...defaultDomain, owner: {}, }, { ...defaultDomain, owner: { username: 'hwelo', }, }, { ...defaultDomain, owner: { email: 'hwelo' }, }, diff --git a/utils/domain.js b/utils/domain.js index e56c59fab..452aab658 100644 --- a/utils/domain.js +++ b/utils/domain.js @@ -25,10 +25,15 @@ const validate = pattern => data => R.compose( R.toPairs, )(pattern); -const validateCnameRecord = type => R.allPass([ - R.propSatisfies(R.is(String), type), +const validateCnameRecord = key => R.allPass([ + R.propSatisfies(R.is(String), key), R.compose(R.equals(1), R.length, R.reject(R.equals('URL')), R.keys), - R.propSatisfies(R.complement(testRegex(/^https?:\/\//ig)), type), + R.propSatisfies(R.complement(testRegex(/^https?:\/\//ig)), key), +]); + +const validateARecord = key => R.allPass([ + R.compose(R.equals(1), R.length, R.keys), + R.propSatisfies(R.compose(R.gte(R.__, 1), R.length), key), ]); const validateDomainData = validate({ @@ -62,7 +67,7 @@ const validateDomainData = validate({ R.compose(R.isEmpty, R.flip(R.difference)(VALID_RECORD_TYPES), R.keys), R.cond([ [R.prop('CNAME'), validateCnameRecord('CNAME')], - [R.prop('A'), R.propSatisfies(R.is(Array), 'A')], + [R.prop('A'), validateARecord('A')], [R.prop('URL'), R.propSatisfies(R.is(String), 'URL')], [R.T, R.T], ]),