Created
November 19, 2019 11:21
-
-
Save zanonnicola/ac7e78dfc0bc26fc79a745191a6c94f0 to your computer and use it in GitHub Desktop.
Credit Card Validation for VueJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const mustBeValidDateFormat = (value: string): boolean => /^[0-9.\/]+$/i.test(value); | |
const mustBeValidMonth = (value: string): boolean => { | |
const [month] = value.split('/'); | |
if (!/^\d*$/.test(month)) { return false; } | |
const inputMonth = parseInt(month, 10); | |
return inputMonth > 0 && inputMonth < 13; | |
}; | |
const mustBeValidYear = (value: string): boolean => { | |
const [_, year] = value.split('/'); | |
const currentYear = new Date().getFullYear(); | |
if (typeof year === 'undefined') { return false; } | |
if (year.length !== 4) { return false; } | |
if (!/^\d*$/.test(year)) { return false; } | |
const y = parseInt(year, 10); | |
// Amazon goes 20 years into the future | |
const MAX_YEARS_IN_THE_FUTURE = 20; | |
return y >= currentYear && y <= currentYear + MAX_YEARS_IN_THE_FUTURE; | |
}; | |
const mustNotBeExpired = (value: string): boolean => { | |
const [month, year] = value.split('/'); | |
if (typeof year === 'undefined' || typeof month === 'undefined') { return false; } | |
const currentYear = new Date().getFullYear(); | |
const currentMonth = new Date().getMonth() + 1; | |
const parsedYear = parseInt(year, 10); | |
const parsedMonth = parseInt(month, 10); | |
if (parsedYear === currentYear) { | |
return parsedMonth >= currentMonth; | |
} else { | |
return parsedYear >= currentYear; | |
} | |
}; | |
const mustBeValidName = (value: string): boolean => /^[^\d]+$/i.test(value); | |
const mustBeValidCardNumber = (value: string): boolean => { | |
if (!value) { return false; } | |
if (!/^[\d\s\-]+$/.test(value)) { return false; } | |
const cc = value.replace(/\-|\s/g, ''); | |
// The Luhn Algorithm | |
// https://medium.com/@ma.juber/mathematics-behind-credit-debit-card-numbering-340bf68d27d2 | |
let i = cc.length - 1; | |
let bit = false; | |
let sum = 0; | |
let val: number; | |
while (i >= 0) { | |
val = parseInt(cc.charAt(i), 10); | |
if (bit) { | |
val *= 2; | |
if (val > 9) { | |
val = (val % 10) + 1; // eslint-disable-line no-extra-parens | |
} | |
} | |
bit = !bit; | |
sum += val; | |
i--; | |
} | |
return sum % 10 === 0; | |
}; | |
// Shamelessly stolen from: https://gist.github.com/maximkott/31dfdd37d4c0fee499de453faca17c83 | |
const applyDateMask = (value: string, mask: string, maskPatterns: { [key: string]: RegExp }): string => { | |
value = value || ''; | |
mask = mask || ''; | |
maskPatterns = maskPatterns || {}; | |
let maskedValue = ''; | |
const valueParts = value.split(''); | |
const maskParts = mask.split(''); | |
while (valueParts.length > 0) { | |
let unmaskedChar = valueParts.shift(); | |
while (unmaskedChar !== null) { | |
const maskChar = maskParts.shift(); | |
if (maskChar !== undefined) { | |
const maskPattern = maskPatterns[maskChar.toUpperCase()]; | |
if (maskPattern !== undefined) { | |
let check = false; | |
if (maskPattern instanceof RegExp) { | |
check = maskPattern.test(unmaskedChar); | |
} | |
if (check) { | |
maskedValue += unmaskedChar; | |
} else { | |
maskParts.unshift(maskChar); | |
} | |
unmaskedChar = null; | |
} else { | |
maskedValue += maskChar; | |
} | |
} else { | |
unmaskedChar = null; | |
} | |
} | |
} | |
return maskedValue; | |
}; | |
const removeDateMask = (cardDate: string): string => { | |
return cardDate.replace('/', ''); | |
}; | |
export { | |
mustBeValidDateFormat, | |
mustBeValidName, | |
mustBeValidCardNumber, | |
mustNotBeExpired, | |
applyDateMask, | |
removeDateMask, | |
mustBeValidMonth, | |
mustBeValidYear | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment