diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 735b0b0a8..325daa987 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -778,13 +778,19 @@ const RocketChat = { try { let loginServicesFilter = []; const loginServicesResult = await fetch(`${ server }/api/v1/settings.oauth`).then(response => response.json()); - // TODO: remove this after SAML and custom oauth - const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter']; + if (loginServicesResult.success && loginServicesResult.services.length > 0) { const { services } = loginServicesResult; - loginServicesFilter = services.filter(item => availableOAuth.includes(item.name)); + loginServicesFilter = services.filter(item => item.custom !== undefined); // TODO: remove this after SAML and CAS + const loginServicesReducer = loginServicesFilter.reduce((ret, item) => { - ret[item.name] = item; + const name = item.name ? item.name : item.service; + const authType = this._determineAuthType(item); + + if (authType !== 'not_supported') { + ret[name] = { ...item, name, authType }; + } + return ret; }, {}); reduxStore.dispatch(setLoginServices(loginServicesReducer)); @@ -795,6 +801,17 @@ const RocketChat = { return Promise.reject(); } }, + _determineAuthType(service) { + // TODO: remove this after other oauth providers are implemented. e.g. Drupal, github_enterprise + const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter']; + const { name, custom } = service; + + if (custom) { + return 'oauth_custom'; + } + + return availableOAuth.includes(name) ? 'oauth' : 'not_supported'; + }, getUsernameSuggestion() { // RC 0.65.0 return this.sdk.get('users.getUsernameSuggestion'); diff --git a/app/reducers/login.js b/app/reducers/login.js index 77c3c6f6d..11efc1051 100644 --- a/app/reducers/login.js +++ b/app/reducers/login.js @@ -51,7 +51,6 @@ export default function login(state = initialState, action) { return { ...state, services: { - ...state.services, ...action.data } }; diff --git a/app/views/LoginSignupView.js b/app/views/LoginSignupView.js index f1d5ca4f8..8184c9a8a 100644 --- a/app/views/LoginSignupView.js +++ b/app/views/LoginSignupView.js @@ -221,6 +221,18 @@ class LoginSignupView extends React.Component { this.openOAuth(url); } + onPressCustomOAuth = (loginService) => { + const { server } = this.props; + const { + serverURL, authorizePath, clientId, scope, service + } = loginService; + const redirectUri = `${ server }/_oauth/${ service }`; + const state = this.getOAuthState(); + const params = `?client_id=${ clientId }&redirect_uri=${ redirectUri }&response_type=code&state=${ state }&scope=${ scope }`; + const url = `${ serverURL }${ authorizePath }${ params }`; + this.openOAuth(url); + } + getOAuthState = () => { const credentialToken = random(43); return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true })); @@ -265,6 +277,19 @@ class LoginSignupView extends React.Component { this.setState(prevState => ({ collapsed: !prevState.collapsed })); } + getSocialOauthProvider = (name) => { + const oauthProviders = { + facebook: this.onPressFacebook, + github: this.onPressGithub, + gitlab: this.onPressGitlab, + google: this.onPressGoogle, + linkedin: this.onPressLinkedin, + 'meteor-developer': this.onPressMeteor, + twitter: this.onPressTwitter + }; + return oauthProviders[name]; + } + renderServicesSeparator = () => { const { collapsed } = this.state; const { services } = this.props; @@ -294,35 +319,23 @@ class LoginSignupView extends React.Component { const icon = `icon_${ name }`; name = name.charAt(0).toUpperCase() + name.slice(1); let onPress = () => {}; - switch (service.name) { - case 'facebook': - onPress = this.onPressFacebook; + + switch (service.authType) { + case 'oauth': { + onPress = this.getSocialOauthProvider(service.name); break; - case 'github': - onPress = this.onPressGithub; - break; - case 'gitlab': - onPress = this.onPressGitlab; - break; - case 'google': - onPress = this.onPressGoogle; - break; - case 'linkedin': - onPress = this.onPressLinkedin; - break; - case 'meteor-developer': - onPress = this.onPressMeteor; - break; - case 'twitter': - onPress = this.onPressTwitter; + } + case 'oauth_custom': { + onPress = () => this.onPressCustomOAuth(service); break; + } default: break; } return ( - + {service.authType === 'oauth' ? : null} {I18n.t('Continue_with')} {name}