Skip to content

Commit 2ead3f3

Browse files
authored
feat: Add Parse.Query option useMaintenanceKey (#2484)
1 parent e6dc1b5 commit 2ead3f3

11 files changed

+89
-6
lines changed

src/CoreManager.ts

+1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ const config: Config & { [key: string]: any } = {
353353
VERSION: 'js' + require('../package.json').version,
354354
APPLICATION_ID: null,
355355
JAVASCRIPT_KEY: null,
356+
MAINTENANCE_KEY: null,
356357
MASTER_KEY: null,
357358
USE_MASTER_KEY: false,
358359
PERFORM_USER_REWRITE: true,

src/Parse.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,15 @@ const Parse = {
110110
Parse._initialize(applicationId, javaScriptKey);
111111
},
112112

113-
_initialize(applicationId: string, javaScriptKey: string, masterKey?: string) {
113+
_initialize(
114+
applicationId: string,
115+
javaScriptKey: string,
116+
masterKey?: string,
117+
maintenanceKey?: string
118+
) {
114119
CoreManager.set('APPLICATION_ID', applicationId);
115120
CoreManager.set('JAVASCRIPT_KEY', javaScriptKey);
121+
CoreManager.set('MAINTENANCE_KEY', maintenanceKey);
116122
CoreManager.set('MASTER_KEY', masterKey);
117123
CoreManager.set('USE_MASTER_KEY', false);
118124
CoreManager.setIfNeeded('EventEmitter', EventEmitter);
@@ -198,6 +204,17 @@ const Parse = {
198204
return CoreManager.get('MASTER_KEY');
199205
},
200206

207+
/**
208+
* @member {string} Parse.maintenanceKey
209+
* @static
210+
*/
211+
set maintenanceKey(value) {
212+
CoreManager.set('MAINTENANCE_KEY', value);
213+
},
214+
get maintenanceKey() {
215+
return CoreManager.get('MAINTENANCE_KEY');
216+
},
217+
201218
/**
202219
* @member {string} Parse.serverURL
203220
* @static

src/ParseObject.ts

+3
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,9 @@ class ParseObject<T extends Attributes = Attributes> {
513513
if (hasOwn(options, 'useMasterKey')) {
514514
requestOptions.useMasterKey = !!options.useMasterKey;
515515
}
516+
if (hasOwn(options, 'useMaintenanceKey')) {
517+
requestOptions.useMaintenanceKey = !!options.useMaintenanceKey;
518+
}
516519
if (hasOwn(options, 'sessionToken') && typeof options.sessionToken === 'string') {
517520
requestOptions.sessionToken = options.sessionToken;
518521
}

src/ParseQuery.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { Pointer } from './ParseObject';
1414
type BatchOptions = FullOptions & {
1515
batchSize?: number;
1616
useMasterKey?: boolean;
17+
useMaintenanceKey?: boolean;
1718
sessionToken?: string;
1819
context?: { [key: string]: any };
1920
json?: boolean;

src/RESTController.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import XhrWeapp from './Xhr.weapp';
77

88
export type RequestOptions = {
99
useMasterKey?: boolean;
10+
useMaintenanceKey?: boolean;
1011
sessionToken?: string;
1112
installationId?: string;
1213
returnStatus?: boolean;
@@ -23,6 +24,7 @@ export type FullOptions = {
2324
success?: any;
2425
error?: any;
2526
useMasterKey?: boolean;
27+
useMaintenanceKey?: boolean;
2628
sessionToken?: string;
2729
installationId?: string;
2830
progress?: any;
@@ -36,6 +38,7 @@ type PayloadType = {
3638
_JavaScriptKey?: string;
3739
_ClientVersion: string;
3840
_MasterKey?: string;
41+
_MaintenanceKey?: string;
3942
_RevocableSession?: string;
4043
_InstallationId?: string;
4144
_SessionToken?: string;
@@ -273,7 +276,9 @@ const RESTController = {
273276
throw new Error('Cannot use the Master Key, it has not been provided.');
274277
}
275278
}
276-
279+
if (options.useMaintenanceKey) {
280+
payload._MaintenanceKey = CoreManager.get('MAINTENANCE_KEY');
281+
}
277282
if (CoreManager.get('FORCE_REVOCABLE_SESSION')) {
278283
payload._RevocableSession = '1';
279284
}

src/__tests__/Parse-test.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ describe('Parse module', () => {
2424
expect(CoreManager.get('APPLICATION_ID')).toBe('A');
2525
expect(CoreManager.get('JAVASCRIPT_KEY')).toBe('B');
2626

27-
Parse._initialize('A', 'B', 'C');
27+
Parse._initialize('A', 'B', 'C', 'D');
2828
expect(CoreManager.get('APPLICATION_ID')).toBe('A');
2929
expect(CoreManager.get('JAVASCRIPT_KEY')).toBe('B');
3030
expect(CoreManager.get('MASTER_KEY')).toBe('C');
31+
expect(CoreManager.get('MAINTENANCE_KEY')).toBe('D');
3132
});
3233

3334
it('enables master key use in the node build', () => {
@@ -55,6 +56,10 @@ describe('Parse module', () => {
5556
expect(CoreManager.get('MASTER_KEY')).toBe('789');
5657
expect(Parse.masterKey).toBe('789');
5758

59+
Parse.maintenanceKey = '000';
60+
expect(CoreManager.get('MAINTENANCE_KEY')).toBe('000');
61+
expect(Parse.maintenanceKey).toBe('000');
62+
5863
Parse.serverURL = 'http://example.com';
5964
expect(CoreManager.get('SERVER_URL')).toBe('http://example.com');
6065
expect(Parse.serverURL).toBe('http://example.com');

src/__tests__/ParseQuery-test.js

+15
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,7 @@ describe('ParseQuery', () => {
12631263
},
12641264
});
12651265
expect(options.useMasterKey).toEqual(true);
1266+
expect(options.useMaintenanceKey).toEqual(true);
12661267
expect(options.sessionToken).toEqual('1234');
12671268
return Promise.resolve({
12681269
results: [],
@@ -1274,6 +1275,7 @@ describe('ParseQuery', () => {
12741275
q.equalTo('size', 'small')
12751276
.first({
12761277
useMasterKey: true,
1278+
useMaintenanceKey: true,
12771279
sessionToken: '1234',
12781280
})
12791281
.then(obj => {
@@ -1440,6 +1442,7 @@ describe('ParseQuery', () => {
14401442
},
14411443
});
14421444
expect(options.useMasterKey).toEqual(true);
1445+
expect(options.useMaintenanceKey).toEqual(true);
14431446
expect(options.sessionToken).toEqual('1234');
14441447
expect(options.context).toEqual(context);
14451448
return Promise.resolve({
@@ -1451,6 +1454,7 @@ describe('ParseQuery', () => {
14511454
const q = new ParseQuery('Item');
14521455
q.get('I27', {
14531456
useMasterKey: true,
1457+
useMaintenanceKey: true,
14541458
sessionToken: '1234',
14551459
context: context,
14561460
}).then(() => {
@@ -1587,6 +1591,7 @@ describe('ParseQuery', () => {
15871591
},
15881592
});
15891593
expect(options.useMasterKey).toEqual(true);
1594+
expect(options.useMaintenanceKey).toEqual(true);
15901595
expect(options.sessionToken).toEqual('1234');
15911596
expect(options.context).toEqual(context);
15921597
return Promise.resolve({
@@ -1599,6 +1604,7 @@ describe('ParseQuery', () => {
15991604
q.containedIn('size', ['small', 'medium'])
16001605
.find({
16011606
useMasterKey: true,
1607+
useMaintenanceKey: true,
16021608
sessionToken: '1234',
16031609
context: context,
16041610
})
@@ -1713,6 +1719,7 @@ describe('ParseQuery', () => {
17131719
it('passes options through to the REST API', async () => {
17141720
const batchOptions = {
17151721
useMasterKey: true,
1722+
useMaintenanceKey: true,
17161723
sessionToken: '1234',
17171724
batchSize: 50,
17181725
};
@@ -1727,6 +1734,7 @@ describe('ParseQuery', () => {
17271734
where: {},
17281735
});
17291736
expect(options.useMasterKey).toBe(true);
1737+
expect(options.useMaintenanceKey).toEqual(true);
17301738
expect(options.sessionToken).toEqual('1234');
17311739
});
17321740

@@ -1840,6 +1848,7 @@ describe('ParseQuery', () => {
18401848
it('passes options through to the REST API', async () => {
18411849
const batchOptions = {
18421850
useMasterKey: true,
1851+
useMaintenanceKey: true,
18431852
sessionToken: '1234',
18441853
batchSize: 50,
18451854
json: true,
@@ -1855,6 +1864,7 @@ describe('ParseQuery', () => {
18551864
where: {},
18561865
});
18571866
expect(options.useMasterKey).toBe(true);
1867+
expect(options.useMaintenanceKey).toEqual(true);
18581868
expect(options.sessionToken).toEqual('1234');
18591869
expect(options.json).toEqual(true);
18601870
});
@@ -1962,6 +1972,7 @@ describe('ParseQuery', () => {
19621972
},
19631973
});
19641974
expect(options.useMasterKey).toEqual(true);
1975+
expect(options.useMaintenanceKey).toEqual(true);
19651976
expect(options.sessionToken).toEqual('1234');
19661977
expect(options.context).toEqual(context);
19671978
return Promise.resolve({
@@ -1986,6 +1997,7 @@ describe('ParseQuery', () => {
19861997
},
19871998
{
19881999
useMasterKey: true,
2000+
useMaintenanceKey: true,
19892001
sessionToken: '1234',
19902002
context: context,
19912003
}
@@ -2014,6 +2026,7 @@ describe('ParseQuery', () => {
20142026
hint: '_id_',
20152027
});
20162028
expect(options.useMasterKey).toEqual(true);
2029+
expect(options.useMaintenanceKey).toEqual(true);
20172030
expect(options.sessionToken).toEqual('1234');
20182031
expect(options.context).toEqual(context);
20192032
return Promise.resolve({
@@ -2039,6 +2052,7 @@ describe('ParseQuery', () => {
20392052
},
20402053
{
20412054
useMasterKey: true,
2055+
useMaintenanceKey: true,
20422056
sessionToken: '1234',
20432057
context: context,
20442058
}
@@ -2761,6 +2775,7 @@ describe('ParseQuery', () => {
27612775
group: { objectId: '$name' },
27622776
});
27632777
expect(options.useMasterKey).toEqual(true);
2778+
expect(options.useMaintenanceKey).toEqual(true);
27642779
expect(options.requestTask).toBeDefined();
27652780
return Promise.resolve({
27662781
results: [],

src/__tests__/RESTController-test.js

+22
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,28 @@ describe('RESTController', () => {
558558
});
559559
});
560560

561+
it('sends the maintenance key when requested', async () => {
562+
CoreManager.set('MAINTENANCE_KEY', 'MK');
563+
const xhr = {
564+
setRequestHeader: jest.fn(),
565+
open: jest.fn(),
566+
send: jest.fn(),
567+
};
568+
RESTController._setXHR(function () {
569+
return xhr;
570+
});
571+
RESTController.request('GET', 'classes/MyObject', {}, { useMaintenanceKey: true });
572+
await flushPromises();
573+
expect(JSON.parse(xhr.send.mock.calls[0][0])).toEqual({
574+
_method: 'GET',
575+
_ApplicationId: 'A',
576+
_JavaScriptKey: 'B',
577+
_MaintenanceKey: 'MK',
578+
_ClientVersion: 'V',
579+
_InstallationId: 'iid',
580+
});
581+
});
582+
561583
it('includes the status code when requested', done => {
562584
RESTController._setXHR(mockXHR([{ status: 200, response: { success: true } }]));
563585
RESTController.request('POST', 'users', {}, { returnStatus: true }).then(response => {

types/Parse.d.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,21 @@ declare const Parse: {
223223
purge: (className: string) => Promise<any>;
224224
get: (className: string, options?: import("./RESTController").RequestOptions) => Promise<any>;
225225
delete: (className: string, options?: import("./RESTController").RequestOptions) => Promise<void>;
226-
create: (className: string, params: any, options?: import("./RESTController").RequestOptions) => Promise<any>;
226+
create: (className: string, params: any, options? /**
227+
* @member {string} Parse.maintenanceKey
228+
* @static
229+
*/: import("./RESTController").RequestOptions) => Promise<any>;
227230
update: (className: string, params: any, options?: import("./RESTController").RequestOptions) => Promise<any>;
228231
send(className: string, method: string, params: any, options?: import("./RESTController").RequestOptions): Promise<any>;
229232
}): void;
230233
getSchemaController(): {
231234
purge: (className: string) => Promise<any>;
232235
get: (className: string, options?: import("./RESTController").RequestOptions) => Promise<any>;
233236
delete: (className: string, options?: import("./RESTController").RequestOptions) => Promise<void>;
234-
create: (className: string, params: any, options?: import("./RESTController").RequestOptions) => Promise<any>;
237+
create: (className: string, params: any, options? /**
238+
* @member {string} Parse.maintenanceKey
239+
* @static
240+
*/: import("./RESTController").RequestOptions) => Promise<any>;
235241
update: (className: string, params: any, options?: import("./RESTController").RequestOptions) => Promise<any>;
236242
send(className: string, method: string, params: any, options?: import("./RESTController").RequestOptions): Promise<any>;
237243
};
@@ -487,7 +493,7 @@ declare const Parse: {
487493
* @static
488494
*/
489495
initialize(applicationId: string, javaScriptKey: string): void;
490-
_initialize(applicationId: string, javaScriptKey: string, masterKey?: string): void;
496+
_initialize(applicationId: string, javaScriptKey: string, masterKey?: string, maintenanceKey?: string): void;
491497
/**
492498
* Call this method to set your AsyncStorage engine
493499
* Starting [email protected], the ParseSDK do not provide a React AsyncStorage as the ReactNative module
@@ -527,6 +533,11 @@ declare const Parse: {
527533
* @static
528534
*/
529535
masterKey: any;
536+
/**
537+
* @member {string} Parse.maintenanceKey
538+
* @static
539+
*/
540+
maintenanceKey: any;
530541
/**
531542
* @member {string} Parse.serverURL
532543
* @static

types/ParseQuery.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Pointer } from './ParseObject';
66
type BatchOptions = FullOptions & {
77
batchSize?: number;
88
useMasterKey?: boolean;
9+
useMaintenanceKey?: boolean;
910
sessionToken?: string;
1011
context?: {
1112
[key: string]: any;

types/RESTController.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export type RequestOptions = {
22
useMasterKey?: boolean;
3+
useMaintenanceKey?: boolean;
34
sessionToken?: string;
45
installationId?: string;
56
returnStatus?: boolean;
@@ -15,6 +16,7 @@ export type FullOptions = {
1516
success?: any;
1617
error?: any;
1718
useMasterKey?: boolean;
19+
useMaintenanceKey?: boolean;
1820
sessionToken?: string;
1921
installationId?: string;
2022
progress?: any;

0 commit comments

Comments
 (0)