diff --git a/app.js b/app.js
index 108ad2e11..0be7a1830 100644
--- a/app.js
+++ b/app.js
@@ -15,6 +15,7 @@ const apollo = require('graphql-server-express');
const accepts = require('accepts');
const compression = require('compression');
const cookieParser = require('cookie-parser');
+const {ROOT_URL} = require('./config');
const app = express();
@@ -74,6 +75,12 @@ app.use('/public', express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
+// Set the BASE_URL as the ROOT_URL.
+app.locals.BASE_URL = ROOT_URL;
+if (app.locals.BASE_URL[app.locals.BASE_URL.length - 1] !== '/') {
+ app.locals.BASE_URL += '/';
+}
+
//==============================================================================
// PASSPORT MIDDLEWARE
//==============================================================================
diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js
index aee40a3a8..99eea97ae 100644
--- a/client/coral-admin/src/AppRouter.js
+++ b/client/coral-admin/src/AppRouter.js
@@ -1,5 +1,6 @@
import React from 'react';
import {Router, Route, IndexRedirect, browserHistory, Redirect} from 'react-router';
+import {useBasename} from 'history';
import Configure from 'routes/Configure';
import Dashboard from 'routes/Dashboard';
@@ -56,6 +57,8 @@ const routes = (
);
-const AppRouter = () => ;
+const AppRouter = () => browserHistory)({
+ basename: '/talk/'
+})} routes={routes}/>;
export default AppRouter;
diff --git a/client/coral-admin/src/routes/Configure/components/EmbedLink.js b/client/coral-admin/src/routes/Configure/components/EmbedLink.js
index 1cd48cdc5..4506d2f06 100644
--- a/client/coral-admin/src/routes/Configure/components/EmbedLink.js
+++ b/client/coral-admin/src/routes/Configure/components/EmbedLink.js
@@ -2,6 +2,7 @@ import React, {Component} from 'react';
import t from 'coral-framework/services/i18n';
import styles from './Configure.css';
import {Button, Card} from 'coral-ui';
+import {BASE_URL} from 'coral-framework/constants/url';
class EmbedLink extends Component {
@@ -24,21 +25,14 @@ class EmbedLink extends Component {
}
render () {
- const location = window.location;
- const talkBaseUrl = [
- location.protocol,
- '//',
- location.hostname,
- location.port ? (`:${window.location.port}`) : ''
- ].join('');
- const coralJsUrl = [talkBaseUrl, '/embed.js'].join('');
+ const coralJsUrl = [BASE_URL, '/embed.js'].join('');
const nonce = String(Math.random()).slice(2);
const streamElementId = `coral_talk_${nonce}`;
const embedText = `
`.trim();
diff --git a/client/coral-framework/constants/url.js b/client/coral-framework/constants/url.js
new file mode 100644
index 000000000..92144bdec
--- /dev/null
+++ b/client/coral-framework/constants/url.js
@@ -0,0 +1,7 @@
+import url from 'url';
+
+const base = document.querySelector('base');
+const baseUrl = base && url.parse(base.href) || {};
+
+export const BASE_URL = base.href;
+export const BASE_PATH = baseUrl.pathname;
diff --git a/client/coral-framework/helpers/request.js b/client/coral-framework/helpers/request.js
index 57e3a6cde..782aa83f6 100644
--- a/client/coral-framework/helpers/request.js
+++ b/client/coral-framework/helpers/request.js
@@ -2,6 +2,7 @@ import bowser from 'bowser';
import * as Storage from './storage';
import merge from 'lodash/merge';
import {getStore} from 'coral-framework/services/store';
+import {BASE_PATH} from 'coral-framework/constants/url';
/**
* getAuthToken returns the active auth token or null
@@ -75,7 +76,7 @@ const handleResp = (res) => {
}
};
-export const base = '/api/v1';
+export const base = `${BASE_PATH}api/v1`;
export default (url, options) => {
return fetch(`${base}${url}`, buildOptions(options)).then(handleResp);
diff --git a/client/coral-framework/services/client.js b/client/coral-framework/services/client.js
index b266822fb..6f044f621 100644
--- a/client/coral-framework/services/client.js
+++ b/client/coral-framework/services/client.js
@@ -4,6 +4,7 @@ import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transpo
import MessageTypes from 'subscriptions-transport-ws/dist/message-types';
import {getAuthToken} from '../helpers/request';
import introspectionQueryResultData from '../graphql/introspection.json';
+import {BASE_PATH} from 'coral-framework/constants/url';
let client, wsClient = null, wsClientToken = null;
@@ -33,7 +34,7 @@ export function getClient(options = {}) {
}
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
- wsClient = new SubscriptionClient(`${protocol}://${location.host}/api/v1/live`, {
+ wsClient = new SubscriptionClient(`${protocol}://${location.host}${BASE_PATH}api/v1/live`, {
reconnect: true,
lazy: true,
connectionParams: {
diff --git a/client/coral-framework/services/transport.js b/client/coral-framework/services/transport.js
index f11c20888..060bfc34b 100644
--- a/client/coral-framework/services/transport.js
+++ b/client/coral-framework/services/transport.js
@@ -1,12 +1,13 @@
import {createNetworkInterface} from 'apollo-client';
import {getAuthToken} from '../helpers/request';
+import {BASE_PATH} from 'coral-framework/constants/url';
//==============================================================================
// NETWORK INTERFACE
//==============================================================================
const networkInterface = createNetworkInterface({
- uri: '/api/v1/graph/ql',
+ uri: `${BASE_PATH}api/v1/graph/ql`,
opts: {
credentials: 'same-origin'
}
diff --git a/config.js b/config.js
index 3769998ae..c6ea774a3 100644
--- a/config.js
+++ b/config.js
@@ -72,7 +72,7 @@ const CONFIG = {
PORT: process.env.TALK_PORT || '3000',
// The URL for this Talk Instance as viewable from the outside.
- ROOT_URL: process.env.TALK_ROOT_URL,
+ ROOT_URL: process.env.TALK_ROOT_URL || null,
// The keepalive timeout (in ms) that should be used to send keep alive
// messages through the websocket to keep the socket alive.
@@ -112,6 +112,12 @@ const CONFIG = {
// CONFIG VALIDATION
//==============================================================================
+if (process.env.NODE_ENV === 'test' && !CONFIG.ROOT_URL) {
+ CONFIG.ROOT_URL = 'http://localhost:3000';
+} else if (!CONFIG.ROOT_URL) {
+ throw new Error('TALK_ROOT_URL must be provided');
+}
+
//------------------------------------------------------------------------------
// JWT based configuration
//------------------------------------------------------------------------------
diff --git a/package.json b/package.json
index 54a136cee..476e7eda5 100644
--- a/package.json
+++ b/package.json
@@ -178,6 +178,7 @@
"graphql-docs": "^0.2.0",
"graphql-tag": "^1.2.3",
"hammerjs": "^2.0.8",
+ "history": "^3.0.0",
"ignore-styles": "^5.0.1",
"immutable": "^3.8.1",
"imports-loader": "^0.7.1",
diff --git a/plugins/talk-plugin-facebook-auth/server/passport.js b/plugins/talk-plugin-facebook-auth/server/passport.js
index ae69ec4bd..14849b7da 100644
--- a/plugins/talk-plugin-facebook-auth/server/passport.js
+++ b/plugins/talk-plugin-facebook-auth/server/passport.js
@@ -1,13 +1,20 @@
const FacebookStrategy = require('passport-facebook').Strategy;
const UsersService = require('services/users');
const {ValidateUserLogin} = require('services/passport');
+let {
+ ROOT_URL
+} = require('config');
+
+if (ROOT_URL[ROOT_URL.length - 1] !== '/') {
+ ROOT_URL += '/';
+}
module.exports = (passport) => {
if (process.env.TALK_FACEBOOK_APP_ID && process.env.TALK_FACEBOOK_APP_SECRET && process.env.TALK_ROOT_URL) {
passport.use(new FacebookStrategy({
clientID: process.env.TALK_FACEBOOK_APP_ID,
clientSecret: process.env.TALK_FACEBOOK_APP_SECRET,
- callbackURL: `${process.env.TALK_ROOT_URL}/api/v1/auth/facebook/callback`,
+ callbackURL: `${ROOT_URL}api/v1/auth/facebook/callback`,
passReqToCallback: true,
profileFields: ['id', 'displayName', 'picture.type(large)']
}, async (req, accessToken, refreshToken, profile, done) => {
diff --git a/routes/admin/index.js b/routes/admin/index.js
index 44ce83222..30bb69f5e 100644
--- a/routes/admin/index.js
+++ b/routes/admin/index.js
@@ -23,7 +23,7 @@ router.get('*', (req, res) => {
TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC
};
- res.render('admin', {basePath: '/client/coral-admin', data});
+ res.render('admin', {data});
});
module.exports = router;
diff --git a/views/admin.ejs b/views/admin.ejs
index 54c666395..0a7c1c218 100644
--- a/views/admin.ejs
+++ b/views/admin.ejs
@@ -4,19 +4,19 @@
Talk - Coral Admin
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -37,10 +37,11 @@
<% if (data != null) { %>
<% } %>
+
-
+