From 33be00a5404cded4b4b5b8b9d1f0ba37533a96f8 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 10 May 2018 16:44:19 -0600 Subject: [PATCH 1/3] Added support for external signins on Admin --- .../coral-admin/src/components/External.css | 16 ++++ client/coral-admin/src/components/External.js | 24 +++++ client/coral-admin/src/components/SignIn.js | 90 ++++++++++--------- client/coral-admin/src/containers/SignIn.js | 4 +- .../coral-framework/services/postMessage.js | 6 +- client/coral-framework/utils/index.js | 20 +++++ plugin-api/beta/client/utils/index.js | 1 + .../client/actions.js | 4 +- .../talk-plugin-google-auth/client/actions.js | 4 +- 9 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 client/coral-admin/src/components/External.css create mode 100644 client/coral-admin/src/components/External.js diff --git a/client/coral-admin/src/components/External.css b/client/coral-admin/src/components/External.css new file mode 100644 index 000000000..ff23c53cc --- /dev/null +++ b/client/coral-admin/src/components/External.css @@ -0,0 +1,16 @@ +.external { + margin-bottom: 20px; +} + +.separator h5 { + text-align: center; + font-size: 1.2em; +} + +.slot > * { +margin-bottom: 8px; + +&:last-child { + margin-bottom: 0px; +} +} diff --git a/client/coral-admin/src/components/External.js b/client/coral-admin/src/components/External.js new file mode 100644 index 000000000..0f133d3b9 --- /dev/null +++ b/client/coral-admin/src/components/External.js @@ -0,0 +1,24 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styles from './External.css'; +import Slot from 'coral-framework/components/Slot'; +import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty'; + +const External = ({ slot }) => ( + +
+
+ +
+
+
Or
+
+
+
+); + +External.propTypes = { + slot: PropTypes.string.isRequired, +}; + +export default External; diff --git a/client/coral-admin/src/components/SignIn.js b/client/coral-admin/src/components/SignIn.js index 5e1de2033..ddd69d3ac 100644 --- a/client/coral-admin/src/components/SignIn.js +++ b/client/coral-admin/src/components/SignIn.js @@ -4,6 +4,7 @@ import styles from './SignIn.css'; import { Button, TextField, Alert } from 'coral-ui'; import cn from 'classnames'; import Recaptcha from 'coral-framework/components/Recaptcha'; +import External from './External'; class SignIn extends React.Component { recaptcha = null; @@ -33,48 +34,55 @@ class SignIn extends React.Component { render() { const { email, password, errorMessage, requireRecaptcha } = this.props; return ( -
- {errorMessage && {errorMessage}} - - - {requireRecaptcha && ( -
- -
- )} - -

- Forgot your password?{' '} - + + + {errorMessage && {errorMessage}} + + + {requireRecaptcha && ( +

+ +
+ )} + +

+ {/* TODO: translate */} + Forgot your password?{' '} + + Request a new one. + +

+ + ); } } diff --git a/client/coral-admin/src/containers/SignIn.js b/client/coral-admin/src/containers/SignIn.js index 523d81091..1af857294 100644 --- a/client/coral-admin/src/containers/SignIn.js +++ b/client/coral-admin/src/containers/SignIn.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { withSignIn } from 'coral-framework/hocs'; +import { withSignIn, withPopupAuthHandler } from 'coral-framework/hocs'; import { compose } from 'recompose'; import SignIn from '../components/SignIn'; @@ -55,4 +55,4 @@ SignInContainer.propTypes = { requireRecaptcha: PropTypes.bool.isRequired, }; -export default compose(withSignIn)(SignInContainer); +export default compose(withSignIn, withPopupAuthHandler)(SignInContainer); diff --git a/client/coral-framework/services/postMessage.js b/client/coral-framework/services/postMessage.js index ef9311e64..6bc18eccf 100644 --- a/client/coral-framework/services/postMessage.js +++ b/client/coral-framework/services/postMessage.js @@ -56,10 +56,10 @@ export function createPostMessage(origin, scope = 'client') { // Send the message. target.postMessage(msg, origin); }, - subscribe: (handler, target = window) => { + subscribe(handler, target = window) { // If this handler is already attached to the target, detach it. if (has(listeners, [target, handler])) { - this.unsubscribeFromMessages(handler, target); + this.unsubscribe(handler, target); } // Wrap the listener with a origin check. @@ -71,7 +71,7 @@ export function createPostMessage(origin, scope = 'client') { // Attach the listener to the target. target.addEventListener('message', listener); }, - unsubscribe: (handler, target = window) => { + unsubscribe(handler, target = window) { if (!has(listeners, [target, handler])) { return; } diff --git a/client/coral-framework/utils/index.js b/client/coral-framework/utils/index.js index e30c12e06..6351c4484 100644 --- a/client/coral-framework/utils/index.js +++ b/client/coral-framework/utils/index.js @@ -273,3 +273,23 @@ export function translateError(error) { } return error.toString(); } + +/** + * handlePopupAuth will optionally open a popup with the requested uri if the + * window is not already a popup. + * + * @param {String} uri the url to open the window? to + * @param {String} title the title of the new window? to open + * @param {String} features the features to use when opening a window? + */ +export function handlePopupAuth( + uri, + title = 'Login', // TODO: translate + features = 'menubar=0,resizable=0,width=500,height=550,top=200,left=500' +) { + if (window.opener) { + window.location = uri; + } else { + window.open(uri, title, features); + } +} diff --git a/plugin-api/beta/client/utils/index.js b/plugin-api/beta/client/utils/index.js index aeb9841f9..0d1893066 100644 --- a/plugin-api/beta/client/utils/index.js +++ b/plugin-api/beta/client/utils/index.js @@ -9,4 +9,5 @@ export { getDefinitionName, getShallowChanges, createDefaultResponseFragments, + handlePopupAuth, } from 'coral-framework/utils'; diff --git a/plugins/talk-plugin-facebook-auth/client/actions.js b/plugins/talk-plugin-facebook-auth/client/actions.js index 79f2d2a6a..2f92ecfb6 100644 --- a/plugins/talk-plugin-facebook-auth/client/actions.js +++ b/plugins/talk-plugin-facebook-auth/client/actions.js @@ -1,3 +1,5 @@ +import { handlePopupAuth } from 'plugin-api/beta/client/utils'; + export const loginWithFacebook = () => (dispatch, _, { rest }) => { - window.location = `${rest.uri}/auth/facebook`; + handlePopupAuth(`${rest.uri}/auth/facebook`); }; diff --git a/plugins/talk-plugin-google-auth/client/actions.js b/plugins/talk-plugin-google-auth/client/actions.js index 8b49bf39e..1856ddb54 100644 --- a/plugins/talk-plugin-google-auth/client/actions.js +++ b/plugins/talk-plugin-google-auth/client/actions.js @@ -1,3 +1,5 @@ +import { handlePopupAuth } from 'plugin-api/beta/client/utils'; + export const loginWithGoogle = () => (dispatch, _, { rest }) => { - window.location = `${rest.uri}/auth/google`; + handlePopupAuth(`${rest.uri}/auth/google`); }; From bde1dff33b4868de902891e07c45c54635574f39 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 11 May 2018 14:45:03 -0600 Subject: [PATCH 2/3] changed to seperate slot --- client/coral-admin/src/components/SignIn.js | 2 +- plugins/talk-plugin-facebook-auth/client/index.js | 1 + plugins/talk-plugin-google-auth/client/index.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/coral-admin/src/components/SignIn.js b/client/coral-admin/src/components/SignIn.js index ddd69d3ac..a067ace1d 100644 --- a/client/coral-admin/src/components/SignIn.js +++ b/client/coral-admin/src/components/SignIn.js @@ -35,7 +35,7 @@ class SignIn extends React.Component { const { email, password, errorMessage, requireRecaptcha } = this.props; return (
- +
{errorMessage && {errorMessage}} Date: Thu, 17 May 2018 21:34:37 +0200 Subject: [PATCH 3/3] Don't close popup when there is an error --- client/coral-auth-callback/src/index.js | 50 +++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/client/coral-auth-callback/src/index.js b/client/coral-auth-callback/src/index.js index 41a83dcd2..7bf75e825 100644 --- a/client/coral-auth-callback/src/index.js +++ b/client/coral-auth-callback/src/index.js @@ -3,32 +3,36 @@ import { getStaticConfiguration } from 'coral-framework/services/staticConfigura import { createPostMessage } from 'coral-framework/services/postMessage'; document.addEventListener('DOMContentLoaded', () => { - try { - const staticConfig = getStaticConfiguration(); - const { STATIC_ORIGIN: origin } = staticConfig; - const postMessage = createPostMessage(origin); + const staticConfig = getStaticConfiguration(); + const { STATIC_ORIGIN: origin } = staticConfig; + const postMessage = createPostMessage(origin); - // Get the auth element and parse it as JSON by decoding it. - const auth = document.getElementById('auth'); - const doc = document.implementation.createHTMLDocument(''); - doc.body.innerHTML = auth.innerText; + // Get the auth element and parse it as JSON by decoding it. + const auth = document.getElementById('auth'); + const doc = document.implementation.createHTMLDocument(''); + doc.body.innerHTML = auth.innerText; - // Auth state is contained within the node. - const { err, data } = JSON.parse(doc.body.textContent); - if (err) { - // TODO: send back the error message. - console.error(err); + // Auth state is contained within the node. + const { err, data } = JSON.parse(doc.body.textContent); + if (err) { + const errDiv = document.createElement('div'); + if (err.message) { + errDiv.innerText = `${err.name}: ${err.message}`; } else { - // The data will contain a user and a token. - const { user, token } = data; - - // Send the state back. - postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token }); + errDiv.innerText = JSON.stringify(err); } - } finally { - // Always close the window. - setTimeout(() => { - window.close(); - }, 50); + document.body.appendChild(errDiv); + throw err; } + + // The data will contain a user and a token. + const { user, token } = data; + + // Send the state back. + postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token }); + + // Close the window when all went well. + setTimeout(() => { + window.close(); + }, 50); });