summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
Diffstat (limited to 'webapp')
-rw-r--r--webapp/actions/admin_actions.jsx14
-rw-r--r--webapp/components/integrations/components/installed_oauth_app.jsx79
-rw-r--r--webapp/components/integrations/components/installed_oauth_apps/index.js4
-rw-r--r--webapp/components/integrations/components/installed_oauth_apps/installed_oauth_apps.jsx12
-rw-r--r--webapp/tests/components/integrations/__snapshots__/installed_oauth_app.test.jsx.snap155
-rw-r--r--webapp/tests/components/integrations/__snapshots__/installed_oauth_apps.test.jsx.snap2
-rw-r--r--webapp/tests/components/integrations/installed_oauth_app.test.jsx71
-rw-r--r--webapp/tests/components/integrations/installed_oauth_apps.test.jsx6
8 files changed, 294 insertions, 49 deletions
diff --git a/webapp/actions/admin_actions.jsx b/webapp/actions/admin_actions.jsx
index 85184a23a..4dd0f848f 100644
--- a/webapp/actions/admin_actions.jsx
+++ b/webapp/actions/admin_actions.jsx
@@ -9,7 +9,6 @@ const getState = store.getState;
import * as AdminActions from 'mattermost-redux/actions/admin';
import * as UserActions from 'mattermost-redux/actions/users';
-import * as IntegrationActions from 'mattermost-redux/actions/integrations';
import {Client4} from 'mattermost-redux/client';
export function saveConfig(config, success, error) {
@@ -238,19 +237,6 @@ export function oauthToEmail(currentService, email, password, success, error) {
);
}
-export function regenerateOAuthAppSecret(oauthAppId, success, error) {
- IntegrationActions.regenOAuthAppSecret(oauthAppId)(dispatch, getState).then(
- (data) => {
- if (data && success) {
- success(data);
- } else if (data == null && error) {
- const serverError = getState().requests.admin.updateOAuthApp.error;
- error({id: serverError.server_error_id, ...serverError});
- }
- }
- );
-}
-
export function uploadBrandImage(brandImage, success, error) {
AdminActions.uploadBrandImage(brandImage)(dispatch, getState).then(
(data) => {
diff --git a/webapp/components/integrations/components/installed_oauth_app.jsx b/webapp/components/integrations/components/installed_oauth_app.jsx
index a59bf8e47..bcb7a7c96 100644
--- a/webapp/components/integrations/components/installed_oauth_app.jsx
+++ b/webapp/components/integrations/components/installed_oauth_app.jsx
@@ -4,70 +4,83 @@
import React from 'react';
import PropTypes from 'prop-types';
-import FormError from 'components/form_error.jsx';
-
import * as Utils from 'utils/utils.jsx';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
-import {regenerateOAuthAppSecret} from 'actions/admin_actions.jsx';
-
+import FormError from 'components/form_error.jsx';
import DeleteIntegration from './delete_integration.jsx';
const FAKE_SECRET = '***************';
-export default class InstalledOAuthApp extends React.Component {
- static get propTypes() {
- return {
- oauthApp: PropTypes.object.isRequired,
- onDelete: PropTypes.func.isRequired,
- filter: PropTypes.string
- };
+export default class InstalledOAuthApp extends React.PureComponent {
+ static propTypes = {
+
+ /**
+ * The oauthApp data
+ */
+ oauthApp: PropTypes.object.isRequired,
+
+ /**
+ * The request state for regenOAuthAppSecret action. Contains status and error
+ */
+ regenOAuthAppSecretRequest: PropTypes.object.isRequired,
+
+ /**
+ * The function to call when Regenerate Secret link is clicked
+ */
+ onRegenerateSecret: PropTypes.func.isRequired,
+
+ /**
+ * The function to call when Delete link is clicked
+ */
+ onDelete: PropTypes.func.isRequired,
+
+ /**
+ * Set to filter OAuthApp
+ */
+ filter: PropTypes.string
}
constructor(props) {
super(props);
- this.handleShowClientSecret = this.handleShowClientSecret.bind(this);
- this.handleHideClientScret = this.handleHideClientScret.bind(this);
- this.handleRegenerate = this.handleRegenerate.bind(this);
- this.handleDelete = this.handleDelete.bind(this);
-
- this.matchesFilter = this.matchesFilter.bind(this);
-
this.state = {
clientSecret: FAKE_SECRET
};
}
- handleShowClientSecret(e) {
- e.preventDefault();
+ handleShowClientSecret = (e) => {
+ if (e && e.preventDefault) {
+ e.preventDefault();
+ }
this.setState({clientSecret: this.props.oauthApp.client_secret});
}
- handleHideClientScret(e) {
+ handleHideClientSecret = (e) => {
e.preventDefault();
this.setState({clientSecret: FAKE_SECRET});
}
- handleRegenerate(e) {
+ handleRegenerate = (e) => {
e.preventDefault();
-
- regenerateOAuthAppSecret(
- this.props.oauthApp.id,
+ this.props.onRegenerateSecret(this.props.oauthApp.id).then(
() => {
- this.handleShowClientSecret(e);
- },
- (err) => {
- this.setState({error: err.message});
+ const {error} = this.props.regenOAuthAppSecretRequest;
+ if (error) {
+ this.setState({error: error.message});
+ } else {
+ this.setState({error: null});
+ this.handleShowClientSecret();
+ }
}
);
}
- handleDelete() {
+ handleDelete = () => {
this.props.onDelete(this.props.oauthApp);
}
- matchesFilter(oauthApp, filter) {
+ matchesFilter = (oauthApp, filter) => {
if (!filter) {
return true;
}
@@ -152,7 +165,7 @@ export default class InstalledOAuthApp extends React.Component {
showHide = (
<a
href='#'
- onClick={this.handleHideClientScret}
+ onClick={this.handleHideClientSecret}
>
<FormattedMessage
id='installed_integrations.hideSecret'
@@ -254,4 +267,4 @@ export default class InstalledOAuthApp extends React.Component {
</div>
);
}
-}
+} \ No newline at end of file
diff --git a/webapp/components/integrations/components/installed_oauth_apps/index.js b/webapp/components/integrations/components/installed_oauth_apps/index.js
index 85d2a5ba7..bfeed6d66 100644
--- a/webapp/components/integrations/components/installed_oauth_apps/index.js
+++ b/webapp/components/integrations/components/installed_oauth_apps/index.js
@@ -13,7 +13,8 @@ function mapStateToProps(state, ownProps) {
return {
...ownProps,
oauthApps: getOAuthApps(state),
- isSystemAdmin: isCurrentUserSystemAdmin(state)
+ isSystemAdmin: isCurrentUserSystemAdmin(state),
+ regenOAuthAppSecretRequest: state.requests.integrations.updateOAuthApp
};
}
@@ -21,6 +22,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getOAuthApps: Actions.getOAuthApps,
+ regenOAuthAppSecret: Actions.regenOAuthAppSecret,
deleteOAuthApp: Actions.deleteOAuthApp
}, dispatch)
};
diff --git a/webapp/components/integrations/components/installed_oauth_apps/installed_oauth_apps.jsx b/webapp/components/integrations/components/installed_oauth_apps/installed_oauth_apps.jsx
index 45dd56310..4cd27ab57 100644
--- a/webapp/components/integrations/components/installed_oauth_apps/installed_oauth_apps.jsx
+++ b/webapp/components/integrations/components/installed_oauth_apps/installed_oauth_apps.jsx
@@ -27,6 +27,11 @@ export default class InstalledOAuthApps extends React.PureComponent {
*/
isSystemAdmin: PropTypes.bool,
+ /**
+ * The request state for regenOAuthAppSecret action. Contains status and error
+ */
+ regenOAuthAppSecretRequest: PropTypes.object.isRequired,
+
actions: PropTypes.shape({
/**
@@ -35,6 +40,11 @@ export default class InstalledOAuthApps extends React.PureComponent {
getOAuthApps: PropTypes.func.isRequired,
/**
+ * The function to call when Regenerate Secret link is clicked
+ */
+ regenOAuthAppSecret: PropTypes.func.isRequired,
+
+ /**
* The function to call when Delete link is clicked
*/
deleteOAuthApp: PropTypes.func.isRequired
@@ -80,6 +90,8 @@ export default class InstalledOAuthApps extends React.PureComponent {
<InstalledOAuthApp
key={app.id}
oauthApp={app}
+ regenOAuthAppSecretRequest={this.props.regenOAuthAppSecretRequest}
+ onRegenerateSecret={this.props.actions.regenOAuthAppSecret}
onDelete={this.deleteOAuthApp}
/>
);
diff --git a/webapp/tests/components/integrations/__snapshots__/installed_oauth_app.test.jsx.snap b/webapp/tests/components/integrations/__snapshots__/installed_oauth_app.test.jsx.snap
new file mode 100644
index 000000000..f4e8fb464
--- /dev/null
+++ b/webapp/tests/components/integrations/__snapshots__/installed_oauth_app.test.jsx.snap
@@ -0,0 +1,155 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/integrations/InstalledOAuthApp should filter out OAuthApp 1`] = `null`;
+
+exports[`components/integrations/InstalledOAuthApp should match snapshot 1`] = `
+<div
+ className="backstage-list__item"
+>
+ <div
+ className="integration__icon integration-list__icon"
+ >
+ <img
+ src="https://test.com/icon"
+ />
+ </div>
+ <div
+ className="item-details"
+ >
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__name"
+ >
+ testApp
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__description"
+ >
+ testing
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__url"
+ >
+ <FormattedHTMLMessage
+ defaultMessage="Is Trusted: <strong>{isTrusted}</strong>"
+ id="installed_oauth_apps.is_trusted"
+ values={
+ Object {
+ "isTrusted": "Yes",
+ }
+ }
+ />
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__token"
+ >
+ <FormattedHTMLMessage
+ defaultMessage="Client ID: <strong>{clientId}</strong>"
+ id="installed_integrations.client_id"
+ values={
+ Object {
+ "clientId": "facxd9wpzpbpfp8pad78xj75pr",
+ }
+ }
+ />
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__token"
+ >
+ <FormattedHTMLMessage
+ defaultMessage="Client Secret: <strong>{clientSecret}</strong>"
+ id="installed_integrations.client_secret"
+ values={
+ Object {
+ "clientSecret": "***************",
+ }
+ }
+ />
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__url"
+ >
+ <FormattedMessage
+ defaultMessage="Callback URLs: {urls}"
+ id="installed_integrations.callback_urls"
+ values={
+ Object {
+ "urls": "https://test.com/callback, https://test.com/callback2",
+ }
+ }
+ />
+ </span>
+ </div>
+ <div
+ className="item-details__row"
+ >
+ <span
+ className="item-details__creation"
+ >
+ <FormattedMessage
+ defaultMessage="Created by {creator} on {createAt, date, full}"
+ id="installed_integrations.creation"
+ values={
+ Object {
+ "createAt": 1501365458934,
+ "creator": "",
+ }
+ }
+ />
+ </span>
+ </div>
+ </div>
+ <div
+ className="item-actions"
+ >
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ <FormattedMessage
+ defaultMessage="Show Secret"
+ id="installed_integrations.showSecret"
+ values={Object {}}
+ />
+ </a>
+ -
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ <FormattedMessage
+ defaultMessage="Regenerate Secret"
+ id="installed_integrations.regenSecret"
+ values={Object {}}
+ />
+ </a>
+ -
+ <DeleteIntegration
+ messageId="installed_oauth_apps.delete.confirm"
+ onDelete={[Function]}
+ />
+ </div>
+</div>
+`;
diff --git a/webapp/tests/components/integrations/__snapshots__/installed_oauth_apps.test.jsx.snap b/webapp/tests/components/integrations/__snapshots__/installed_oauth_apps.test.jsx.snap
index 022bc1476..c6ef12112 100644
--- a/webapp/tests/components/integrations/__snapshots__/installed_oauth_apps.test.jsx.snap
+++ b/webapp/tests/components/integrations/__snapshots__/installed_oauth_apps.test.jsx.snap
@@ -72,6 +72,7 @@ exports[`components/integrations/InstalledOAuthApps should match snapshot 1`] =
}
}
onDelete={[Function]}
+ onRegenerateSecret={[Function]}
/>
<InstalledOAuthApp
oauthApp={
@@ -93,6 +94,7 @@ exports[`components/integrations/InstalledOAuthApps should match snapshot 1`] =
}
}
onDelete={[Function]}
+ onRegenerateSecret={[Function]}
/>
</BackstageList>
`;
diff --git a/webapp/tests/components/integrations/installed_oauth_app.test.jsx b/webapp/tests/components/integrations/installed_oauth_app.test.jsx
new file mode 100644
index 000000000..ff27a5768
--- /dev/null
+++ b/webapp/tests/components/integrations/installed_oauth_app.test.jsx
@@ -0,0 +1,71 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+import {shallow} from 'enzyme';
+
+import InstalledOAuthApp from 'components/integrations/components/installed_oauth_app.jsx';
+
+describe('components/integrations/InstalledOAuthApp', () => {
+ const emptyFunction = jest.fn();
+ const app = {
+ id: 'facxd9wpzpbpfp8pad78xj75pr',
+ name: 'testApp',
+ client_secret: '88cxd9wpzpbpfp8pad78xj75pr',
+ create_at: 1501365458934,
+ creator_id: '88oybd1dwfdoxpkpw1h5kpbyco',
+ description: 'testing',
+ homepage: 'https://test.com',
+ icon_url: 'https://test.com/icon',
+ is_trusted: true,
+ update_at: 1501365458934,
+ callback_urls: ['https://test.com/callback', 'https://test.com/callback2']
+ };
+
+ test('should match snapshot', () => {
+ const wrapper = shallow(
+ <InstalledOAuthApp
+ oauthApp={app}
+ onRegenerateSecret={emptyFunction}
+ onDelete={emptyFunction}
+ filter={''}
+ />
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test('should call onRegenerateSecret function', () => {
+ const onRegenerateSecret = jest.genMockFunction().mockImplementation(
+ () => {
+ return new Promise((resolve) => {
+ process.nextTick(() => resolve());
+ });
+ }
+ );
+
+ const wrapper = shallow(
+ <InstalledOAuthApp
+ oauthApp={app}
+ onRegenerateSecret={onRegenerateSecret}
+ onDelete={emptyFunction}
+ filter={''}
+ />
+ );
+ wrapper.find('div.item-actions a').at(1).simulate('click', {preventDefault() {
+ return jest.fn();
+ }});
+ expect(onRegenerateSecret).toBeCalled();
+ });
+
+ test('should filter out OAuthApp', () => {
+ const wrapper = shallow(
+ <InstalledOAuthApp
+ oauthApp={app}
+ onRegenerateSecret={emptyFunction}
+ onDelete={emptyFunction}
+ filter={'filter'}
+ />
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+}); \ No newline at end of file
diff --git a/webapp/tests/components/integrations/installed_oauth_apps.test.jsx b/webapp/tests/components/integrations/installed_oauth_apps.test.jsx
index 4f3ca6ba8..2e5ccad7a 100644
--- a/webapp/tests/components/integrations/installed_oauth_apps.test.jsx
+++ b/webapp/tests/components/integrations/installed_oauth_apps.test.jsx
@@ -44,7 +44,11 @@ describe('components/integrations/InstalledOAuthApps', () => {
team={{name: 'test'}}
oauthApps={oauthApps}
isSystemAdmin={true}
- actions={{getOAuthApps: emptyFunction, deleteOAuthApp: emptyFunction}}
+ actions={{
+ getOAuthApps: emptyFunction,
+ regenOAuthAppSecret: emptyFunction,
+ deleteOAuthApp: emptyFunction
+ }}
/>
);
expect(wrapper.find('InstalledOAuthApp').length).toBe(2);