2017-02-08 09:15:09 +08:00
|
|
|
import { createMemoryHistory } from 'react-router';
|
|
|
|
|
2017-02-08 04:36:57 +08:00
|
|
|
import { Meteor } from 'meteor/meteor';
|
|
|
|
import { DDP } from 'meteor/ddp';
|
|
|
|
import { Accounts } from 'meteor/accounts-base';
|
2017-02-08 09:15:09 +08:00
|
|
|
import { RoutePolicy } from 'meteor/routepolicy';
|
2017-02-08 04:36:57 +08:00
|
|
|
|
|
|
|
import { createApolloClient, getReducers, getMiddlewares } from '../modules/index.js';
|
|
|
|
import { configureStore } from './store.js';
|
|
|
|
|
|
|
|
const Fiber = Npm.require('fibers');
|
|
|
|
|
|
|
|
export const renderContext = new Meteor.EnvironmentVariable();
|
|
|
|
|
|
|
|
export const getRenderContext = () => renderContext.get();
|
|
|
|
|
2017-02-08 09:15:09 +08:00
|
|
|
function isAppUrl(req) {
|
|
|
|
const url = req.url;
|
|
|
|
if (url === '/favicon.ico' || url === '/robots.txt') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (url === '/app.manifest') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Avoid serving app HTML for declared routes such as /sockjs/.
|
|
|
|
if (RoutePolicy.classify(url)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we only need to support HTML pages only
|
|
|
|
// this is a check to do it
|
|
|
|
return /html/.test(req.headers.accept);
|
|
|
|
}
|
|
|
|
|
2017-02-08 04:36:57 +08:00
|
|
|
const LoginContext = function LoginContext(loginToken) {
|
|
|
|
this._loginToken = loginToken;
|
|
|
|
|
|
|
|
// get the user
|
|
|
|
if (Meteor.users) {
|
|
|
|
// check to make sure, we've the loginToken,
|
|
|
|
// otherwise a random user will fetched from the db
|
|
|
|
let user;
|
|
|
|
if (loginToken) {
|
|
|
|
const hashedToken = loginToken && Accounts._hashLoginToken(loginToken);
|
|
|
|
const query = { 'services.resume.loginTokens.hashedToken': hashedToken };
|
|
|
|
const options = { fields: { _id: 1 } };
|
|
|
|
user = Meteor.users.findOne(query, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
this.userId = user._id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-02-08 09:15:09 +08:00
|
|
|
export const withRenderContextRaw = (func, options = {}) => {
|
2017-02-08 04:36:57 +08:00
|
|
|
const newFunc = Meteor.bindEnvironment((req, res, next) => {
|
|
|
|
Fiber.current._meteor_dynamics = Fiber.current._meteor_dynamics || [];
|
|
|
|
Fiber.current._meteor_dynamics[DDP._CurrentInvocation.slot] = req.loginContext;
|
|
|
|
Fiber.current._meteor_dynamics[renderContext.slot] = req.renderContext;
|
|
|
|
|
|
|
|
func(req, res, next);
|
|
|
|
|
|
|
|
if (options.autoNext) {
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if (options.name) {
|
|
|
|
Object.defineProperty(newFunc, 'name', { value: options.name });
|
|
|
|
}
|
|
|
|
WebApp.connectHandlers.use(newFunc);
|
|
|
|
}
|
|
|
|
|
2017-02-08 09:15:09 +08:00
|
|
|
export const withRenderContext = (func) => {
|
|
|
|
withRenderContextRaw(func, { autoNext: true });
|
|
|
|
};
|
|
|
|
|
|
|
|
WebApp.connectHandlers.use(Meteor.bindEnvironment((req, res, next) => {
|
|
|
|
if (!isAppUrl(req)) {
|
|
|
|
next();
|
|
|
|
return;
|
|
|
|
}
|
2017-02-08 04:36:57 +08:00
|
|
|
|
2017-02-08 09:15:09 +08:00
|
|
|
req.history = createMemoryHistory(req.url);
|
|
|
|
req.loginToken = req.cookies && req.cookies.meteor_login_token;
|
|
|
|
req.apolloClient = createApolloClient({ currentUserToken: req.loginToken });
|
|
|
|
req.reducers = { ...getReducers(), apollo: req.apolloClient.reducer() };
|
|
|
|
req.middlewares = [...getMiddlewares(), req.apolloClient.middleware()];
|
|
|
|
req.store = configureStore(req.reducers, {}, req.middlewares);
|
|
|
|
req.loginContext = new LoginContext(req.loginToken);
|
|
|
|
req.renderContext = {
|
|
|
|
history: req.history,
|
|
|
|
loginToken: req.loginToken,
|
|
|
|
apolloClient: req.apolloClient,
|
|
|
|
reducers: req.reducers,
|
|
|
|
middlewares: req.middlewares,
|
|
|
|
store: req.store,
|
|
|
|
};
|
2017-02-08 04:36:57 +08:00
|
|
|
next();
|
2017-02-08 09:15:09 +08:00
|
|
|
}));
|