Skip to content

Commit

Permalink
feat: support encoding uri (follow-up to #3027)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marsup committed Apr 23, 2024
1 parent 9af6f1f commit 2772a34
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
2 changes: 1 addition & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -3085,7 +3085,7 @@ Requires the string value to be a valid [RFC 3986](http://tools.ietf.org/html/rf
- `relativeOnly` - Restrict only relative URIs. Defaults to `false`.
- `allowQuerySquareBrackets` - Allows unencoded square brackets inside the query string. This is **NOT** RFC 3986 compliant but query strings like `abc[]=123&abc[]=456` are very common these days. Defaults to `false`.
- `domain` - Validate the domain component using the options specified in [`string.domain()`](#stringdomainoptions).
- `encodeUri` - Encodes the uri with non-alphabetical characters. Defaults to `false`.
- `encodeUri` - When `convert` is true, if the validation fails, attempts to encode the URI using [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) before validating it again. This allows to provide, for example, unicode URIs, and have it encoded for you. Defaults to `false`.

```js
// Accept git or git http/https
Expand Down
16 changes: 8 additions & 8 deletions lib/types/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,11 +665,16 @@ module.exports = Any.extend({
return helpers.error('string.uri');
}

if (helpers.prefs.convert && options.encodeUri) {
value = encodeURI(value);
let match = regex.exec(value);

if (!match && helpers.prefs.convert && options.encodeUri) {
const encoded = encodeURI(value);
match = regex.exec(encoded);
if (match) {
value = encoded;
}
}

const match = regex.exec(value);
if (match) {
const matched = match[1] || match[2];
if (domain &&
Expand All @@ -690,10 +695,6 @@ module.exports = Any.extend({
return helpers.error('string.uriCustomScheme', { scheme, value });
}

if (options.encodeUri) {
return helpers.error('string.uriEncoding');
}

return helpers.error('string.uri');
}
}
Expand Down Expand Up @@ -744,7 +745,6 @@ module.exports = Any.extend({
'string.uri': '{{#label}} must be a valid uri',
'string.uriCustomScheme': '{{#label}} must be a valid uri with a scheme matching the {{#scheme}} pattern',
'string.uriRelativeOnly': '{{#label}} must be a valid relative uri',
'string.uriEncoding': '{{#label}} must contain only valid characters or "convert" must be allowed',
'string.uppercase': '{{#label}} must only contain uppercase characters'
}
});
Expand Down
42 changes: 39 additions & 3 deletions test/types/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -9017,7 +9017,43 @@ describe('string', () => {
const schema = Joi.string().uri({ encodeUri: true });

Helper.validate(schema, { convert: true }, [
['https://linkedin.com/in/aïssa/', true, 'https://linkedin.com/in/a%C3%AFssa/']
['https://linkedin.com/in/aïssa/', true, 'https://linkedin.com/in/a%C3%AFssa/'],
['https://linkedin.com/in/a%C3%AFssa/', true, 'https://linkedin.com/in/a%C3%AFssa/'],
['/#.domain.com/', false, {
message: '"value" must be a valid uri',
path: [],
type: 'string.uri',
context: { label: 'value', value: '/#.domain.com/' }
}]
]);
});

it('validates relative uri with accented characters with encoding', () => {

const schema = Joi.string().uri({ encodeUri: true, allowRelative: true });

Helper.validate(schema, { convert: true }, [
['/in/aïssa/', true, '/in/a%C3%AFssa/'],
['/in/a%C3%AFssa/', true, '/in/a%C3%AFssa/']
]);
});

it('validates uri with encodeUri and scheme', () => {

const schema = Joi.string().uri({ encodeUri: true, scheme: 'https' });

Helper.validate(schema, { convert: true }, [
['https://linkedin.com/in/aïssa/', true, 'https://linkedin.com/in/a%C3%AFssa/'],
['http://linkedin.com/in/aïssa/', false, {
message: '"value" must be a valid uri with a scheme matching the https pattern',
path: [],
type: 'string.uriCustomScheme',
context: {
scheme: 'https',
value: 'http://linkedin.com/in/aïssa/',
label: 'value'
}
}]
]);
});

Expand All @@ -9027,9 +9063,9 @@ describe('string', () => {

Helper.validate(schema, { convert: false }, [
['https://linkedin.com/in/aïssa/', false, {
message: '"value" must contain only valid characters or "convert" must be allowed',
message: '"value" must be a valid uri',
path: [],
type: 'string.uriEncoding',
type: 'string.uri',
context: { value: 'https://linkedin.com/in/aïssa/', label: 'value' }
}]
]);
Expand Down

0 comments on commit 2772a34

Please sign in to comment.