{"version":3,"file":"/Users/anthonygubler/development/dojo-org/widgets/src/middleware/validation.tsx","sourceRoot":"","sources":["validation.tsx"],"names":[],"mappings":"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","sourcesContent":["import bundle from './validation.nls';\nimport { create } from '@dojo/framework/core/vdom';\nimport i18n from '@dojo/framework/core/middleware/i18n';\n\nconst upperCaseRegEx = /[A-Z]/;\nconst numbersRegEx = /\\d/;\n\ninterface LengthMin {\n\tmin: number;\n\tmax?: number;\n}\n\ninterface LengthMax {\n\tmin?: number;\n\tmax: number;\n}\n\ninterface ContainsUppercase {\n\tuppercase: number;\n\tnumbers?: number;\n\tspecialCharacters?: number;\n}\n\ninterface ContainsNumbers {\n\tuppercase?: number;\n\tnumbers: number;\n\tspecialCharacters?: number;\n}\n\ninterface ContainsSpecialCharacters {\n\tuppercase?: number;\n\tnumbers?: number;\n\tspecialCharacters: number;\n}\n\ntype ContainsRules =\n\t| ContainsUppercase\n\t| ContainsNumbers\n\t| ContainsSpecialCharacters\n\t| (ContainsUppercase & ContainsNumbers & ContainsSpecialCharacters);\n\ninterface LengthRule {\n\tlength: LengthMin | LengthMax | (LengthMin & LengthMax);\n}\n\ninterface ContainsRule {\n\tcontains: ({ atLeast?: number }) & ContainsRules;\n}\n\nexport type ValidationRules = RequireAtLeastOne<LengthRule & ContainsRule>;\n\ntype RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &\n\t{ [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>> }[Keys];\n\n/* OWASP Special Characters: https://www.owasp.org/index.php/Password_special_characters */\nconst specialCharactersRegEx = new RegExp(\n\t[\n\t\t' ',\n\t\t'!',\n\t\t'\"',\n\t\t'#',\n\t\t'\\\\$',\n\t\t'%',\n\t\t'&',\n\t\t\"'\",\n\t\t'\\\\(',\n\t\t'\\\\)',\n\t\t'\\\\*',\n\t\t'\\\\+',\n\t\t',',\n\t\t'-',\n\t\t'\\\\.',\n\t\t'/',\n\t\t':',\n\t\t';',\n\t\t'<',\n\t\t'=',\n\t\t'>',\n\t\t'\\\\?',\n\t\t'@',\n\t\t'\\\\[',\n\t\t'\\\\\\\\',\n\t\t'\\\\]',\n\t\t'\\\\^',\n\t\t'_',\n\t\t'`',\n\t\t'{',\n\t\t'\\\\|',\n\t\t'}',\n\t\t'~'\n\t].join('|')\n);\n\ntype ValidationType<T> = {\n\t[P in keyof T]: {\n\t\tvalidate: (\n\t\t\trules: NonNullable<T[P]>,\n\t\t\tvalue: string\n\t\t) => { valid?: boolean; message?: string } | void;\n\t\tdescribe: (rules: NonNullable<T[P]>) => string[];\n\t}\n};\n\nconst validationFactory = create({ i18n });\nconst validation = validationFactory(function validation({ middleware: { i18n } }) {\n\tconst { format } = i18n.localize(bundle);\n\n\tfunction formatList(atLeast: number | undefined, list: string[]) {\n\t\tconst fixedList = [...list];\n\n\t\tif (list.length > 1) {\n\t\t\tif (atLeast) {\n\t\t\t\tfixedList[fixedList.length - 1] = format('or', {\n\t\t\t\t\trule: fixedList[fixedList.length - 1]\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tfixedList[fixedList.length - 1] = format('and', {\n\t\t\t\t\trule: fixedList[fixedList.length - 1]\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (fixedList.length === 1 && !atLeast) {\n\t\t\treturn format('mustContain', { rules: fixedList[0] });\n\t\t}\n\n\t\treturn format('mustContain', {\n\t\t\trules: format(atLeast ? 'atLeastOf' : 'allOf', {\n\t\t\t\tcount: atLeast,\n\t\t\t\trules: fixedList.join(', ')\n\t\t\t})\n\t\t});\n\t}\n\n\tconst validators: ValidationType<Required<ValidationRules>> = {\n\t\tlength: {\n\t\t\tvalidate: ({ min, max }, value) => {\n\t\t\t\tif (min !== undefined) {\n\t\t\t\t\tif (value.length < min) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\t\tmessage: format('minimumLength', { length: min })\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (max !== undefined) {\n\t\t\t\t\tif (value.length > max) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\t\tmessage: format('maximumLength', { length: max })\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdescribe: ({ min, max }) => {\n\t\t\t\tconst limits: string[] = [];\n\n\t\t\t\tif (min !== undefined) {\n\t\t\t\t\tlimits.push(format('minimumLength', { length: min }));\n\t\t\t\t}\n\n\t\t\t\tif (max !== undefined) {\n\t\t\t\t\tlimits.push(format('maximumLength', { length: max }));\n\t\t\t\t}\n\n\t\t\t\treturn limits;\n\t\t\t}\n\t\t},\n\t\tcontains: {\n\t\t\tvalidate: ({ atLeast, uppercase = 0, numbers = 0, specialCharacters = 0 }, value) => {\n\t\t\t\tconst failures: string[] = [];\n\t\t\t\tlet uppercaseTotal = 0;\n\t\t\t\tlet numberTotal = 0;\n\t\t\t\tlet specialTotal = 0;\n\t\t\t\tlet containsAtLeast = atLeast || 0;\n\t\t\t\tlet successes = 0;\n\n\t\t\t\tif (atLeast === undefined) {\n\t\t\t\t\tcontainsAtLeast =\n\t\t\t\t\t\t(uppercase ? 1 : 0) + (numbers ? 1 : 0) + (specialCharacters ? 1 : 0);\n\t\t\t\t}\n\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tconst c = value.charAt(i);\n\n\t\t\t\t\tuppercaseTotal += uppercase && upperCaseRegEx.test(c) ? 1 : 0;\n\t\t\t\t\tnumberTotal += numbers && numbersRegEx.test(c) ? 1 : 0;\n\t\t\t\t\tspecialTotal += specialCharacters && specialCharactersRegEx.test(value) ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\tif (uppercaseTotal < uppercase) {\n\t\t\t\t\tfailures.push(\n\t\t\t\t\t\tformat('uppercase', {\n\t\t\t\t\t\t\tcount: uppercase\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t} else if (uppercase) {\n\t\t\t\t\tsuccesses++;\n\t\t\t\t}\n\n\t\t\t\tif (numberTotal < numbers) {\n\t\t\t\t\tfailures.push(\n\t\t\t\t\t\tformat('numbers', {\n\t\t\t\t\t\t\tcount: numbers\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t} else if (numbers) {\n\t\t\t\t\tsuccesses++;\n\t\t\t\t}\n\n\t\t\t\tif (specialTotal < specialCharacters) {\n\t\t\t\t\tfailures.push(\n\t\t\t\t\t\tformat('specialCharacters', {\n\t\t\t\t\t\t\tcount: specialCharacters\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t} else if (specialCharacters) {\n\t\t\t\t\tsuccesses++;\n\t\t\t\t}\n\n\t\t\t\tif (successes < containsAtLeast) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\tmessage: formatList(\n\t\t\t\t\t\t\tatLeast ? containsAtLeast - successes : undefined,\n\t\t\t\t\t\t\tfailures\n\t\t\t\t\t\t)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t},\n\t\t\tdescribe: ({ atLeast, uppercase, numbers, specialCharacters }) => {\n\t\t\t\tlet types: string[] = [];\n\n\t\t\t\tif (uppercase) {\n\t\t\t\t\ttypes.push(\n\t\t\t\t\t\tformat('uppercase', {\n\t\t\t\t\t\t\tcount: uppercase\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (numbers) {\n\t\t\t\t\ttypes.push(\n\t\t\t\t\t\tformat('numbers', {\n\t\t\t\t\t\t\tcount: numbers\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (specialCharacters) {\n\t\t\t\t\ttypes.push(\n\t\t\t\t\t\tformat('specialCharacters', {\n\t\t\t\t\t\t\tcount: specialCharacters\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn [formatList(atLeast, types)];\n\t\t\t}\n\t\t}\n\t};\n\n\treturn (rules: ValidationRules) => {\n\t\tfunction validator(value: string) {\n\t\t\tconst failedResults = (Object.keys(rules) as (keyof ValidationRules)[])\n\t\t\t\t.map(\n\t\t\t\t\t(rule) =>\n\t\t\t\t\t\tvalidators[rule] && validators[rule].validate(rules[rule] as any, value)\n\t\t\t\t)\n\t\t\t\t.filter((result) => result && !result.valid);\n\n\t\t\tif (failedResults.length) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\tmessage: failedResults.map((result) => (result ? result.message : '')).join(' ')\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tvalidator.describe = () =>\n\t\t\t(Object.keys(rules) as (keyof ValidationRules)[]).reduce(\n\t\t\t\t(prev, rule) => [...prev, ...validators[rule].describe(rules[rule] as any)],\n\t\t\t\t[] as string[]\n\t\t\t);\n\n\t\treturn validator;\n\t};\n});\n\nexport default validation;\n"]}