mirror of
https://github.com/wassname/talk.git
synced 2026-08-06 13:41:02 +08:00
Added support for hosting Talk under a different path
This commit is contained in:
@@ -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
|
||||
//==============================================================================
|
||||
|
||||
@@ -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 = (
|
||||
</div>
|
||||
);
|
||||
|
||||
const AppRouter = () => <Router history={browserHistory} routes={routes} />;
|
||||
const AppRouter = () => <Router history={useBasename(() => browserHistory)({
|
||||
basename: '/talk/'
|
||||
})} routes={routes}/>;
|
||||
|
||||
export default AppRouter;
|
||||
|
||||
@@ -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 = `
|
||||
<div id="${streamElementId}"></div>
|
||||
<script src="${coralJsUrl}" async onload="
|
||||
Coral.Talk.render(document.getElementById('${streamElementId}'), {
|
||||
talk: '${talkBaseUrl}'
|
||||
talk: '${BASE_URL}'
|
||||
});
|
||||
"></script>
|
||||
`.trim();
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -109,6 +109,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
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
+2
-1
@@ -37,10 +37,11 @@
|
||||
<% if (data != null) { %>
|
||||
<script id="data" type="application/json"><%- JSON.stringify(data) %></script>
|
||||
<% } %>
|
||||
<base href="<%= BASE_URL %>"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src='https://www.google.com/recaptcha/api.js?render=explicit' async defer></script>
|
||||
<script src="<%= basePath %>/bundle.js" charset="utf-8"></script>
|
||||
<script src="client/coral-admin/bundle.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
<% if (data != null) { %>
|
||||
<script id="data" type="application/json"><%- JSON.stringify(data) %></script>
|
||||
<% } %>
|
||||
<base href="<%= BASE_URL %>"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="talk-embed-stream-container"></div>
|
||||
<script src="/client/embed/stream/bundle.js"></script>
|
||||
<script src="client/embed/stream/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ const config = {
|
||||
new webpack.EnvironmentPlugin({
|
||||
'TALK_PLUGINS_JSON': '{}',
|
||||
'TALK_THREADING_LEVEL': '3',
|
||||
'TALK_DEFAULT_STREAM_TAB': 'all',
|
||||
'TALK_DEFAULT_STREAM_TAB': 'all'
|
||||
})
|
||||
],
|
||||
resolveLoader: {
|
||||
|
||||
Reference in New Issue
Block a user