diff options
21 files changed, 298 insertions, 600 deletions
diff --git a/api4/webhook.go b/api4/webhook.go index 6602c7a26..668636932 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -71,7 +71,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { return } - hookID := c.Params.HookId + hookId := c.Params.HookId updatedHook := model.IncomingWebhookFromJson(r.Body) if updatedHook == nil { @@ -81,12 +81,16 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("attempt") - oldHook, err := app.GetIncomingWebhook(hookID) + oldHook, err := app.GetIncomingWebhook(hookId) if err != nil { c.Err = err return } + if updatedHook.TeamId == "" { + updatedHook.TeamId = oldHook.TeamId + } + if updatedHook.TeamId != oldHook.TeamId { c.Err = model.NewAppError("updateIncomingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) return @@ -161,13 +165,13 @@ func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { return } - hookID := c.Params.HookId + hookId := c.Params.HookId var err *model.AppError var hook *model.IncomingWebhook var channel *model.Channel - if hook, err = app.GetIncomingWebhook(hookID); err != nil { + if hook, err = app.GetIncomingWebhook(hookId); err != nil { c.Err = err return } else { @@ -195,13 +199,13 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { return } - hookID := c.Params.HookId + hookId := c.Params.HookId var err *model.AppError var hook *model.IncomingWebhook var channel *model.Channel - if hook, err = app.GetIncomingWebhook(hookID); err != nil { + if hook, err = app.GetIncomingWebhook(hookId); err != nil { c.Err = err return } else { @@ -217,7 +221,7 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) return } else { - if err = app.DeleteIncomingWebhook(hookID); err != nil { + if err = app.DeleteIncomingWebhook(hookId); err != nil { c.Err = err return } diff --git a/webapp/actions/admin_actions.jsx b/webapp/actions/admin_actions.jsx index 307f0c4a7..b9580c746 100644 --- a/webapp/actions/admin_actions.jsx +++ b/webapp/actions/admin_actions.jsx @@ -1,16 +1,18 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import Client from 'client/web_client.jsx'; - import {clientLogout} from 'actions/global_actions.jsx'; +import Client from 'client/web_client.jsx'; + import store from 'stores/redux_store.jsx'; const dispatch = store.dispatch; 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) { AdminActions.updateConfig(config)(dispatch, getState).then( @@ -157,13 +159,13 @@ export function ldapSyncNow(success, error) { } export function getOAuthAppInfo(clientId, success, error) { - Client.getOAuthAppInfo( - clientId, + Client4.getOAuthAppInfo(clientId).then( (data) => { if (success) { success(data); } - }, + } + ).catch( (err) => { if (error) { error(err); @@ -179,12 +181,13 @@ export function allowOAuth2(params, success, error) { const state = params.state; const scope = params.scope; - Client.allowOAuth2(responseType, clientId, redirectUri, state, scope, + Client4.authorizeOAuthApp(responseType, clientId, redirectUri, state, scope).then( (data) => { if (success) { success(data); } - }, + } + ).catch( (err) => { if (error) { error(err); @@ -238,16 +241,13 @@ export function oauthToEmail(currentService, email, password, success, error) { } export function regenerateOAuthAppSecret(oauthAppId, success, error) { - Client.regenerateOAuthAppSecret( - oauthAppId, + IntegrationActions.regenOAuthAppSecret(oauthAppId)(dispatch, getState).then( (data) => { - if (success) { + if (data && success) { success(data); - } - }, - (err) => { - if (error) { - error(err); + } else if (data == null && error) { + const serverError = getState().requests.admin.updateOAuthApp.error; + error({id: serverError.server_error_id, ...serverError}); } } ); diff --git a/webapp/actions/integration_actions.jsx b/webapp/actions/integration_actions.jsx index c1bbf3432..39dbbb2a8 100644 --- a/webapp/actions/integration_actions.jsx +++ b/webapp/actions/integration_actions.jsx @@ -1,35 +1,26 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import AppDispatcher from 'dispatcher/app_dispatcher.jsx'; - -import TeamStore from 'stores/team_store.jsx'; import UserStore from 'stores/user_store.jsx'; - -import * as AsyncClient from 'utils/async_client.jsx'; -import Client from 'client/web_client.jsx'; - -import {ActionTypes} from 'utils/constants.jsx'; +import TeamStore from 'stores/team_store.jsx'; // Redux actions import store from 'stores/redux_store.jsx'; const dispatch = store.dispatch; const getState = store.getState; import {getProfilesByIds} from 'mattermost-redux/actions/users'; +import * as IntegrationActions from 'mattermost-redux/actions/integrations'; -export function loadIncomingHooks() { - Client.listIncomingHooks( +export function loadIncomingHooks(complete) { + IntegrationActions.getIncomingHooks('', 0, 10000)(dispatch, getState).then( (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_INCOMING_WEBHOOKS, - teamId: TeamStore.getCurrentId(), - incomingWebhooks: data - }); - - loadProfilesForIncomingHooks(data); - }, - (err) => { - AsyncClient.dispatchError(err, 'listIncomingHooks'); + if (data) { + loadProfilesForIncomingHooks(data); + } + + if (complete) { + complete(data); + } } ); } @@ -51,19 +42,16 @@ function loadProfilesForIncomingHooks(hooks) { getProfilesByIds(list)(dispatch, getState); } -export function loadOutgoingHooks() { - Client.listOutgoingHooks( +export function loadOutgoingHooks(complete) { + IntegrationActions.getOutgoingHooks('', '', 0, 10000)(dispatch, getState).then( (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_OUTGOING_WEBHOOKS, - teamId: TeamStore.getCurrentId(), - outgoingWebhooks: data - }); - - loadProfilesForOutgoingHooks(data); - }, - (err) => { - AsyncClient.dispatchError(err, 'listOutgoingHooks'); + if (data) { + loadProfilesForOutgoingHooks(data); + } + + if (complete) { + complete(data); + } } ); } @@ -85,19 +73,16 @@ function loadProfilesForOutgoingHooks(hooks) { getProfilesByIds(list)(dispatch, getState); } -export function loadTeamCommands() { - Client.listTeamCommands( +export function loadTeamCommands(complete) { + IntegrationActions.getCustomTeamCommands(TeamStore.getCurrentId())(dispatch, getState).then( (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_COMMANDS, - teamId: Client.teamId, - commands: data - }); - - loadProfilesForCommands(data); - }, - (err) => { - AsyncClient.dispatchError(err, 'loadTeamCommands'); + if (data) { + loadProfilesForCommands(data); + } + + if (complete) { + complete(data); + } } ); } @@ -118,3 +103,101 @@ function loadProfilesForCommands(commands) { getProfilesByIds(list)(dispatch, getState); } + +export function addIncomingHook(hook, success, error) { + IntegrationActions.createIncomingHook(hook)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.createIncomingHook.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function updateIncomingHook(hook, success, error) { + IntegrationActions.updateIncomingHook(hook)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.updateIncomingHook.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function addOutgoingHook(hook, success, error) { + IntegrationActions.createOutgoingHook(hook)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.createOutgoingHook.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function updateOutgoingHook(hook, success, error) { + IntegrationActions.updateOutgoingHook(hook)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.updateOutgoingHook.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function deleteIncomingHook(id) { + IntegrationActions.removeIncomingHook(id)(dispatch, getState); +} + +export function deleteOutgoingHook(id) { + IntegrationActions.removeOutgoingHook(id)(dispatch, getState); +} + +export function regenOutgoingHookToken(id) { + IntegrationActions.regenOutgoingHookToken(id)(dispatch, getState); +} + +export function addCommand(command, success, error) { + IntegrationActions.addCommand(command)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.addCommand.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function editCommand(command, success, error) { + IntegrationActions.editCommand(command)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.editCommand.error; + error({id: serverError.server_error_id, ...serverError}); + } + } + ); +} + +export function deleteCommand(id) { + IntegrationActions.deleteCommand(id)(dispatch, getState); +} + +export function regenCommandToken(id) { + IntegrationActions.regenCommandToken(id)(dispatch, getState); +} diff --git a/webapp/actions/oauth_actions.jsx b/webapp/actions/oauth_actions.jsx index d7e033604..03508efc1 100644 --- a/webapp/actions/oauth_actions.jsx +++ b/webapp/actions/oauth_actions.jsx @@ -1,60 +1,44 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import Client from 'client/web_client.jsx'; -import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; -import Constants from 'utils/constants.jsx'; +import store from 'stores/redux_store.jsx'; +const dispatch = store.dispatch; +const getState = store.getState; -const ActionTypes = Constants.ActionTypes; +import * as IntegrationActions from 'mattermost-redux/actions/integrations'; -export function listOAuthApps(userId, onSuccess, onError) { - Client.listOAuthApps( +export function listOAuthApps(complete) { + IntegrationActions.getOAuthApps(0, 10000)(dispatch, getState).then( (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_OAUTHAPPS, - userId, - oauthApps: data - }); - - if (onSuccess) { - onSuccess(data); + if (complete) { + complete(data); } - }, - onError + } ); } -export function deleteOAuthApp(id, userId, onSuccess, onError) { - Client.deleteOAuthApp( - id, - () => { - AppDispatcher.handleServerAction({ - type: ActionTypes.REMOVED_OAUTHAPP, - userId, - id - }); - - if (onSuccess) { - onSuccess(); +export function deleteOAuthApp(id, success, error) { + IntegrationActions.deleteOAuthApp(id)(dispatch, getState).then( + (data) => { + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.deleteOAuthApp.error; + error({id: serverError.server_error_id, ...serverError}); } - }, - onError + } ); } -export function registerOAuthApp(app, onSuccess, onError) { - Client.registerOAuthApp( - app, +export function registerOAuthApp(app, success, error) { + IntegrationActions.addOAuthApp(app)(dispatch, getState).then( (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_OAUTHAPP, - oauthApp: data - }); - - if (onSuccess) { - onSuccess(data); + if (data && success) { + success(data); + } else if (data == null && error) { + const serverError = getState().requests.integrations.addOAuthApp.error; + error({id: serverError.server_error_id, ...serverError}); } - }, - onError + } ); } diff --git a/webapp/actions/user_actions.jsx b/webapp/actions/user_actions.jsx index 88325de3e..c94f6232d 100644 --- a/webapp/actions/user_actions.jsx +++ b/webapp/actions/user_actions.jsx @@ -12,8 +12,6 @@ import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/s import {getDirectChannelName, getUserIdFromChannelName} from 'utils/utils.jsx'; -import Client from 'client/web_client.jsx'; - import {Constants, ActionTypes, Preferences} from 'utils/constants.jsx'; import {browserHistory} from 'react-router/es6'; @@ -26,6 +24,7 @@ import * as Selectors from 'mattermost-redux/selectors/entities/users'; import {getBool} from 'mattermost-redux/selectors/entities/preferences'; import * as UserActions from 'mattermost-redux/actions/users'; +import {Client4} from 'mattermost-redux/client'; import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general'; import {getTeamMembersByIds, getMyTeamMembers, getMyTeamUnreads} from 'mattermost-redux/actions/teams'; @@ -739,32 +738,35 @@ export function webLoginByLdap(loginId, password, token, success, error) { } export function getAuthorizedApps(success, error) { - Client.getAuthorizedApps( + Client4.getAuthorizedOAuthApps(getState().entities.users.currentUserId).then( (authorizedApps) => { if (success) { success(authorizedApps); } - }, + } + ).catch( (err) => { if (error) { error(err); } - }); + } + ); } export function deauthorizeOAuthApp(appId, success, error) { - Client.deauthorizeOAuthApp( - appId, + Client4.deauthorizeOAuthApp(appId).then( () => { if (success) { success(); } - }, + } + ).catch( (err) => { if (error) { error(err); } - }); + } + ); } export function uploadProfileImage(userPicture, success, error) { diff --git a/webapp/components/integrations/components/abstract_incoming_webhook.jsx b/webapp/components/integrations/components/abstract_incoming_webhook.jsx index 9c73ae6d6..a75c29fac 100644 --- a/webapp/components/integrations/components/abstract_incoming_webhook.jsx +++ b/webapp/components/integrations/components/abstract_incoming_webhook.jsx @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; import BackstageHeader from 'components/backstage/components/backstage_header.jsx'; import ChannelSelect from 'components/channel_select.jsx'; diff --git a/webapp/components/integrations/components/abstract_outgoing_webhook.jsx b/webapp/components/integrations/components/abstract_outgoing_webhook.jsx index 9f3902e2c..912ad3bdf 100644 --- a/webapp/components/integrations/components/abstract_outgoing_webhook.jsx +++ b/webapp/components/integrations/components/abstract_outgoing_webhook.jsx @@ -1,9 +1,10 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; + +import TeamStore from 'stores/team_store.jsx'; import {localizeMessage} from 'utils/utils.jsx'; @@ -131,6 +132,7 @@ export default class AbstractOutgoingWebhook extends React.Component { } const hook = { + team_id: TeamStore.getCurrentId(), channel_id: this.state.channelId, trigger_words: triggerWords, trigger_when: parseInt(this.state.triggerWhen, 10), diff --git a/webapp/components/integrations/components/add_command.jsx b/webapp/components/integrations/components/add_command.jsx index 204b45ca4..dcf059a1d 100644 --- a/webapp/components/integrations/components/add_command.jsx +++ b/webapp/components/integrations/components/add_command.jsx @@ -1,13 +1,13 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; -import * as AsyncClient from 'utils/async_client.jsx'; import * as Utils from 'utils/utils.jsx'; +import {addCommand} from 'actions/integration_actions.jsx'; + import BackstageHeader from 'components/backstage/components/backstage_header.jsx'; import {FormattedMessage} from 'react-intl'; import FormError from 'components/form_error.jsx'; @@ -165,7 +165,7 @@ export default class AddCommand extends React.Component { return; } - AsyncClient.addCommand( + addCommand( command, (data) => { browserHistory.push('/' + this.props.team.name + '/integrations/commands/confirm?type=commands&id=' + data.id); diff --git a/webapp/components/integrations/components/add_incoming_webhook.jsx b/webapp/components/integrations/components/add_incoming_webhook.jsx index c3ddf5798..eecfb8558 100644 --- a/webapp/components/integrations/components/add_incoming_webhook.jsx +++ b/webapp/components/integrations/components/add_incoming_webhook.jsx @@ -1,14 +1,14 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as AsyncClient from 'utils/async_client.jsx'; +import {addIncomingHook} from 'actions/integration_actions.jsx'; import {browserHistory} from 'react-router/es6'; import AbstractIncomingWebhook from './abstract_incoming_webhook.jsx'; export default class AddIncomingWebhook extends AbstractIncomingWebhook { performAction(hook) { - AsyncClient.addIncomingHook( + addIncomingHook( hook, (data) => { browserHistory.push(`/${this.props.team.name}/integrations/confirm?type=incoming_webhooks&id=${data.id}`); diff --git a/webapp/components/integrations/components/add_outgoing_webhook.jsx b/webapp/components/integrations/components/add_outgoing_webhook.jsx index 22fba7c7d..d7f338587 100644 --- a/webapp/components/integrations/components/add_outgoing_webhook.jsx +++ b/webapp/components/integrations/components/add_outgoing_webhook.jsx @@ -1,14 +1,14 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as AsyncClient from 'utils/async_client.jsx'; +import {addOutgoingHook} from 'actions/integration_actions.jsx'; import {browserHistory} from 'react-router/es6'; import AbstractOutgoingWebhook from './abstract_outgoing_webhook.jsx'; export default class AddOutgoingWebhook extends AbstractOutgoingWebhook { performAction(hook) { - AsyncClient.addOutgoingHook( + addOutgoingHook( hook, (data) => { browserHistory.push(`/${this.props.team.name}/integrations/confirm?type=outgoing_webhooks&id=${data.id}`); diff --git a/webapp/components/integrations/components/commands_container.jsx b/webapp/components/integrations/components/commands_container.jsx index a831bc8f2..338d95fa0 100644 --- a/webapp/components/integrations/components/commands_container.jsx +++ b/webapp/components/integrations/components/commands_container.jsx @@ -40,7 +40,7 @@ export default class CommandsContainer extends React.Component { UserStore.addChangeListener(this.handleUserChange); if (window.mm_config.EnableCommands === 'true') { - loadTeamCommands(); + loadTeamCommands((() => this.setState({loading: false}))); } } @@ -53,8 +53,7 @@ export default class CommandsContainer extends React.Component { const teamId = this.props.team.id; this.setState({ - commands: IntegrationStore.getCommands(teamId), - loading: !IntegrationStore.hasReceivedCommands(teamId) + commands: IntegrationStore.getCommands(teamId) }); } diff --git a/webapp/components/integrations/components/edit_command.jsx b/webapp/components/integrations/components/edit_command.jsx index ae1040463..68b50c01c 100644 --- a/webapp/components/integrations/components/edit_command.jsx +++ b/webapp/components/integrations/components/edit_command.jsx @@ -1,16 +1,14 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; -import * as AsyncClient from 'utils/async_client.jsx'; import IntegrationStore from 'stores/integration_store.jsx'; import TeamStore from 'stores/team_store.jsx'; import * as Utils from 'utils/utils.jsx'; -import {loadTeamCommands} from 'actions/integration_actions.jsx'; +import {loadTeamCommands, editCommand} from 'actions/integration_actions.jsx'; import BackstageHeader from 'components/backstage/components/backstage_header.jsx'; import {FormattedMessage} from 'react-intl'; import FormError from 'components/form_error.jsx'; @@ -98,7 +96,7 @@ export default class EditCommand extends React.Component { } submitCommand() { - AsyncClient.editCommand( + editCommand( this.newCmd, browserHistory.push('/' + this.props.team.name + '/integrations/commands'), (err) => { diff --git a/webapp/components/integrations/components/edit_incoming_webhook.jsx b/webapp/components/integrations/components/edit_incoming_webhook.jsx index 2c3a69c0d..5a6309212 100644 --- a/webapp/components/integrations/components/edit_incoming_webhook.jsx +++ b/webapp/components/integrations/components/edit_incoming_webhook.jsx @@ -1,11 +1,9 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as AsyncClient from 'utils/async_client.jsx'; - import {browserHistory} from 'react-router/es6'; import IntegrationStore from 'stores/integration_store.jsx'; -import {loadIncomingHooks} from 'actions/integration_actions.jsx'; +import {updateIncomingHook, loadIncomingHooks} from 'actions/integration_actions.jsx'; import AbstractIncomingWebhook from './abstract_incoming_webhook.jsx'; import TeamStore from 'stores/team_store.jsx'; @@ -54,7 +52,7 @@ export default class EditIncomingWebhook extends AbstractIncomingWebhook { hook.id = this.originalIncomingHook.id; } - AsyncClient.updateIncomingHook( + updateIncomingHook( hook, () => { browserHistory.push(`/${this.props.team.name}/integrations/incoming_webhooks`); diff --git a/webapp/components/integrations/components/edit_outgoing_webhook.jsx b/webapp/components/integrations/components/edit_outgoing_webhook.jsx index 785023d14..2b6776b28 100644 --- a/webapp/components/integrations/components/edit_outgoing_webhook.jsx +++ b/webapp/components/integrations/components/edit_outgoing_webhook.jsx @@ -3,11 +3,9 @@ import React from 'react'; -import * as AsyncClient from 'utils/async_client.jsx'; - import {browserHistory} from 'react-router/es6'; import IntegrationStore from 'stores/integration_store.jsx'; -import {loadOutgoingHooks} from 'actions/integration_actions.jsx'; +import {loadOutgoingHooks, updateOutgoingHook} from 'actions/integration_actions.jsx'; import AbstractOutgoingWebhook from './abstract_outgoing_webhook.jsx'; import ConfirmModal from 'components/confirm_modal.jsx'; @@ -131,7 +129,7 @@ export default class EditOutgoingWebhook extends AbstractOutgoingWebhook { } submitCommand() { - AsyncClient.updateOutgoingHook( + updateOutgoingHook( this.newHook, () => { browserHistory.push(`/${this.props.team.name}/integrations/outgoing_webhooks`); diff --git a/webapp/components/integrations/components/installed_commands.jsx b/webapp/components/integrations/components/installed_commands.jsx index 9d7b16c88..731b62cd6 100644 --- a/webapp/components/integrations/components/installed_commands.jsx +++ b/webapp/components/integrations/components/installed_commands.jsx @@ -4,7 +4,7 @@ import BackstageList from 'components/backstage/components/backstage_list.jsx'; import InstalledCommand from './installed_command.jsx'; -import * as AsyncClient from 'utils/async_client.jsx'; +import {regenCommandToken, deleteCommand} from 'actions/integration_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import PropTypes from 'prop-types'; @@ -32,11 +32,11 @@ export default class InstalledCommands extends React.Component { } regenCommandToken(command) { - AsyncClient.regenCommandToken(command.id); + regenCommandToken(command.id); } deleteCommand(command) { - AsyncClient.deleteCommand(command.id); + deleteCommand(command.id); } commandCompare(a, b) { diff --git a/webapp/components/integrations/components/installed_incoming_webhooks.jsx b/webapp/components/integrations/components/installed_incoming_webhooks.jsx index 5667979e1..80f887d1b 100644 --- a/webapp/components/integrations/components/installed_incoming_webhooks.jsx +++ b/webapp/components/integrations/components/installed_incoming_webhooks.jsx @@ -9,9 +9,8 @@ import IntegrationStore from 'stores/integration_store.jsx'; import TeamStore from 'stores/team_store.jsx'; import UserStore from 'stores/user_store.jsx'; -import {loadIncomingHooks} from 'actions/integration_actions.jsx'; +import {loadIncomingHooks, deleteIncomingHook} from 'actions/integration_actions.jsx'; -import * as AsyncClient from 'utils/async_client.jsx'; import * as Utils from 'utils/utils.jsx'; import PropTypes from 'prop-types'; @@ -49,7 +48,7 @@ export default class InstalledIncomingWebhooks extends React.Component { UserStore.addChangeListener(this.handleUserChange); if (window.mm_config.EnableIncomingWebhooks === 'true') { - loadIncomingHooks(); + loadIncomingHooks(() => this.setState({loading: false})); } } @@ -62,8 +61,7 @@ export default class InstalledIncomingWebhooks extends React.Component { const teamId = TeamStore.getCurrentId(); this.setState({ - incomingWebhooks: IntegrationStore.getIncomingWebhooks(teamId), - loading: !IntegrationStore.hasReceivedIncomingWebhooks(teamId) + incomingWebhooks: IntegrationStore.getIncomingWebhooks(teamId) }); } @@ -74,7 +72,7 @@ export default class InstalledIncomingWebhooks extends React.Component { } deleteIncomingWebhook(incomingWebhook) { - AsyncClient.deleteIncomingHook(incomingWebhook.id); + deleteIncomingHook(incomingWebhook.id); } incomingWebhookCompare(a, b) { diff --git a/webapp/components/integrations/components/installed_oauth_app.jsx b/webapp/components/integrations/components/installed_oauth_app.jsx index 100d82043..a59bf8e47 100644 --- a/webapp/components/integrations/components/installed_oauth_app.jsx +++ b/webapp/components/integrations/components/installed_oauth_app.jsx @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; import FormError from 'components/form_error.jsx'; @@ -55,8 +54,7 @@ export default class InstalledOAuthApp extends React.Component { regenerateOAuthAppSecret( this.props.oauthApp.id, - (data) => { - this.props.oauthApp.client_secret = data.client_secret; + () => { this.handleShowClientSecret(e); }, (err) => { diff --git a/webapp/components/integrations/components/installed_oauth_apps.jsx b/webapp/components/integrations/components/installed_oauth_apps.jsx index 33494c464..36d9c8dfa 100644 --- a/webapp/components/integrations/components/installed_oauth_apps.jsx +++ b/webapp/components/integrations/components/installed_oauth_apps.jsx @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; import UserStore from 'stores/user_store.jsx'; import IntegrationStore from 'stores/integration_store.jsx'; @@ -28,11 +27,9 @@ export default class InstalledOAuthApps extends React.Component { this.deleteOAuthApp = this.deleteOAuthApp.bind(this); - const userId = UserStore.getCurrentId(); - this.state = { - oauthApps: IntegrationStore.getOAuthApps(userId), - loading: !IntegrationStore.hasReceivedOAuthApps(userId) + oauthApps: IntegrationStore.getOAuthApps(), + loading: !IntegrationStore.hasReceivedOAuthApps() }; } @@ -40,7 +37,7 @@ export default class InstalledOAuthApps extends React.Component { IntegrationStore.addChangeListener(this.handleIntegrationChange); if (window.mm_config.EnableOAuthServiceProvider === 'true') { - OAuthActions.listOAuthApps(UserStore.getCurrentId()); + OAuthActions.listOAuthApps(() => this.setState({loading: false})); } } @@ -49,17 +46,13 @@ export default class InstalledOAuthApps extends React.Component { } handleIntegrationChange() { - const userId = UserStore.getCurrentId(); - this.setState({ - oauthApps: IntegrationStore.getOAuthApps(userId), - loading: !IntegrationStore.hasReceivedOAuthApps(userId) + oauthApps: IntegrationStore.getOAuthApps() }); } deleteOAuthApp(app) { - const userId = UserStore.getCurrentId(); - OAuthActions.deleteOAuthApp(app.id, userId); + OAuthActions.deleteOAuthApp(app.id); } oauthAppCompare(a, b) { diff --git a/webapp/components/integrations/components/installed_outgoing_webhooks.jsx b/webapp/components/integrations/components/installed_outgoing_webhooks.jsx index 0750b5157..2a0f1c59f 100644 --- a/webapp/components/integrations/components/installed_outgoing_webhooks.jsx +++ b/webapp/components/integrations/components/installed_outgoing_webhooks.jsx @@ -9,10 +9,9 @@ import IntegrationStore from 'stores/integration_store.jsx'; import TeamStore from 'stores/team_store.jsx'; import UserStore from 'stores/user_store.jsx'; -import {loadOutgoingHooks} from 'actions/integration_actions.jsx'; +import {loadOutgoingHooks, regenOutgoingHookToken, deleteOutgoingHook} from 'actions/integration_actions.jsx'; import * as Utils from 'utils/utils.jsx'; -import * as AsyncClient from 'utils/async_client.jsx'; import PropTypes from 'prop-types'; @@ -50,7 +49,7 @@ export default class InstalledOutgoingWebhooks extends React.Component { UserStore.addChangeListener(this.handleUserChange); if (window.mm_config.EnableOutgoingWebhooks === 'true') { - loadOutgoingHooks(); + loadOutgoingHooks(() => this.setState({loading: false})); } } @@ -63,8 +62,7 @@ export default class InstalledOutgoingWebhooks extends React.Component { const teamId = TeamStore.getCurrentId(); this.setState({ - outgoingWebhooks: IntegrationStore.getOutgoingWebhooks(teamId), - loading: !IntegrationStore.hasReceivedOutgoingWebhooks(teamId) + outgoingWebhooks: IntegrationStore.getOutgoingWebhooks(teamId) }); } @@ -73,11 +71,11 @@ export default class InstalledOutgoingWebhooks extends React.Component { } regenOutgoingWebhookToken(outgoingWebhook) { - AsyncClient.regenOutgoingHookToken(outgoingWebhook.id); + regenOutgoingHookToken(outgoingWebhook.id); } deleteOutgoingWebhook(outgoingWebhook) { - AsyncClient.deleteOutgoingHook(outgoingWebhook.id); + deleteOutgoingHook(outgoingWebhook.id); } outgoingWebhookCompare(a, b) { diff --git a/webapp/stores/integration_store.jsx b/webapp/stores/integration_store.jsx index 89d2438bb..ff01774e1 100644 --- a/webapp/stores/integration_store.jsx +++ b/webapp/stores/integration_store.jsx @@ -1,27 +1,26 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; -import Constants from 'utils/constants.jsx'; import EventEmitter from 'events'; -const ActionTypes = Constants.ActionTypes; - const CHANGE_EVENT = 'changed'; +import store from 'stores/redux_store.jsx'; + class IntegrationStore extends EventEmitter { constructor() { super(); - this.dispatchToken = AppDispatcher.register(this.handleEventPayload.bind(this)); - - this.incomingWebhooks = new Map(); - - this.outgoingWebhooks = new Map(); + this.entities = {}; - this.commands = new Map(); + store.subscribe(() => { + const newEntities = store.getState().entities.integrations; + if (newEntities !== this.entities) { + this.emitChange(); + } - this.oauthApps = new Map(); + this.entities = newEntities; + }); } addChangeListener(callback) { @@ -37,236 +36,97 @@ class IntegrationStore extends EventEmitter { } hasReceivedIncomingWebhooks(teamId) { - return this.incomingWebhooks.has(teamId); - } - - getIncomingWebhooks(teamId) { - return this.incomingWebhooks.get(teamId) || []; - } - - setIncomingWebhooks(teamId, incomingWebhooks) { - this.incomingWebhooks.set(teamId, incomingWebhooks); - } - - addIncomingWebhook(incomingWebhook) { - const teamId = incomingWebhook.team_id; - const incomingWebhooks = this.getIncomingWebhooks(teamId); - - incomingWebhooks.push(incomingWebhook); - - this.setIncomingWebhooks(teamId, incomingWebhooks); - } + const hooks = store.getState().entities.integrations.incomingHooks || {}; - updateIncomingWebhook(incomingWebhook) { - const teamId = incomingWebhook.team_id; - const incomingWebhooks = this.getIncomingWebhooks(teamId); - - for (let i = 0; i < incomingWebhooks.length; i++) { - if (incomingWebhooks[i].id === incomingWebhook.id) { - incomingWebhooks[i] = incomingWebhook; - break; + let hasTeam = false; + Object.values(hooks).forEach((hook) => { + if (hook.team_id === teamId) { + hasTeam = true; } - } + }); - this.setIncomingWebhooks(teamId, incomingWebhooks); + return hasTeam; } - removeIncomingWebhook(teamId, id) { - let incomingWebhooks = this.getIncomingWebhooks(teamId); + getIncomingWebhooks(teamId) { + const hooks = store.getState().entities.integrations.incomingHooks; - incomingWebhooks = incomingWebhooks.filter((incomingWebhook) => incomingWebhook.id !== id); + const teamHooks = []; + Object.values(hooks).forEach((hook) => { + if (hook.team_id === teamId) { + teamHooks.push(hook); + } + }); - this.setIncomingWebhooks(teamId, incomingWebhooks); + return teamHooks; } hasReceivedOutgoingWebhooks(teamId) { - return this.outgoingWebhooks.has(teamId); - } + const hooks = store.getState().entities.integrations.outgoingHooks; - getOutgoingWebhooks(teamId) { - return this.outgoingWebhooks.get(teamId) || []; - } - - getOutgoingWebhook(teamId, id) { - return this.getOutgoingWebhooks(teamId).filter((outgoingWebhook) => outgoingWebhook.id === id)[0]; - } - - setOutgoingWebhooks(teamId, outgoingWebhooks) { - this.outgoingWebhooks.set(teamId, outgoingWebhooks); - } - - addOutgoingWebhook(outgoingWebhook) { - const teamId = outgoingWebhook.team_id; - const outgoingWebhooks = this.getOutgoingWebhooks(teamId); - - outgoingWebhooks.push(outgoingWebhook); + let hasTeam = false; + Object.values(hooks).forEach((hook) => { + if (hook.team_id === teamId) { + hasTeam = true; + } + }); - this.setOutgoingWebhooks(teamId, outgoingWebhooks); + return hasTeam; } - updateOutgoingWebhook(outgoingWebhook) { - const teamId = outgoingWebhook.team_id; - const outgoingWebhooks = this.getOutgoingWebhooks(teamId); + getOutgoingWebhooks(teamId) { + const hooks = store.getState().entities.integrations.outgoingHooks; - for (let i = 0; i < outgoingWebhooks.length; i++) { - if (outgoingWebhooks[i].id === outgoingWebhook.id) { - outgoingWebhooks[i] = outgoingWebhook; - break; + const teamHooks = []; + Object.values(hooks).forEach((hook) => { + if (hook.team_id === teamId) { + teamHooks.push(hook); } - } + }); - this.setOutgoingWebhooks(teamId, outgoingWebhooks); + return teamHooks; } - removeOutgoingWebhook(teamId, id) { - let outgoingWebhooks = this.getOutgoingWebhooks(teamId); - - outgoingWebhooks = outgoingWebhooks.filter((outgoingWebhook) => outgoingWebhook.id !== id); - - this.setOutgoingWebhooks(teamId, outgoingWebhooks); + getOutgoingWebhook(teamId, id) { + return store.getState().entities.integrations.outgoingHooks[id]; } hasReceivedCommands(teamId) { - return this.commands.has(teamId); - } - - getCommands(teamId) { - return this.commands.get(teamId) || []; - } - - getCommand(teamId, id) { - return this.getCommands(teamId).filter((command) => command.id === id)[0]; - } - - setCommands(teamId, commands) { - this.commands.set(teamId, commands); - } - - addCommand(command) { - const teamId = command.team_id; - const commands = this.getCommands(teamId); - - commands.push(command); - - this.setCommands(teamId, commands); - } - - updateCommand(command) { - const teamId = command.team_id; - const commands = this.getCommands(teamId); + const commands = store.getState().entities.integrations.commands; - for (let i = 0; i < commands.length; i++) { - if (commands[i].id === command.id) { - commands[i] = command; - break; + let hasTeam = false; + Object.values(commands).forEach((command) => { + if (command.team_id === teamId) { + hasTeam = true; } - } - - this.setCommands(teamId, commands); - } + }); - removeCommand(teamId, id) { - let commands = this.getCommands(teamId); - - commands = commands.filter((command) => command.id !== id); - - this.setCommands(teamId, commands); + return hasTeam; } - hasReceivedOAuthApps(userId) { - return this.oauthApps.has(userId); - } + getCommands(teamId) { + const commands = store.getState().entities.integrations.commands; - getOAuthApps(userId) { - return this.oauthApps.get(userId) || []; - } + const teamCommands = []; + Object.values(commands).forEach((command) => { + if (command.team_id === teamId) { + teamCommands.push(command); + } + }); - setOAuthApps(userId, oauthApps) { - this.oauthApps.set(userId, oauthApps); + return teamCommands; } - addOAuthApp(oauthApp) { - const userId = oauthApp.creator_id; - const oauthApps = this.getOAuthApps(userId); - - oauthApps.push(oauthApp); - - this.setOAuthApps(userId, oauthApps); + getCommand(teamId, id) { + return store.getState().entities.integrations.commands[id]; } - removeOAuthApp(userId, id) { - let apps = this.getOAuthApps(userId); - - apps = apps.filter((app) => app.id !== id); - - this.setOAuthApps(userId, apps); + hasReceivedOAuthApps() { + return Object.keys(store.getState().entities.integrations.oauthApps).length > 0; } - handleEventPayload(payload) { - const action = payload.action; - - switch (action.type) { - case ActionTypes.RECEIVED_INCOMING_WEBHOOKS: - this.setIncomingWebhooks(action.teamId, action.incomingWebhooks); - this.emitChange(); - break; - case ActionTypes.RECEIVED_INCOMING_WEBHOOK: - this.addIncomingWebhook(action.incomingWebhook); - this.emitChange(); - break; - case ActionTypes.UPDATED_INCOMING_WEBHOOK: - this.updateIncomingWebhook(action.incomingWebhook); - this.emitChange(); - break; - case ActionTypes.REMOVED_INCOMING_WEBHOOK: - this.removeIncomingWebhook(action.teamId, action.id); - this.emitChange(); - break; - case ActionTypes.RECEIVED_OUTGOING_WEBHOOKS: - this.setOutgoingWebhooks(action.teamId, action.outgoingWebhooks); - this.emitChange(); - break; - case ActionTypes.RECEIVED_OUTGOING_WEBHOOK: - this.addOutgoingWebhook(action.outgoingWebhook); - this.emitChange(); - break; - case ActionTypes.UPDATED_OUTGOING_WEBHOOK: - this.updateOutgoingWebhook(action.outgoingWebhook); - this.emitChange(); - break; - case ActionTypes.REMOVED_OUTGOING_WEBHOOK: - this.removeOutgoingWebhook(action.teamId, action.id); - this.emitChange(); - break; - case ActionTypes.RECEIVED_COMMANDS: - this.setCommands(action.teamId, action.commands); - this.emitChange(); - break; - case ActionTypes.RECEIVED_COMMAND: - this.addCommand(action.command); - this.emitChange(); - break; - case ActionTypes.UPDATED_COMMAND: - this.updateCommand(action.command); - this.emitChange(); - break; - case ActionTypes.REMOVED_COMMAND: - this.removeCommand(action.teamId, action.id); - this.emitChange(); - break; - case ActionTypes.RECEIVED_OAUTHAPPS: - this.setOAuthApps(action.userId, action.oauthApps); - this.emitChange(); - break; - case ActionTypes.RECEIVED_OAUTHAPP: - this.addOAuthApp(action.oauthApp); - this.emitChange(); - break; - case ActionTypes.REMOVED_OAUTHAPP: - this.removeOAuthApp(action.userId, action.id); - this.emitChange(); - break; - } + getOAuthApps() { + return Object.values(store.getState().entities.integrations.oauthApps); } } diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx index deb967e3a..820199339 100644 --- a/webapp/utils/async_client.jsx +++ b/webapp/utils/async_client.jsx @@ -712,222 +712,6 @@ export function getRecentAndNewUsersAnalytics(teamId) { ); } -export function addIncomingHook(hook, success, error) { - Client.addIncomingHook( - hook, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_INCOMING_WEBHOOK, - incomingWebhook: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'addIncomingHook'); - } - } - ); -} - -export function updateIncomingHook(hook, success, error) { - Client.updateIncomingHook( - hook, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.UPDATED_INCOMING_WEBHOOK, - incomingWebhook: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'updateIncomingHook'); - } - } - ); -} - -export function addOutgoingHook(hook, success, error) { - Client.addOutgoingHook( - hook, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_OUTGOING_WEBHOOK, - outgoingWebhook: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'addOutgoingHook'); - } - } - ); -} - -export function updateOutgoingHook(hook, success, error) { - Client.updateOutgoingHook( - hook, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.UPDATED_OUTGOING_WEBHOOK, - outgoingWebhook: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'updateOutgoingHook'); - } - } - ); -} - -export function deleteIncomingHook(id) { - Client.deleteIncomingHook( - id, - () => { - AppDispatcher.handleServerAction({ - type: ActionTypes.REMOVED_INCOMING_WEBHOOK, - teamId: Client.teamId, - id - }); - }, - (err) => { - dispatchError(err, 'deleteIncomingHook'); - } - ); -} - -export function deleteOutgoingHook(id) { - Client.deleteOutgoingHook( - id, - () => { - AppDispatcher.handleServerAction({ - type: ActionTypes.REMOVED_OUTGOING_WEBHOOK, - teamId: Client.teamId, - id - }); - }, - (err) => { - dispatchError(err, 'deleteOutgoingHook'); - } - ); -} - -export function regenOutgoingHookToken(id) { - Client.regenOutgoingHookToken( - id, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.UPDATED_OUTGOING_WEBHOOK, - outgoingWebhook: data - }); - }, - (err) => { - dispatchError(err, 'regenOutgoingHookToken'); - } - ); -} - -export function addCommand(command, success, error) { - Client.addCommand( - command, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_COMMAND, - command: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'addCommand'); - } - } - ); -} - -export function editCommand(command, success, error) { - Client.editCommand( - command, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.UPDATED_COMMAND, - command: data - }); - - if (success) { - success(data); - } - }, - (err) => { - if (error) { - error(err); - } else { - dispatchError(err, 'editCommand'); - } - } - ); -} - -export function deleteCommand(id) { - Client.deleteCommand( - id, - () => { - AppDispatcher.handleServerAction({ - type: ActionTypes.REMOVED_COMMAND, - teamId: Client.teamId, - id - }); - }, - (err) => { - dispatchError(err, 'deleteCommand'); - } - ); -} - -export function regenCommandToken(id) { - Client.regenCommandToken( - id, - (data) => { - AppDispatcher.handleServerAction({ - type: ActionTypes.UPDATED_COMMAND, - command: data - }); - }, - (err) => { - dispatchError(err, 'regenCommandToken'); - } - ); -} - export function getPublicLink(fileId, success, error) { const callName = 'getPublicLink' + fileId; |