cozy-sharing 31.0.1 → 31.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [31.0.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@31.0.1...cozy-sharing@31.0.2) (2026-05-07)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **cozy-sharing:** Escape user input in suggestion matchers ([d1bce0d](https://github.com/cozy/cozy-libs/commit/d1bce0d4426a04960e8e44d93b301c2f673e584e))
|
|
11
|
+
|
|
6
12
|
## [31.0.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@31.0.0...cozy-sharing@31.0.1) (2026-05-07)
|
|
7
13
|
|
|
8
14
|
**Note:** Version bump only for package cozy-sharing
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import escapeRegExp from 'lodash/escapeRegExp';
|
|
1
2
|
import { Group } from 'cozy-doctypes'; // TODO: sadly we have different versions of contacts' doctype to handle...
|
|
2
3
|
// A migration tool on the stack side is needed here
|
|
3
4
|
|
|
4
5
|
var emailMatch = function emailMatch(input, contact) {
|
|
5
6
|
if (!contact.email) return false;
|
|
6
|
-
var emailInput = new RegExp(input, 'i');
|
|
7
|
+
var emailInput = new RegExp(escapeRegExp(input), 'i');
|
|
7
8
|
|
|
8
9
|
if (Array.isArray(contact.email)) {
|
|
9
10
|
return contact.email.some(function (email) {
|
|
@@ -16,7 +17,7 @@ var emailMatch = function emailMatch(input, contact) {
|
|
|
16
17
|
|
|
17
18
|
var cozyUrlMatch = function cozyUrlMatch(input, contact) {
|
|
18
19
|
if (!contact.cozy && !contact.url) return false;
|
|
19
|
-
var urlInput = new RegExp(input, 'i');
|
|
20
|
+
var urlInput = new RegExp(escapeRegExp(input), 'i');
|
|
20
21
|
|
|
21
22
|
if (contact.cozy && Array.isArray(contact.cozy)) {
|
|
22
23
|
return contact.cozy.some(function (cozy) {
|
|
@@ -29,13 +30,13 @@ var cozyUrlMatch = function cozyUrlMatch(input, contact) {
|
|
|
29
30
|
|
|
30
31
|
var groupNameMatch = function groupNameMatch(input, contactOrGroup) {
|
|
31
32
|
if (contactOrGroup._type !== Group.doctype) return false;
|
|
32
|
-
var nameInput = new RegExp(input, 'i');
|
|
33
|
+
var nameInput = new RegExp(escapeRegExp(input), 'i');
|
|
33
34
|
return nameInput.test(contactOrGroup.name);
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
var fullnameMatch = function fullnameMatch(input, contact) {
|
|
37
38
|
if (!contact.fullname) return false;
|
|
38
|
-
var fullnameInput = new RegExp(input, 'i');
|
|
39
|
+
var fullnameInput = new RegExp(escapeRegExp(input), 'i');
|
|
39
40
|
return fullnameInput.test(contact.fullname);
|
|
40
41
|
};
|
|
41
42
|
|
|
@@ -72,6 +72,44 @@ describe('Suggestion matchers', function () {
|
|
|
72
72
|
expect(result).toBe(false);
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
|
+
describe('with regex special characters in input', function () {
|
|
76
|
+
var contact = {
|
|
77
|
+
fullname: 'Jon (the) Snow*',
|
|
78
|
+
email: [{
|
|
79
|
+
address: 'jon+snow@winterfell.westeros'
|
|
80
|
+
}],
|
|
81
|
+
cozy: [{
|
|
82
|
+
url: 'https://jon.mycozy.cloud'
|
|
83
|
+
}]
|
|
84
|
+
};
|
|
85
|
+
var group = {
|
|
86
|
+
_type: 'io.cozy.contacts.groups',
|
|
87
|
+
name: 'House (Stark)'
|
|
88
|
+
};
|
|
89
|
+
it('should not throw on unbalanced parentheses', function () {
|
|
90
|
+
expect(function () {
|
|
91
|
+
return matchers.emailMatch('foo (bar', contact);
|
|
92
|
+
}).not.toThrow();
|
|
93
|
+
expect(function () {
|
|
94
|
+
return matchers.cozyUrlMatch('foo (bar', contact);
|
|
95
|
+
}).not.toThrow();
|
|
96
|
+
expect(function () {
|
|
97
|
+
return matchers.fullnameMatch('foo (bar', contact);
|
|
98
|
+
}).not.toThrow();
|
|
99
|
+
expect(function () {
|
|
100
|
+
return matchers.groupNameMatch('foo (bar', group);
|
|
101
|
+
}).not.toThrow();
|
|
102
|
+
});
|
|
103
|
+
it('should match special chars literally instead of as regex', function () {
|
|
104
|
+
expect(matchers.fullnameMatch('(the)', contact)).toBe(true);
|
|
105
|
+
expect(matchers.fullnameMatch('Snow*', contact)).toBe(true);
|
|
106
|
+
expect(matchers.emailMatch('jon+snow', contact)).toBe(true);
|
|
107
|
+
expect(matchers.groupNameMatch('(Stark)', group)).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it('should not let . match any character', function () {
|
|
110
|
+
expect(matchers.fullnameMatch('J.n', contact)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
75
113
|
describe('fullnameMatch', function () {
|
|
76
114
|
it('should return false if no fullname or no match', function () {
|
|
77
115
|
var contact = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "31.0.
|
|
3
|
+
"version": "31.0.2",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"sideEffects": [
|
|
85
85
|
"*.css"
|
|
86
86
|
],
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "cf80a630e5308718b52411e3792f145041d94170"
|
|
88
88
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import escapeRegExp from 'lodash/escapeRegExp'
|
|
2
|
+
|
|
1
3
|
import { Group } from 'cozy-doctypes'
|
|
2
4
|
|
|
3
5
|
// TODO: sadly we have different versions of contacts' doctype to handle...
|
|
4
6
|
// A migration tool on the stack side is needed here
|
|
5
7
|
const emailMatch = (input, contact) => {
|
|
6
8
|
if (!contact.email) return false
|
|
7
|
-
const emailInput = new RegExp(input, 'i')
|
|
9
|
+
const emailInput = new RegExp(escapeRegExp(input), 'i')
|
|
8
10
|
if (Array.isArray(contact.email)) {
|
|
9
11
|
return contact.email.some(email => emailInput.test(email.address))
|
|
10
12
|
}
|
|
@@ -13,7 +15,7 @@ const emailMatch = (input, contact) => {
|
|
|
13
15
|
|
|
14
16
|
const cozyUrlMatch = (input, contact) => {
|
|
15
17
|
if (!contact.cozy && !contact.url) return false
|
|
16
|
-
const urlInput = new RegExp(input, 'i')
|
|
18
|
+
const urlInput = new RegExp(escapeRegExp(input), 'i')
|
|
17
19
|
if (contact.cozy && Array.isArray(contact.cozy)) {
|
|
18
20
|
return contact.cozy.some(cozy => urlInput.test(cozy.url))
|
|
19
21
|
}
|
|
@@ -22,13 +24,13 @@ const cozyUrlMatch = (input, contact) => {
|
|
|
22
24
|
|
|
23
25
|
const groupNameMatch = (input, contactOrGroup) => {
|
|
24
26
|
if (contactOrGroup._type !== Group.doctype) return false
|
|
25
|
-
const nameInput = new RegExp(input, 'i')
|
|
27
|
+
const nameInput = new RegExp(escapeRegExp(input), 'i')
|
|
26
28
|
return nameInput.test(contactOrGroup.name)
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
const fullnameMatch = (input, contact) => {
|
|
30
32
|
if (!contact.fullname) return false
|
|
31
|
-
const fullnameInput = new RegExp(input, 'i')
|
|
33
|
+
const fullnameInput = new RegExp(escapeRegExp(input), 'i')
|
|
32
34
|
return fullnameInput.test(contact.fullname)
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -95,6 +95,36 @@ describe('Suggestion matchers', () => {
|
|
|
95
95
|
})
|
|
96
96
|
})
|
|
97
97
|
|
|
98
|
+
describe('with regex special characters in input', () => {
|
|
99
|
+
const contact = {
|
|
100
|
+
fullname: 'Jon (the) Snow*',
|
|
101
|
+
email: [{ address: 'jon+snow@winterfell.westeros' }],
|
|
102
|
+
cozy: [{ url: 'https://jon.mycozy.cloud' }]
|
|
103
|
+
}
|
|
104
|
+
const group = {
|
|
105
|
+
_type: 'io.cozy.contacts.groups',
|
|
106
|
+
name: 'House (Stark)'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
it('should not throw on unbalanced parentheses', () => {
|
|
110
|
+
expect(() => matchers.emailMatch('foo (bar', contact)).not.toThrow()
|
|
111
|
+
expect(() => matchers.cozyUrlMatch('foo (bar', contact)).not.toThrow()
|
|
112
|
+
expect(() => matchers.fullnameMatch('foo (bar', contact)).not.toThrow()
|
|
113
|
+
expect(() => matchers.groupNameMatch('foo (bar', group)).not.toThrow()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('should match special chars literally instead of as regex', () => {
|
|
117
|
+
expect(matchers.fullnameMatch('(the)', contact)).toBe(true)
|
|
118
|
+
expect(matchers.fullnameMatch('Snow*', contact)).toBe(true)
|
|
119
|
+
expect(matchers.emailMatch('jon+snow', contact)).toBe(true)
|
|
120
|
+
expect(matchers.groupNameMatch('(Stark)', group)).toBe(true)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('should not let . match any character', () => {
|
|
124
|
+
expect(matchers.fullnameMatch('J.n', contact)).toBe(false)
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
98
128
|
describe('fullnameMatch', () => {
|
|
99
129
|
it('should return false if no fullname or no match', () => {
|
|
100
130
|
const contact = {}
|