feat: Add dynamic master key by setting Parse Server option masterKey to a function (#9582)
This commit is contained in:
@@ -46,32 +46,32 @@ describe('middlewares', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but no key supplied', () => {
|
||||
it('should give invalid response when keys are configured but no key supplied', async () => {
|
||||
AppCachePut(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey',
|
||||
});
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
await middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but supplied key is incorrect', () => {
|
||||
it('should give invalid response when keys are configured but supplied key is incorrect', async () => {
|
||||
AppCachePut(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey',
|
||||
});
|
||||
fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
await middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but different key is supplied', () => {
|
||||
it('should give invalid response when keys are configured but different key is supplied', async () => {
|
||||
AppCachePut(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey',
|
||||
});
|
||||
fakeReq.headers['x-parse-client-key'] = 'clientKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
await middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
@@ -157,13 +157,7 @@ describe('middlewares', () => {
|
||||
fakeReq.ip = '127.0.0.1';
|
||||
fakeReq.headers['x-parse-master-key'] = 'masterKey';
|
||||
|
||||
let error;
|
||||
|
||||
try {
|
||||
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
const error = await middlewares.handleParseHeaders(fakeReq, fakeRes, () => {}).catch(e => e);
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toEqual(`unauthorized`);
|
||||
@@ -182,13 +176,7 @@ describe('middlewares', () => {
|
||||
fakeReq.ip = '10.0.0.2';
|
||||
fakeReq.headers['x-parse-maintenance-key'] = 'masterKey';
|
||||
|
||||
let error;
|
||||
|
||||
try {
|
||||
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
const error = await middlewares.handleParseHeaders(fakeReq, fakeRes, () => {}).catch(e => e);
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toEqual(`unauthorized`);
|
||||
|
||||
@@ -601,6 +601,63 @@ describe('server', () => {
|
||||
await new Promise(resolve => server.close(resolve));
|
||||
});
|
||||
|
||||
it('should load masterKey', async () => {
|
||||
await reconfigureServer({
|
||||
masterKey: () => 'testMasterKey',
|
||||
masterKeyTtl: 1000, // TTL is set
|
||||
});
|
||||
|
||||
await new Parse.Object('TestObject').save();
|
||||
|
||||
const config = Config.get(Parse.applicationId);
|
||||
expect(config.masterKeyCache.masterKey).toEqual('testMasterKey');
|
||||
expect(config.masterKeyCache.expiresAt.getTime()).toBeGreaterThan(Date.now());
|
||||
});
|
||||
|
||||
it('should not reload if ttl is not set', async () => {
|
||||
const masterKeySpy = jasmine.createSpy().and.returnValue(Promise.resolve('initialMasterKey'));
|
||||
|
||||
await reconfigureServer({
|
||||
masterKey: masterKeySpy,
|
||||
masterKeyTtl: null, // No TTL set
|
||||
});
|
||||
|
||||
await new Parse.Object('TestObject').save();
|
||||
|
||||
const config = Config.get(Parse.applicationId);
|
||||
const firstMasterKey = config.masterKeyCache.masterKey;
|
||||
|
||||
// Simulate calling the method again
|
||||
await config.loadMasterKey();
|
||||
const secondMasterKey = config.masterKeyCache.masterKey;
|
||||
|
||||
expect(firstMasterKey).toEqual('initialMasterKey');
|
||||
expect(secondMasterKey).toEqual('initialMasterKey');
|
||||
expect(masterKeySpy).toHaveBeenCalledTimes(1); // Should only be called once
|
||||
expect(config.masterKeyCache.expiresAt).toBeNull(); // TTL is not set, so expiresAt should remain null
|
||||
});
|
||||
|
||||
it('should reload masterKey if ttl is set and expired', async () => {
|
||||
const masterKeySpy = jasmine.createSpy()
|
||||
.and.returnValues(Promise.resolve('firstMasterKey'), Promise.resolve('secondMasterKey'));
|
||||
|
||||
await reconfigureServer({
|
||||
masterKey: masterKeySpy,
|
||||
masterKeyTtl: 1 / 1000, // TTL is set to 1ms
|
||||
});
|
||||
|
||||
await new Parse.Object('TestObject').save();
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 10));
|
||||
|
||||
await new Parse.Object('TestObject').save();
|
||||
|
||||
const config = Config.get(Parse.applicationId);
|
||||
expect(masterKeySpy).toHaveBeenCalledTimes(2);
|
||||
expect(config.masterKeyCache.masterKey).toEqual('secondMasterKey');
|
||||
});
|
||||
|
||||
|
||||
it('should not fail when Google signin is introduced without the optional clientId', done => {
|
||||
const jwt = require('jsonwebtoken');
|
||||
const authUtils = require('../lib/Adapters/Auth/utils');
|
||||
|
||||
Reference in New Issue
Block a user