Skip to content
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

Add masterkey parameters #1233

Merged
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
39 changes: 24 additions & 15 deletions src/dashboard/Data/Config/Config.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class Config extends TableView {
modalOpen: false,
modalParam: '',
modalType: 'String',
modalValue: ''
modalValue: '',
modalMasterKeyOnly: false
};
}

Expand Down Expand Up @@ -58,13 +59,16 @@ class Config extends TableView {
if (!this.state.modalOpen) {
return null;
}
const { currentApp = {} } = this.context;
return (
<ConfigDialog
onConfirm={this.saveParam.bind(this)}
onCancel={() => this.setState({ modalOpen: false })}
param={this.state.modalParam}
type={this.state.modalType}
value={this.state.modalValue} />
value={this.state.modalValue}
masterKeyOnly={this.state.modalMasterKeyOnly}
parseServerVersion={currentApp.serverInfo && currentApp.serverInfo.parseServerVersion} />
);
}

Expand Down Expand Up @@ -103,9 +107,11 @@ class Config extends TableView {
modalOpen: true,
modalParam: data.param,
modalType: type,
modalValue: modalValue
modalValue: modalValue,
modalMasterKeyOnly: data.masterKeyOnly
});
let columnStyle = { width: '30%', cursor: 'pointer' };
let columnStyleLarge = { width: '30%', cursor: 'pointer' };
let columnStyleSmall = { width: '15%', cursor: 'pointer' };

let openModalValueColumn = () => {
if (data.value instanceof Parse.File) {
Expand All @@ -116,9 +122,10 @@ class Config extends TableView {

return (
<tr key={data.param}>
<td style={columnStyle} onClick={openModal}>{data.param}</td>
<td style={columnStyle} onClick={openModal}>{type}</td>
<td style={columnStyle} onClick={openModalValueColumn}>{value}</td>
<td style={columnStyleLarge} onClick={openModal}>{data.param}</td>
<td style={columnStyleSmall} onClick={openModal}>{type}</td>
<td style={columnStyleLarge} onClick={openModalValueColumn}>{value}</td>
<td style={columnStyleSmall} onClick={openModal}>{data.masterKeyOnly.toString()}</td>
<td style={{ textAlign: 'center' }}>
<a onClick={this.deleteParam.bind(this, data.param)}>
<Icon width={16} height={16} name='trash-solid' fill='#ff395e' />
Expand All @@ -131,8 +138,9 @@ class Config extends TableView {
renderHeaders() {
return [
<TableHeader key='parameter' width={30}>Parameter</TableHeader>,
<TableHeader key='type' width={30}>Type</TableHeader>,
<TableHeader key='value' width={30}>Value</TableHeader>
<TableHeader key='type' width={15}>Type</TableHeader>,
<TableHeader key='value' width={30}>Value</TableHeader>,
<TableHeader key='masterKeyOnly' width={15}>Master key only</TableHeader>
];
}

Expand All @@ -151,20 +159,20 @@ class Config extends TableView {
let data = undefined;
if (this.props.config.data) {
let params = this.props.config.data.get('params');
let masterKeyOnlyParams = this.props.config.data.get('masterKeyOnly') || {};
if (params) {
data = [];
params.forEach((value, param) => {
let masterKeyOnly = masterKeyOnlyParams.get(param) || false;
let type = typeof value;
if (type === 'object' && value.__type == 'File') {
value = Parse.File.fromJSON(value);
}
else if (type === 'object' && value.__type == 'GeoPoint') {
value = new Parse.GeoPoint(value);
}

data.push({ param: param, value: value })
data.push({ param: param, value: value, masterKeyOnly: masterKeyOnly })
});

data.sort((object1, object2) => {
return object1.param.localeCompare(object2.param);
});
Expand All @@ -173,10 +181,10 @@ class Config extends TableView {
return data;
}

saveParam({ name, value }) {
saveParam({ name, value, masterKeyOnly }) {
this.props.config.dispatch(
ActionTypes.SET,
{ param: name, value: value }
{ param: name, value: value, masterKeyOnly: masterKeyOnly }
).then(() => {
this.setState({ modalOpen: false });
}, () => {
Expand All @@ -196,7 +204,8 @@ class Config extends TableView {
modalOpen: true,
modalParam: '',
modalType: 'String',
modalValue: ''
modalValue: '',
modalMasterKeyOnly: false
});
}
}
Expand Down
31 changes: 30 additions & 1 deletion src/dashboard/Data/Config/ConfigDialog.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import React from 'react';
import TextInput from 'components/TextInput/TextInput.react';
import Toggle from 'components/Toggle/Toggle.react';
import validateNumeric from 'lib/validateNumeric';
import styles from 'dashboard/Data/Browser/Browser.scss';
import semver from 'semver';

const PARAM_TYPES = [
'Boolean',
Expand Down Expand Up @@ -108,13 +110,15 @@ export default class ConfigDialog extends React.Component {
this.state = {
value: null,
type: 'String',
name: ''
name: '',
masterKeyOnly: false
};
if (props.param.length > 0) {
this.state = {
name: props.param,
type: props.type,
value: props.value,
masterKeyOnly: props.masterKeyOnly
};
}
}
Expand Down Expand Up @@ -176,6 +180,7 @@ export default class ConfigDialog extends React.Component {
this.props.onConfirm({
name: this.state.name,
value: GET_VALUE[this.state.type](this.state.value),
masterKeyOnly: this.state.masterKeyOnly
});
}

Expand Down Expand Up @@ -228,6 +233,30 @@ export default class ConfigDialog extends React.Component {
description='Use this to configure your app. You can change it at any time.' />
}
input={EDITORS[this.state.type](this.state.value, (value) => { this.setState({ value }) })} />

{
/*
Add `Requires master key` field if parse-server version >= 3.8.0,
that is the minimum version that supports this feature.
*/
semver.valid(this.props.parseServerVersion) && semver.gte(this.props.parseServerVersion, '3.8.0')
mtrezza marked this conversation as resolved.
Show resolved Hide resolved
? <Field
label={
<Label
text='Requires master key?'
description='When set to yes the parameter is returned only when requested with the master key. You can change it at any time.' />
}
input={
<Toggle
type={Toggle.Types.YES_NO}
value={this.state.masterKeyOnly}
onChange={(masterKeyOnly) => this.setState({ masterKeyOnly })}
additionalStyles={{ margin: '0px' }} />
}
className={styles.addColumnToggleWrapper}
/>
: null
}
</Modal>
);
}
Expand Down
11 changes: 7 additions & 4 deletions src/lib/stores/ConfigStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const ActionTypes = keyMirror(['FETCH', 'SET', 'DELETE']);
// Config state should be an Immutable Map with the following fields:
// - lastFetch: the last time all data was fetched from the server
// - params: An Immutable Map of parameter strings to values
// - masterKeyOnly: An Immutable Map of parameter properties for read with master key only

function ConfigStore(state, action) {
action.app.setParseKeys();
Expand All @@ -27,22 +28,24 @@ function ConfigStore(state, action) {
{},
{ useMasterKey: true }
).then((result) => {
return Map({ lastFetch: new Date(), params: Map(result.params) });
return Map({ lastFetch: new Date(), params: Map(result.params), masterKeyOnly: Map(result.masterKeyOnly) });
});
case ActionTypes.SET:
return Parse._request(
'PUT',
'config',
{ params: { [action.param]: Parse._encode(action.value) } },
{ params: { [action.param]: Parse._encode(action.value) }, masterKeyOnly: { [action.param]: action.masterKeyOnly} },
{ useMasterKey: true }
).then(() => {
return state.setIn(['params', action.param], action.value);
return state
.setIn(['params', action.param], action.value)
.setIn(['masterKeyOnly', action.param], action.masterKeyOnly);
});
case ActionTypes.DELETE:
return Parse._request(
'PUT',
'config',
{ params: { [action.param]: { __op: 'Delete' } } },
{ params: { [action.param]: { __op: 'Delete' } }, masterKeyOnly: { [action.param]: { __op: 'Delete' } } },
{ useMasterKey: true }
).then(() => {
return state.deleteIn(['params', action.param]);
Expand Down