diff --git a/README.md b/README.md index 4ccd2b1..b5db6c6 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,22 @@ Rules supported as of now are: The following options can be passed to `validate` method: * `list` - If set, validate method returns a list of rules which failed instead of true/false. +## Character Support +This package comes with a basic support for many common charsets. Eventhough it can not be fully relied upon regarding every language and sign there is. If you see something missing please consider contributing it via a pull request. + +Supported Letters: +* [Basic Latin](https://www.unicode.org/charts/PDF/U0000.pdf) +* [Latin-1 Supplement](https://www.unicode.org/charts/PDF/U0080.pdf) +* [Latin Extended-A](https://www.unicode.org/charts/PDF/U0100.pdf) +* [Latin Extended-B](https://www.unicode.org/charts/PDF/U0180.pdf) +* [Latin Extended Additional](https://www.unicode.org/charts/PDF/U1E00.pdf) +* [Greek and Coptic](https://www.unicode.org/charts/PDF/U0370.pdf) +* [Greek Extended](https://www.unicode.org/charts/PDF/U1F00.pdf) +* [Cyrillic](https://www.unicode.org/charts/PDF/U0400.pdf) +* [CJK](https://www.unicode.org/charts/PDF/U4E00.pdf) + + + ## Resources * API Reference - [latest](https://tarunbatra.github.io/password-validator) diff --git a/src/constants.js b/src/constants.js index b598df9..9339bae 100644 --- a/src/constants.js +++ b/src/constants.js @@ -5,7 +5,42 @@ module.exports = { }, regex: { digits: '(\\d.*)', - letters: '([a-zA-Z].*)', + letters: [ + '([', + + // Basic Latin + '\\u{0041}-\\u{005A}', // A-Z + '\\u{0061}-\\u{007A}', // a-z + + // Latin-1 Supplement + '\\u{00C0}-\\u{00D6}', // À-Ö + '\\u{00D8}-\\u{00DE}', // Ø-Þ + '\\u{00DF}-\\u{00F6}', // ß-ö + '\\u{00F8}-\\u{00FF}', // ø-ÿ + + // Latin Extended-A + '\\u{0100}-\\u{017F}', // Ā-ſ + + // Latin Extended-B + '\\u{0180}-\\u{024F}', // ƀ-ɏ + + // Latin Extended Additional + '\\u{1E02}-\\u{1EF3}', // Ḃ-ỳ + + // Greek and Coptic + '\\u{0370}-\\u{03FF}', // Ͱ-Ͽ + + // Greek Extended + '\\u{1F00}-\\u{1FFF}', // ἀ- + + // Cyrillic + '\\u{0400}-\\u{04FF}', // Ѐ-ӿ + + // CJK + '\\u{4E00}-\\u{9FFC}', + + '].*)' + ].join(''), symbols: '([`~\\!@#\\$%\\^\\&\\*\\(\\)\\-_\\=\\+\\[\\\{\\}\\]\\\\\|;:\\\'",<.>\\/\\?€£¥₹§±].*)', spaces: '([\\s].*)' } diff --git a/src/lib.js b/src/lib.js index a1d7c06..16e1822 100644 --- a/src/lib.js +++ b/src/lib.js @@ -7,12 +7,12 @@ */ var regex = require('./constants').regex; -function _process(regexp, repeat) { +function _process(regexp, repeat, flags) { if (repeat && repeat > 1) { const parsedRepeat = parseInt(repeat, 10); - return new RegExp(regexp + '{' + parsedRepeat + ',}').test(this.password) === this.positive; + return new RegExp(regexp + '{' + parsedRepeat + ',}', flags || '').test(this.password) === this.positive; } - return new RegExp(regexp).test(this.password) === this.positive; + return new RegExp(regexp, flags || '').test(this.password) === this.positive; } module.exports = { @@ -86,7 +86,7 @@ module.exports = { * @param {number} repeat - count of required letters */ letters: function letters(repeat) { - return _process.call(this, regex.letters, repeat); + return _process.call(this, regex.letters, repeat, 'u'); }, /** diff --git a/tests/index.test.js b/tests/index.test.js index 14bfd92..f1b976b 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -437,6 +437,72 @@ describe('password-validator', function () { } }); }); + + describe('the password clears for all uppercase Basic Latin', function () { + + beforeEach(function () { + schema = new Schema(); + schema.letters(26); + valid = schema.validate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + }); + + it('should return true on validation', function () { + expect(valid).to.be.true; + }); + }); + + describe('the password clears for all lowercase Basic Latin', function () { + + beforeEach(function () { + schema = new Schema(); + schema.letters(26); + valid = schema.validate('abcdefghijklmnopqrstuvwxyz'); + }); + + it('should return true on validation', function () { + expect(valid).to.be.true; + }); + }); + + describe('the password fails for digits', function () { + + beforeEach(function () { + schema = new Schema(); + schema.letters(); + valid = schema.validate('0123456789'); + }); + + it('should return true on validation', function () { + expect(valid).to.be.false; + }); + }); + + describe('the password fails for symbols', function () { + + beforeEach(function () { + schema = new Schema(); + schema.letters(); + valid = schema.validate('`~!@#$%^&*()-_=+[{}]|;:\'",<.>\/?€£¥₹§±'); + }); + + it('should return true on validation', function () { + expect(valid).to.be.false; + }); + }); + + describe('the password fails for spaces', function () { + + beforeEach(function () { + schema = new Schema(); + schema.letters(); + valid = schema.validate(' '); + }); + + it('should return true on validation', function () { + expect(valid).to.be.false; + }); + }); + }); describe('lowercase', function () {