Here is my test and code snippet:
// this test is failing
describe('for type email', () => {
describe('given correct email', () => {
const email = '[email protected]';
it('given type url', () => expect(isValueTypeViolated(email, 'url')).toBe(true));
});
});
// here is my code
export const isValueTypeViolated = (value, type) => {
switch(type) {
case 'email': return !isEmail(value);
case 'url': return !isURL(value);
case 'number': return !isNumber(value);
default: return false;
}
}
export const isURL = (value) => validator.isURL(value);
Hello ankitrg,
it seems to be a problem (logical error) with the validator.js's code. It's true that validator.isURL("[email protected]") returns true and I think that in "test/validator.js" there aren't any tests that check email-like strings for validation. The problem may start from here: https://github.com/chriso/validator.js/blob/master/src/lib/isURL.js#L71
You're probably after validator.isURL(email, {require_protocol: true})
Should we always have to use require_protocol: true option in order to have correct results in method .isURL? If that is the case, should we change the default option to true after all?
Thank you for your time.
The problem may be that .isURL has to pass strings like "example.com", where if you use require_protocol: true, validator.isURL would return false (but the string is actually a url).
@Litarhis agreed with what you are saying about example.com but instead the validation should just fail for url if there is an @ symbol
@ankitrg at first, these were my thoughts also. But then I reviewed the code and the tests that it's going through and sadly it's not that simple. As it is seen here: https://github.com/chriso/validator.js/blob/master/test/validators.js#L216
this string should pass for test .isURL . Also, I can give you an example from a real url: a string with the form of "https://myteam.slack.com/messages/@aPersonsUsername" is a valid URL as it is a page for you to send private messages via Slack to "aPersonsUsername" in team "myteam". As you see, the string contains the symbol @, thus we can't just eliminate all strings that contain that symbol.
NOTE: the slack URL is an example, it's not a real URL, but its schema is possible
@Litarhis, I was of the idea that @ is not used in the URLs. My bad.
@ankitrg, the thing is that actually your issue is quite interesting. An easy fix would be to check if the given string is an email address by testing it with validator.isEmail(string) in the .isURL code and if it is isURL should return false. But then, there is the possibility that the username in the url https://github.com/chriso/validator.js/blob/master/test/validators.js#L216
would be an email address like this 'http://[email protected]:[email protected]/' and I don't know if isEmail would return true in that case. Because if it does, then the easy fixed I suggested would reject that string, but the string is actually a URL
@Litarhis This makes sense and checking for !isEmail && isURl will perfectly, but for me, I think I can safely use {require_protocol: true} as my I explicitly want my URL to begin with www or https and as a by-product it solved the @ problem
Well well well.... validator.isURL('http://[email protected]:[email protected]/'); returns false and I think that it should return true. May I address it as a new issue? I am sorry but I am new at this contribution-style github thing. 馃槢
Searching for a better and more solid answer, if you want to pass an email-like username to the basic http auth via URL, you should encode the contained symbol @ in the email address to '%40'. That way the above example of validator.isURL('http://[email protected]:[email protected]/'); returns true as it should do when written to the correct format of validator.isURL('http://john%40doe.com:[email protected]/');. So, a simple fix of checking if the given string is an email address with the method .isEmail will probably do the job.
http://[email protected]:[email protected]/ is not a valid URL. The @ needs to be encoded, as you've said above.