PLT-2057 User as a first class object (#2648)

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding client side unit test

* Cleaning up the clint side tests

* Fixing msg

* Adding more client side unit tests

* Adding more using tests

* Adding last bit of client side unit tests and adding make cmd

* Fixing bad merge

* Fixing libraries

* Updating to new client side API

* Fixing borken unit test

* Fixing unit tests

* ugg...trying to beat gofmt

* ugg...trying to beat gofmt

* Cleaning up remainder of the server side routes

* Adding inital load api

* Increased coverage of webhook unit tests (#2660)

* Adding loading ... to root html

* Fixing bad merge

* Removing explicit content type so superagent will guess corectly (#2685)

* Fixing merge and unit tests

* Adding create team UI

* Fixing signup flows

* Adding LDAP unit tests and enterprise unit test helper (#2702)

* Add the ability to reset MFA from the commandline (#2706)

* Fixing compliance unit tests

* Fixing client side tests

* Adding open server to system console

* Moving websocket connection

* Fixing unit test

* Fixing unit tests

* Fixing unit tests

* Adding nickname and more LDAP unit tests (#2717)

* Adding join open teams

* Cleaning up all TODOs in the code

* Fixing web sockets

* Removing unused webockets file

* PLT-2533 Add the ability to reset a user's MFA from the system console (#2715)

* Add the ability to reset a user's MFA from the system console

* Add client side unit test for adminResetMfa

* Reorganizing authentication to fix LDAP error message (#2723)

* Fixing failing unit test

* Initial upgrade db code

* Adding upgrade script

* Fixing upgrade script after running on core

* Update OAuth and Claim routes to work with user model changes (#2739)

* Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740)

* Fixing team invite ldap login call (#2741)

* Fixing bluebar and some img stuff

* Fix all the different file upload web utils (#2743)

* Fixing invalid session redirect (#2744)

* Redirect on bad channel name (#2746)

* Fixing a bunch of issue and removing dead code

* Patch to fix error message on leave channel (#2747)

* Setting EnableOpenServer to false by default

* Fixing config

* Fixing upgrade

* Fixing reported bugs

* Bug fixes for PLT-2057

* PLT-2563 Redo password recovery to use a database table (#2745)

* Redo password recovery to use a database table

* Update reset password audits

* Split out admin and user reset password APIs to be separate

* Delete password recovery when user is permanently deleted

* Consolidate password resetting into a single function

* Removed private channels as an option for outgoing webhooks (#2752)

* PLT-2577/PLT-2552 Fixes for backstage (#2753)

* Added URL to incoming webhook list

* Fixed client functions for adding/removing integrations

* Disallowed slash commands without trigger words

* Fixed clientside handling of errors on AddCommand page

* Minor auth cleanup (#2758)

* Changed EditPostModal to just close if you save without making any changes (#2759)

* Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756)

* Fixed url in channel info modal (#2755)

* Fixing reported issues

* Moving to version 3 of the apis

* Fixing command unit tests (#2760)

* Adding team admins

* Fixing DM issue

* Fixing eslint error

* Properly set EditPostModal's originalText state in all cases (#2762)

* Update client config check to assume features is defined if server is licensed (#2772)

* Fixing url link

* Fixing issue with websocket crashing when sending messages to different teams
This commit is contained in:
Corey Hulen
2016-04-21 22:37:01 -07:00
parent 5c755463ed
commit 2e5617c29b
268 changed files with 13214 additions and 9686 deletions

View File

@@ -10,10 +10,10 @@ import 'sass/styles.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, IndexRoute, IndexRedirect, Redirect, browserHistory} from 'react-router';
import {Router, Route, IndexRoute, Redirect, browserHistory} from 'react-router';
import Root from 'components/root.jsx';
import LoggedIn from 'components/logged_in.jsx';
import NotLoggedIn from 'components/not_logged_in.jsx';
import HeaderFooterTemplate from 'components/header_footer_template.jsx';
import NeedsTeam from 'components/needs_team.jsx';
import PasswordResetSendLink from 'components/password_reset_send_link.jsx';
import PasswordResetForm from 'components/password_reset_form.jsx';
@@ -21,16 +21,15 @@ import ChannelView from 'components/channel_view.jsx';
import PermalinkView from 'components/permalink_view.jsx';
import Sidebar from 'components/sidebar.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import SignupTeam from 'components/signup_team.jsx';
import * as Client from 'utils/client.jsx';
import * as Websockets from 'action_creators/websocket_actions.jsx';
import TeamStore from 'stores/team_store.jsx';
import * as Utils from 'utils/utils.jsx';
import Client from 'utils/web_client.jsx';
import * as Websockets from 'action_creators/websocket_actions.jsx';
import * as GlobalActions from 'action_creators/global_actions.jsx';
import SignupTeamConfirm from 'components/signup_team_confirm.jsx';
import SignupUserComplete from 'components/signup_user_complete.jsx';
import ShouldVerifyEmail from 'components/should_verify_email.jsx';
import DoVerifyEmail from 'components/do_verify_email.jsx';
@@ -47,14 +46,9 @@ import AddOutgoingWebhook from 'components/backstage/add_outgoing_webhook.jsx';
import AddCommand from 'components/backstage/add_command.jsx';
import ErrorPage from 'components/error_page.jsx';
import SignupTeamComplete from 'components/signup_team_complete/components/signup_team_complete.jsx';
import WelcomePage from 'components/signup_team_complete/components/team_signup_welcome_page.jsx';
import TeamDisplayNamePage from 'components/signup_team_complete/components/team_signup_display_name_page.jsx';
import TeamURLPage from 'components/signup_team_complete/components/team_signup_url_page.jsx';
import SendInivtesPage from 'components/signup_team_complete/components/team_signup_send_invites_page.jsx';
import UsernamePage from 'components/signup_team_complete/components/team_signup_username_page.jsx';
import PasswordPage from 'components/signup_team_complete/components/team_signup_password_page.jsx';
import FinishedPage from 'components/signup_team_complete/components/team_signup_finished.jsx';
import AppDispatcher from './dispatcher/app_dispatcher.jsx';
import Constants from './utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
import Claim from 'components/claim/claim.jsx';
import EmailToOAuth from 'components/claim/components/email_to_oauth.jsx';
@@ -63,6 +57,10 @@ import LDAPToEmail from 'components/claim/components/ldap_to_email.jsx';
import EmailToLDAP from 'components/claim/components/email_to_ldap.jsx';
import Login from 'components/login/login.jsx';
import SelectTeam from 'components/select_team/select_team.jsx';
import CreateTeam from 'components/create_team/create_team.jsx';
import CreateTeamDisplayName from 'components/create_team/components/display_name.jsx';
import CreateTeamTeamUrl from 'components/create_team/components/team_url.jsx';
import * as I18n from 'i18n/i18n.jsx';
@@ -76,53 +74,33 @@ const notFoundParams = {
// This is for anything that needs to be done for ALL react components.
// This runs before we start to render anything.
function preRenderSetup(callwhendone) {
const d1 = Client.getClientConfig(
(data, textStatus, xhr) => {
if (!data) {
return;
}
window.onerror = (msg, url, line, column, stack) => {
var l = {};
l.level = 'ERROR';
l.message = 'msg: ' + msg + ' row: ' + line + ' col: ' + column + ' stack: ' + stack + ' url: ' + url;
global.window.mm_config = data;
$.ajax({
url: '/api/v3/admin/log_client',
dataType: 'json',
contentType: 'application/json',
type: 'POST',
data: JSON.stringify(l)
});
var serverVersion = xhr.getResponseHeader('X-Version-ID');
if (window.mm_config && window.mm_config.EnableDeveloper === 'true') {
window.ErrorStore.storeLastError({message: 'DEVELOPER MODE: A javascript error has occured. Please use the javascript console to capture and report the error (row: ' + line + ' col: ' + column + ').'});
window.ErrorStore.emitChange();
}
};
if (serverVersion !== BrowserStore.getLastServerVersion()) {
if (!BrowserStore.getLastServerVersion() || BrowserStore.getLastServerVersion() === '') {
BrowserStore.setLastServerVersion(serverVersion);
} else {
BrowserStore.setLastServerVersion(serverVersion);
window.location.reload(true);
console.log('Detected version update refreshing the page'); //eslint-disable-line no-console
}
}
},
(err) => {
AsyncClient.dispatchError(err, 'getClientConfig');
var d1 = $.Deferred(); //eslint-disable-line new-cap
GlobalActions.emitInitialLoad(
() => {
d1.resolve();
}
);
const d2 = Client.getClientLicenceConfig(
(data) => {
if (!data) {
return;
}
global.window.mm_license = data;
},
(err) => {
AsyncClient.dispatchError(err, 'getClientLicenceConfig');
}
);
// Set these here so they don't fail in client.jsx track
global.window.analytics = [];
global.window.analytics.page = () => {
// Do Nothing
};
global.window.analytics.track = () => {
// Do Nothing
};
// Make sure the websockets close
$(window).on('beforeunload',
() => {
@@ -132,7 +110,9 @@ function preRenderSetup(callwhendone) {
function afterIntl() {
I18n.doAddLocaleData();
$.when(d1, d2).done(callwhendone);
$.when(d1).done(() => {
callwhendone();
});
}
if (global.Intl) {
@@ -143,18 +123,59 @@ function preRenderSetup(callwhendone) {
}
function preLoggedIn(nextState, replace, callback) {
const d1 = Client.getAllPreferences(
ErrorStore.clearLastError();
callback();
}
function preNeedsTeam(nextState, replace, callback) {
// First check to make sure you're in the current team
// for the current url.
var teamName = Utils.getTeamNameFromUrl();
var team = TeamStore.getByName(teamName);
if (!team) {
browserHistory.push('/error');
return;
}
GlobalActions.emitCloseRightHandSide();
TeamStore.saveMyTeam(team);
TeamStore.emitChange();
var d1 = $.Deferred(); //eslint-disable-line new-cap
var d2 = $.Deferred(); //eslint-disable-line new-cap
Client.getChannels(
(data) => {
PreferenceStore.setPreferencesFromServer(data);
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CHANNELS,
channels: data.channels,
members: data.members
});
d1.resolve();
},
(err) => {
AsyncClient.dispatchError(err, 'getAllPreferences');
AsyncClient.dispatchError(err, 'getChannels');
d1.resolve();
}
);
const d2 = AsyncClient.getChannels();
Client.getProfiles(
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PROFILES,
profiles: data
});
ErrorStore.clearLastError();
d2.resolve();
},
(err) => {
AsyncClient.dispatchError(err, 'getProfiles');
d2.resolve();
}
);
$.when(d1, d2).done(() => {
callback();
@@ -163,21 +184,20 @@ function preLoggedIn(nextState, replace, callback) {
function onPermalinkEnter(nextState) {
const postId = nextState.params.postid;
GlobalActions.emitPostFocusEvent(postId);
}
function onChannelEnter(nextState) {
doChannelChange(nextState);
function onChannelEnter(nextState, replace) {
doChannelChange(nextState, replace);
}
function onChannelChange(prevState, nextState) {
function onChannelChange(prevState, nextState, replace) {
if (prevState.params.channel !== nextState.params.channel) {
doChannelChange(nextState);
doChannelChange(nextState, replace);
}
}
function doChannelChange(state) {
function doChannelChange(state, replace) {
let channel;
if (state.location.query.fakechannel) {
channel = JSON.parse(state.location.query.fakechannel);
@@ -187,28 +207,13 @@ function doChannelChange(state) {
channel = ChannelStore.getMoreByName(state.params.channel);
}
if (!channel) {
console.error('Unable to get channel to change to.'); //eslint-disable-line no-console
replace('/');
return;
}
}
GlobalActions.emitChannelClickEvent(channel);
}
function onLoggedOut(nextState) {
const teamName = nextState.params.team;
Client.logout(
() => {
browserHistory.push('/' + teamName + '/login');
BrowserStore.signalLogout();
BrowserStore.clear();
ErrorStore.clearLastError();
PreferenceStore.clear();
},
() => {
browserHistory.push('/' + teamName + '/login');
}
);
}
function renderRootComponent() {
ReactDOM.render((
<Router
@@ -222,151 +227,44 @@ function renderRootComponent() {
path='error'
component={ErrorPage}
/>
<Route
component={LoggedIn}
onEnter={preLoggedIn}
>
<Route component={HeaderFooterTemplate}>
<Route
path=':team/channels/:channel'
onEnter={onChannelEnter}
onChange={onChannelChange}
components={{
sidebar: Sidebar,
center: ChannelView
}}
path='login'
component={Login}
/>
<Route
path=':team/pl/:postid'
onEnter={onPermalinkEnter}
components={{
sidebar: Sidebar,
center: PermalinkView
}}
path='reset_password'
component={PasswordResetSendLink}
/>
<Route
path=':team/tutorial'
components={{
sidebar: Sidebar,
center: TutorialView
}}
path='reset_password_complete'
component={PasswordResetForm}
/>
<Route
path=':team/logout'
onEnter={onLoggedOut}
/>
<Route path='settings/integrations'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: Integrations
}}
/>
<Route path='incoming_webhooks'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledIncomingWebhooks
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddIncomingWebhook
}}
/>
</Route>
<Route path='outgoing_webhooks'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledOutgoingWebhooks
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddOutgoingWebhook
}}
/>
</Route>
<Route path='commands'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledCommands
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddCommand
}}
/>
</Route>
<Redirect
from='*'
to='/error'
query={notFoundParams}
/>
</Route>
<Route
path='admin_console'
component={AdminConsole}
/>
</Route>
<Route component={NotLoggedIn}>
<Route
path='signup_team'
component={SignupTeam}
/>
<Route
path='signup_team_complete'
component={SignupTeamComplete}
path='claim'
component={Claim}
>
<IndexRoute component={FinishedPage}/>
<Route
path='welcome'
component={WelcomePage}
path='oauth_to_email'
component={OAuthToEmail}
/>
<Route
path='team_display_name'
component={TeamDisplayNamePage}
path='email_to_oauth'
component={EmailToOAuth}
/>
<Route
path='team_url'
component={TeamURLPage}
path='email_to_ldap'
component={EmailToLDAP}
/>
<Route
path='send_invites'
component={SendInivtesPage}
/>
<Route
path='username'
component={UsernamePage}
/>
<Route
path='password'
component={PasswordPage}
path='ldap_to_email'
component={LDAPToEmail}
/>
</Route>
<Route
path='signup_user_complete'
component={SignupUserComplete}
/>
<Route
path='signup_team_confirm'
component={SignupTeamConfirm}
/>
<Route
path='should_verify_email'
component={ShouldVerifyEmail}
@@ -375,51 +273,136 @@ function renderRootComponent() {
path='do_verify_email'
component={DoVerifyEmail}
/>
</Route>
<Route
component={LoggedIn}
onEnter={preLoggedIn}
>
<Route component={HeaderFooterTemplate}>
<Route
path='select_team'
component={SelectTeam}
/>
<Route
path='create_team'
component={CreateTeam}
>
<IndexRoute component={CreateTeamDisplayName}/>
<Route
path='display_name'
component={CreateTeamDisplayName}
/>
<Route
path='team_url'
component={CreateTeamTeamUrl}
/>
</Route>
</Route>
<Route
path='admin_console'
component={AdminConsole}
/>
<Route
path=':team'
component={NeedsTeam}
onEnter={preNeedsTeam}
>
<IndexRedirect to='login'/>
<Route
path='login'
component={Login}
path='channels/:channel'
onEnter={onChannelEnter}
onChange={onChannelChange}
components={{
sidebar: Sidebar,
center: ChannelView
}}
/>
<Route
path='reset_password'
component={PasswordResetSendLink}
path='pl/:postid'
onEnter={onPermalinkEnter}
components={{
sidebar: Sidebar,
center: PermalinkView
}}
/>
<Route
path='reset_password_complete'
component={PasswordResetForm}
path='tutorial'
components={{
sidebar: Sidebar,
center: TutorialView
}}
/>
<Route
path='claim'
component={Claim}
>
<Route
path='oauth_to_email'
component={OAuthToEmail}
<Route path='settings/integrations'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: Integrations
}}
/>
<Route
path='email_to_oauth'
component={EmailToOAuth}
/>
<Route
path='email_to_ldap'
component={EmailToLDAP}
/>
<Route
path='ldap_to_email'
component={LDAPToEmail}
<Route path='incoming_webhooks'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledIncomingWebhooks
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddIncomingWebhook
}}
/>
</Route>
<Route path='outgoing_webhooks'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledOutgoingWebhooks
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddOutgoingWebhook
}}
/>
</Route>
<Route path='commands'>
<IndexRoute
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: InstalledCommands
}}
/>
<Route
path='add'
components={{
navbar: BackstageNavbar,
sidebar: BackstageSidebar,
center: AddCommand
}}
/>
</Route>
<Redirect
from='*'
to='/error'
query={notFoundParams}
/>
</Route>
<Redirect
from='*'
to='/error'
query={notFoundParams}
/>
</Route>
</Route>
<Redirect
from='*'
to='/error'
query={notFoundParams}
/>
</Route>
</Router>
),