Skip to content

Commit

Permalink
feat: Add the 'Preferred-Languages' directive (#53)
Browse files Browse the repository at this point in the history
The preferredLanguages key implements the Preferred-Languages directive. It can be passed a comma delimited string, or an array that will be converted into one.

#50
  • Loading branch information
joker314 authored Jan 10, 2019
1 parent 16ca1a2 commit 019cfdc
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
28 changes: 28 additions & 0 deletions __tests__/formatPolicy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,31 @@ test('uses new spelling with deprecated keys', () => {

expect(global.console.warn).toHaveBeenCalled()
})

test('preferredLanguages directive works with multiple values', () => {
const options = {
contact: 'mailto:[email protected]',
preferredLanguages: ['en', 'ru', 'es']
}

const res = securityTxt.formatSecurityPolicy(options)

expect(res).toBe(
'Contact: mailto:[email protected]\n' +
'Preferred-Languages: en, ru, es\n'
)
})

test('preferredLanguages directive works with one value only', () => {
const options = {
contact: 'mailto:[email protected]',
preferredLanguages: 'en'
}

const res = securityTxt.formatSecurityPolicy(options)

expect(res).toBe(
'Contact: mailto:[email protected]\n' +
'Preferred-Languages: en\n'
)
})
32 changes: 32 additions & 0 deletions __tests__/validatePolicy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,35 @@ test('using both deprecated spelling and new spelling throws', () => {

expect(() => securityTxt.validatePolicyFields(options)).toThrow()
})

test('validate successfully for the preferredLanguages key', () => {
const optionsWithArray = {
contact: '...',
preferredLanguages: ['en', 'es']
}

const optionsWithString = {
contact: '...',
preferredLanguages: 'ru'
}

const optionsWithComment = {
contact: '...',
preferredLanguages: { comment: 'I am fluent in these', value: ['en', 'ru'] }
}

expect(() => securityTxt.validatePolicyFields(optionsWithArray)).not.toThrow()
expect(() => securityTxt.validatePolicyFields(optionsWithString)).not.toThrow()
expect(() => securityTxt.validatePolicyFields(optionsWithComment)).not.toThrow()
})

test('validate fails if Array<object> fed to preferredLanguages', () => {
const options = {
contact: '...',
preferredLanguages: [
{ comment: '...', value: 'en' }
]
}

expect(() => securityTxt.validatePolicyFields(options).toThrow())
})
11 changes: 10 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const Joi = require('joi')
const DIRECTIVES = ['Contact', 'Encryption', 'Acknowledgments', 'Signature', 'Policy', 'Hiring', 'Permission']
const DIRECTIVES = ['Contact', 'Encryption', 'Acknowledgments', 'Preferred-Languages', 'Signature', 'Policy', 'Hiring', 'Permission']

/**
* @TODO Fully remove outdated spelling in breaking changes
Expand Down Expand Up @@ -104,6 +104,14 @@ class middleware {
value = [ value ]
}

// For the other fields, arrays are used to represent multiple occurences
// of a field. However, for the Preferred-Language: directive, an array shows
// a comma separated list. Convert the provided array into an array of one
// value: a string with commas.
if (outputDirective === 'Preferred-Languages') {
value = [ value.map(languageCode => languageCode.trim()).join(', ') ]
}

value.forEach(valueOption => {
if (valueOption.hasOwnProperty('value')) {
if (valueOption.hasOwnProperty('comment')) {
Expand Down Expand Up @@ -187,6 +195,7 @@ class middleware {
contact: fieldValue({ required: true }),
permission: fieldValue({ canBeArray: false, singleValue: string.only('none').insensitive() }),
encryption: fieldValue({ singleValue: string.regex(/^(?!http:)/i) }),
preferredLanguages: fieldValue({ canBeArray: false, singleValue: array.items(string) }),
policy: fieldValue(),
hiring: fieldValue(),
signature: fieldValue({ canBeArray: false }),
Expand Down

0 comments on commit 019cfdc

Please sign in to comment.