101 lines
3.7 KiB
JavaScript
101 lines
3.7 KiB
JavaScript
// global_config.js
|
|
import Parse from 'parse/node';
|
|
import PromiseRouter from '../PromiseRouter';
|
|
import * as middleware from '../middlewares';
|
|
import * as triggers from '../triggers';
|
|
|
|
const getConfigFromParams = params => {
|
|
const config = new Parse.Config();
|
|
for (const attr in params) {
|
|
config.attributes[attr] = Parse._decode(undefined, params[attr]);
|
|
}
|
|
return config;
|
|
};
|
|
|
|
export class GlobalConfigRouter extends PromiseRouter {
|
|
getGlobalConfig(req) {
|
|
return req.config.database
|
|
.find('_GlobalConfig', { objectId: '1' }, { limit: 1 })
|
|
.then(results => {
|
|
if (results.length != 1) {
|
|
// If there is no config in the database - return empty config.
|
|
return { response: { params: {} } };
|
|
}
|
|
const globalConfig = results[0];
|
|
if (!req.auth.isMaster && globalConfig.masterKeyOnly !== undefined) {
|
|
for (const param in globalConfig.params) {
|
|
if (globalConfig.masterKeyOnly[param]) {
|
|
delete globalConfig.params[param];
|
|
delete globalConfig.masterKeyOnly[param];
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
response: {
|
|
params: globalConfig.params,
|
|
masterKeyOnly: globalConfig.masterKeyOnly,
|
|
},
|
|
};
|
|
});
|
|
}
|
|
|
|
async updateGlobalConfig(req) {
|
|
if (req.auth.isReadOnly) {
|
|
throw new Parse.Error(
|
|
Parse.Error.OPERATION_FORBIDDEN,
|
|
"read-only masterKey isn't allowed to update the config."
|
|
);
|
|
}
|
|
const params = req.body.params;
|
|
const masterKeyOnly = req.body.masterKeyOnly || {};
|
|
// Transform in dot notation to make sure it works
|
|
const update = Object.keys(params).reduce((acc, key) => {
|
|
acc[`params.${key}`] = params[key];
|
|
acc[`masterKeyOnly.${key}`] = masterKeyOnly[key] || false;
|
|
return acc;
|
|
}, {});
|
|
const className = triggers.getClassName(Parse.Config);
|
|
const hasBeforeSaveHook = triggers.triggerExists(className, triggers.Types.beforeSave, req.config.applicationId);
|
|
const hasAfterSaveHook = triggers.triggerExists(className, triggers.Types.afterSave, req.config.applicationId);
|
|
let originalConfigObject;
|
|
let updatedConfigObject;
|
|
const configObject = new Parse.Config();
|
|
configObject.attributes = params;
|
|
|
|
const results = await req.config.database.find('_GlobalConfig', { objectId: '1' }, { limit: 1 });
|
|
const isNew = results.length !== 1;
|
|
if (!isNew && (hasBeforeSaveHook || hasAfterSaveHook)) {
|
|
originalConfigObject = getConfigFromParams(results[0].params);
|
|
}
|
|
try {
|
|
await triggers.maybeRunGlobalConfigTrigger(triggers.Types.beforeSave, req.auth, configObject, originalConfigObject, req.config, req.context);
|
|
if (isNew) {
|
|
await req.config.database.update('_GlobalConfig', { objectId: '1' }, update, { upsert: true }, true)
|
|
updatedConfigObject = configObject;
|
|
} else {
|
|
const result = await req.config.database.update('_GlobalConfig', { objectId: '1' }, update, {}, true);
|
|
updatedConfigObject = getConfigFromParams(result.params);
|
|
}
|
|
await triggers.maybeRunGlobalConfigTrigger(triggers.Types.afterSave, req.auth, updatedConfigObject, originalConfigObject, req.config, req.context);
|
|
return { response: { result: true } }
|
|
} catch (err) {
|
|
const error = triggers.resolveError(err, {
|
|
code: Parse.Error.SCRIPT_FAILED,
|
|
message: 'Script failed. Unknown error.',
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
mountRoutes() {
|
|
this.route('GET', '/config', req => {
|
|
return this.getGlobalConfig(req);
|
|
});
|
|
this.route('PUT', '/config', middleware.promiseEnforceMasterKeyAccess, req => {
|
|
return this.updateGlobalConfig(req);
|
|
});
|
|
}
|
|
}
|
|
|
|
export default GlobalConfigRouter;
|