Skip to content

Commit 721ffd9

Browse files
authored
build: release
2 parents b90ae25 + 141370c commit 721ffd9

File tree

11 files changed

+406
-268
lines changed

11 files changed

+406
-268
lines changed

changelogs/CHANGELOG_alpha.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## [3.4.3-alpha.2](https://github.com/parse-community/Parse-SDK-JS/compare/3.4.3-alpha.1...3.4.3-alpha.2) (2022-05-29)
2+
3+
4+
### Bug Fixes
5+
6+
* invalid name for `Parse.Role` throws incorrect error ([#1481](https://github.com/parse-community/Parse-SDK-JS/issues/1481)) ([8326a6f](https://github.com/parse-community/Parse-SDK-JS/commit/8326a6f1d7cda0ca8c6f1a3a7ea82448881e118e))
7+
8+
## [3.4.3-alpha.1](https://github.com/parse-community/Parse-SDK-JS/compare/3.4.2...3.4.3-alpha.1) (2022-05-02)
9+
10+
11+
### Bug Fixes
12+
13+
* creating a Parse.File with base64 string fails for some file types ([#1467](https://github.com/parse-community/Parse-SDK-JS/issues/1467)) ([c07d6c9](https://github.com/parse-community/Parse-SDK-JS/commit/c07d6c99968163a72b6ab46e7970b7a5ca4ed540))
14+
115
## [3.4.2-alpha.1](https://github.com/parse-community/Parse-SDK-JS/compare/3.4.1...3.4.2-alpha.1) (2022-04-09)
216

317

integration/test/ParseACLTest.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,13 @@ describe('Parse.ACL', () => {
533533
const obj1withInclude = await query.first();
534534
assert(obj1withInclude.get('other').get('ACL'));
535535
});
536+
537+
it('prevents save with invalid role name', async () => {
538+
expect(() => new Parse.Role(':%#', new Parse.ACL())).toThrow(
539+
new Parse.Error(
540+
Parse.Error.OTHER_CAUSE,
541+
`A role's name can be only contain alphanumeric characters, _, -, and spaces.`
542+
)
543+
);
544+
});
536545
});

integration/test/ParseFileTest.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('Parse.File', () => {
6666

6767
it('can get file data from base64', async () => {
6868
const file = new Parse.File('parse-server-logo', { base64: 'ParseA==' });
69+
await file.save();
6970
let data = await file.getData();
7071
assert.equal(data, 'ParseA==');
7172
file._data = null;
@@ -79,6 +80,7 @@ describe('Parse.File', () => {
7980
const file = new Parse.File('parse-server-logo', {
8081
base64: 'data:image/jpeg;base64,ParseA==',
8182
});
83+
await file.save();
8284
let data = await file.getData();
8385
assert.equal(data, 'ParseA==');
8486
file._data = null;

package-lock.json

Lines changed: 290 additions & 228 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse",
3-
"version": "3.4.2",
3+
"version": "3.4.3-alpha.2",
44
"description": "The Parse JavaScript SDK",
55
"homepage": "https://parseplatform.org/",
66
"keywords": [
@@ -30,11 +30,11 @@
3030
},
3131
"dependencies": {
3232
"@babel/runtime-corejs3": "7.17.8",
33-
"@babel/runtime": "7.17.9",
33+
"@babel/runtime": "7.18.0",
3434
"idb-keyval": "6.0.3",
3535
"react-native-crypto-js": "1.0.0",
3636
"uuid": "3.4.0",
37-
"ws": "7.5.1",
37+
"ws": "8.6.0",
3838
"xmlhttprequest": "1.8.0"
3939
},
4040
"devDependencies": {
@@ -82,7 +82,7 @@
8282
"jsdoc-babel": "0.5.0",
8383
"lint-staged": "10.5.3",
8484
"metro-react-native-babel-preset": "0.59.0",
85-
"parse-server": "github:parse-community/parse-server#alpha",
85+
"parse-server": "git+https://github.com/parse-community/parse-server#alpha",
8686
"prettier": "2.2.1",
8787
"regenerator-runtime": "0.13.5",
8888
"semantic-release": "17.4.6",

release.config.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,20 @@ async function config() {
8383
['@semantic-release/git', {
8484
assets: [changelogFile, 'package.json', 'package-lock.json', 'npm-shrinkwrap.json'],
8585
}],
86+
['@semantic-release/github', {
87+
successComment: getReleaseComment(),
88+
labels: ['type:ci'],
89+
releasedLabels: ['state:released<%= nextRelease.channel ? `-\${nextRelease.channel}` : "" %>']
90+
}],
8691
[
8792
'@saithodev/semantic-release-backmerge',
8893
{
8994
'branches': [
9095
{ from: 'beta', to: 'alpha' },
9196
{ from: 'release', to: 'beta' },
92-
{ from: 'release', to: 'alpha' },
9397
]
9498
}
9599
],
96-
['@semantic-release/github', {
97-
successComment: getReleaseComment(),
98-
labels: ['type:ci'],
99-
releasedLabels: ['state:released<%= nextRelease.channel ? `-\${nextRelease.channel}` : "" %>']
100-
}],
101100
],
102101
};
103102

src/ParseFile.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,15 @@ export type FileSource =
4242
type: string,
4343
};
4444

45-
const dataUriRegexp = /^data:([a-zA-Z]+\/[-a-zA-Z0-9+.]+)(;charset=[a-zA-Z0-9\-\/]*)?;base64,/;
45+
const base64Regex = new RegExp(
46+
'([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))',
47+
'i'
48+
);
49+
50+
const dataUriRegex = new RegExp(
51+
`^data:([a-zA-Z]+\\/[-a-zA-Z0-9+.]+(;[a-z-]+=[a-zA-Z0-9+.-]+)?)?(;base64)?,(${base64Regex.source})*$`,
52+
'i'
53+
);
4654

4755
function b64Digit(number: number): string {
4856
if (number < 26) {
@@ -137,26 +145,30 @@ class ParseFile {
137145
type: specifiedType,
138146
};
139147
} else if (data && typeof data.base64 === 'string') {
140-
const base64 = data.base64;
141-
const commaIndex = base64.indexOf(',');
142-
143-
if (commaIndex !== -1) {
144-
const matches = dataUriRegexp.exec(base64.slice(0, commaIndex + 1));
145-
// if data URI with type and charset, there will be 4 matches.
146-
this._data = base64.slice(commaIndex + 1);
147-
this._source = {
148-
format: 'base64',
149-
base64: this._data,
150-
type: matches[1],
151-
};
152-
} else {
153-
this._data = base64;
154-
this._source = {
155-
format: 'base64',
156-
base64: base64,
157-
type: specifiedType,
158-
};
148+
// Check if data URI or base64 string is valid
149+
const validationRegex = new RegExp(base64Regex.source + '|' + dataUriRegex.source, 'i');
150+
if (!validationRegex.test(data.base64)) {
151+
throw new Error(
152+
'Cannot create a Parse.File without valid data URIs or base64 encoded data.'
153+
);
154+
}
155+
156+
const base64 = data.base64.split(',').slice(-1)[0];
157+
let type =
158+
specifiedType || data.base64.split(';').slice(0, 1)[0].split(':').slice(1, 2)[0] || '';
159+
160+
// https://tools.ietf.org/html/rfc2397
161+
// If <mediatype> is omitted, it defaults to text/plain;charset=US-ASCII.
162+
// As a shorthand, "text/plain" can be omitted but the charset parameter supplied.
163+
if (dataUriRegex.test(data.base64)) {
164+
type = type || 'text/plain';
159165
}
166+
167+
this._source = {
168+
format: 'base64',
169+
base64,
170+
type,
171+
};
160172
} else {
161173
throw new TypeError('Cannot create a Parse.File with that data.');
162174
}

src/ParseRole.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class ParseRole extends ParseObject {
7575
* @returns {(ParseObject|boolean)} true if the set succeeded.
7676
*/
7777
setName(name: string, options?: mixed): ParseObject | boolean {
78+
this._validateName(name);
7879
return this.set('name', name, options);
7980
}
8081

@@ -108,6 +109,18 @@ class ParseRole extends ParseObject {
108109
return this.relation('roles');
109110
}
110111

112+
_validateName(newName) {
113+
if (typeof newName !== 'string') {
114+
throw new ParseError(ParseError.OTHER_CAUSE, "A role's name must be a String.");
115+
}
116+
if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) {
117+
throw new ParseError(
118+
ParseError.OTHER_CAUSE,
119+
"A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.'
120+
);
121+
}
122+
}
123+
111124
validate(attrs: AttributeMap, options?: mixed): ParseError | boolean {
112125
const isInvalid = super.validate(attrs, options);
113126
if (isInvalid) {
@@ -125,14 +138,10 @@ class ParseRole extends ParseObject {
125138
"A role's name can only be set before it has been saved."
126139
);
127140
}
128-
if (typeof newName !== 'string') {
129-
return new ParseError(ParseError.OTHER_CAUSE, "A role's name must be a String.");
130-
}
131-
if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) {
132-
return new ParseError(
133-
ParseError.OTHER_CAUSE,
134-
"A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.'
135-
);
141+
try {
142+
this._validateName(newName);
143+
} catch (e) {
144+
return e;
136145
}
137146
}
138147
return false;

src/ParseUser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ class ParseUser extends ParseObject {
779779
* Request an email verification.
780780
*
781781
* @param {string} email The email address associated with the user that
782-
* forgot their password.
782+
* needs to verify their email.
783783
* @param {object} options
784784
* @static
785785
* @returns {Promise}

src/__tests__/ParseFile-test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,30 @@ describe('ParseFile', () => {
6666
expect(file._source.type).toBe('');
6767
});
6868

69-
it('can extract data type from base64', () => {
69+
it('can set the default type to be text/plain when using base64', () => {
7070
const file = new ParseFile('parse.txt', {
71+
base64: 'data:;base64,ParseA==',
72+
});
73+
expect(file._source.base64).toBe('ParseA==');
74+
expect(file._source.type).toBe('text/plain');
75+
});
76+
77+
it('can extract data type from base64', () => {
78+
const file = new ParseFile('parse.png', {
7179
base64: 'data:image/png;base64,ParseA==',
7280
});
7381
expect(file._source.base64).toBe('ParseA==');
7482
expect(file._source.type).toBe('image/png');
7583
});
7684

85+
it('can extract data type from base64 with a filename parameter', () => {
86+
const file = new ParseFile('parse.pdf', {
87+
base64: 'data:application/pdf;filename=parse.pdf;base64,ParseA==',
88+
});
89+
expect(file._source.base64).toBe('ParseA==');
90+
expect(file._source.type).toBe('application/pdf');
91+
});
92+
7793
it('can create files with file uri', () => {
7894
const file = new ParseFile('parse-image', {
7995
uri: 'http://example.com/image.png',
@@ -136,6 +152,12 @@ describe('ParseFile', () => {
136152
expect(function () {
137153
new ParseFile('parse.txt', 'string');
138154
}).toThrow('Cannot create a Parse.File with that data.');
155+
156+
expect(function () {
157+
new ParseFile('parse.txt', {
158+
base64: 'abc',
159+
});
160+
}).toThrow('Cannot create a Parse.File without valid data URIs or base64 encoded data.');
139161
});
140162

141163
it('throws with invalid base64', () => {

src/__tests__/ParseRole-test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ describe('ParseRole', () => {
4545
expect(role.getName()).toBe('');
4646
});
4747

48+
it('should throw error string with invalid name', () => {
49+
expect(() => new ParseRole('invalid:name', new ParseACL())).toThrow(
50+
new ParseError(
51+
ParseError.OTHER_CAUSE,
52+
"A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.'
53+
)
54+
);
55+
});
56+
4857
it('can validate attributes', () => {
4958
const acl = new ParseACL({ aUserId: { read: true, write: true } });
5059
const role = new ParseRole('admin', acl);

0 commit comments

Comments
 (0)