Skip to content

Features Endpoint for Dashboard. #739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions spec/features.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var features = require('../src/features')

describe('features', () => {
it('set and get features', (done) => {
features.setFeature('users', {
testOption1: true,
testOption2: false
});

var _features = features.getFeatures();

var expected = {
testOption1: true,
testOption2: false
};

expect(_features.users).toEqual(expected);
done();
});

it('get features that does not exist', (done) => {
var _features = features.getFeatures();
expect(_features.test).toBeUndefined();
done();
});
});
4 changes: 4 additions & 0 deletions src/Adapters/Push/ParsePushAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export class ParsePushAdapter extends PushAdapter {
super(pushConfig);
this.validPushTypes = ['ios', 'android'];
this.senderMap = {};
// used in PushController for Dashboard Features
this.feature = {
immediatePush: true
};
let pushTypes = Object.keys(pushConfig);

for (let pushType of pushTypes) {
Expand Down
6 changes: 5 additions & 1 deletion src/Controllers/AdaptableController.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export class AdaptableController {
this.options = options;
this.appId = appId;
this.adapter = adapter;
this.setFeature();
}

// sets features for Dashboard to consume from features router
setFeature() {}

set adapter(adapter) {
this.validateAdapter(adapter);
this[_adapter] = adapter;
Expand Down Expand Up @@ -67,4 +71,4 @@ export class AdaptableController {
}
}

export default AdaptableController;
export default AdaptableController;
7 changes: 7 additions & 0 deletions src/Controllers/PushController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ import PromiseRouter from '../PromiseRouter';
import rest from '../rest';
import AdaptableController from './AdaptableController';
import { PushAdapter } from '../Adapters/Push/PushAdapter';
import features from '../features';

const FEATURE_NAME = 'push';

export class PushController extends AdaptableController {

setFeature() {
features.setFeature(FEATURE_NAME, this.adapter.feature || {});
}

/**
* Check whether the deviceType parameter in qury condition is valid or not.
* @param {Object} where A query condition
Expand Down
32 changes: 32 additions & 0 deletions src/Routers/FeaturesRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import PromiseRouter from '../PromiseRouter';
import {getFeatures} from '../features';

let masterKeyRequiredResponse = () => {
return Promise.resolve({
status: 401,
response: {error: 'master key not specified'},
})
}

export class FeaturesRouter extends PromiseRouter {

mountRoutes() {
this.route('GET','/features', (req) => {
return this.handleGET(req);
});
}

handleGET(req) {
if (!req.auth.isMaster) {
return masterKeyRequiredResponse();
}

return Promise.resolve({
response: {
results: [getFeatures()]
}
});
}
}

export default FeaturesRouter;
107 changes: 107 additions & 0 deletions src/features.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* features.js
* Feature config file that holds information on the features that are currently
* available on Parse Server. This is primarily created to work with an UI interface
* like the web dashboard. The list of features will change depending on the your
* app, choice of adapter as well as Parse Server version. This approach will enable
* the dashboard to be built independently and still support these use cases.
*
*
* Default features and feature options are listed in the features object.
*
* featureSwitch is a convenient way to turn on/off features without changing the config
*
* Features that use Adapters should specify the feature options through
* the setFeature method in your controller and feature
* Reference PushController and ParsePushAdapter as an example.
*
* NOTE: When adding new endpoints be sure to update this list both (features, featureSwitch)
* if you are planning to have a UI consume it.
*/

// default features
let features = {
analytics: {
slowQueries: false,
performanceAnalysis: false,
retentionAnalysis: false,
},
classes: {},
files: {},
functions: {},
globalConfig: {
create: true,
read: true,
update: true,
delete: true,
},
hooks: {
create: false,
read: false,
update: false,
delete: false,
},
iapValidation: {},
installations: {},
logs: {
info: true,
error: true,
},
publicAPI: {},
push: {},
roles: {},
schemas: {
addField: true,
removeField: true,
addClass: true,
removeClass: true,
clearAllDataFromClass: false,
exportClass: false,
},
sessions: {},
users: {},
};

// master switch for features
let featuresSwitch = {
analytics: true,
classes: true,
files: true,
functions: true,
globalConfig: true,
hooks: true,
iapValidation: true,
installations: true,
logs: true,
publicAPI: true,
push: true,
roles: true,
schemas: true,
sessions: true,
users: true,
};

/**
* set feature config options
*/
function setFeature(key, value) {
features[key] = value;
}

/**
* get feature config options
*/
function getFeatures() {
let result = {};
Object.keys(features).forEach((key) => {
if (featuresSwitch[key]) {
result[key] = features[key];
}
});
return result;
}

module.exports = {
getFeatures,
setFeature,
};
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ParsePushAdapter from './Adapters/Push/ParsePushAdapter';
import PromiseRouter from './PromiseRouter';
import { AnalyticsRouter } from './Routers/AnalyticsRouter';
import { ClassesRouter } from './Routers/ClassesRouter';
import { FeaturesRouter } from './Routers/FeaturesRouter';
import { FileLoggerAdapter } from './Adapters/Logger/FileLoggerAdapter';
import { FilesController } from './Controllers/FilesController';
import { FilesRouter } from './Routers/FilesRouter';
Expand Down Expand Up @@ -207,7 +208,8 @@ function ParseServer({
new SchemasRouter(),
new PushRouter(),
new LogsRouter(),
new IAPValidationRouter()
new IAPValidationRouter(),
new FeaturesRouter(),
];

if (process.env.PARSE_EXPERIMENTAL_CONFIG_ENABLED || process.env.TESTING) {
Expand Down