Initial commit

This commit is contained in:
Linus Miller 2017-02-23 19:27:30 +01:00
commit 2216758d14
27 changed files with 1001 additions and 0 deletions

42
.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# NPM Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
npm-debug.log
# Bower dependency directory
bower_components
.tern-port
/build
/dump
/public
/server/uploads

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "gulp"]
path = gulp
url = https://github.com/thebitmill/gulp.git

23
assets/less/dragula.less Normal file
View File

@ -0,0 +1,23 @@
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
// opacity: 0.8;
// -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
// filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.gu-transit {
display: none !important;
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}

29
assets/less/main.less Normal file
View File

@ -0,0 +1,29 @@
@import "./dragula";
div.container {
margin: 0 auto;
display: flex;
> div.location {
width: 100px;
height: 100px;
padding: 40px;
&.over {
> .item {
transform: scale(1.3);
background: blue;
}
}
}
}
div.item {
transition: all 0.2s;
width: 100px !important;
height: 100px !important;
background: red;
border-radius: 300px;
display: flex;
justify-content: center;
align-items: center;
}

55
client/index.js Normal file
View File

@ -0,0 +1,55 @@
import { $, $$ } from 'dollr';
import dragula from 'dragula';
const result = $('pre');
const containers = $$('.location');
const drake = dragula(containers, {
revertOnSpill: true,
// accepts(el, target, source, sibling) {
// // console.log('accepts');
// // console.log(target);
// return true;
// }
});
drake.on('drop', (el, target, source) => {
drake.cancel();
if (target !== source) {
fetch('/api/trip', {
method: 'POST',
headers: {
'content-type': 'application/json',
accepts: 'application/json',
},
body: JSON.stringify({
from: source.dataset.location,
to: target.dataset.location,
}),
}).then((res) => {
return res.json();
}).then((json) => {
console.log(json);
result.textContent = JSON.stringify(json, null, ' ')
}).catch((err) => {
console.log('error');
console.log(err);
});
}
});
drake.on('over', (el, target, source) => {
if (target !== source) {
target.classList.add('over');
}
});
drake.on('out', (el, target, source) => {
if (target !== source) {
target.classList.remove('over');
}
});

26
client/master.jsx Normal file
View File

@ -0,0 +1,26 @@
import { h } from 'jsx-node';
export default ({ articleUrl, protocol, hostname, websocketsPort, INITIAL_STATE, js, css, cssFile }) => {
return '<!doctype html>' + (
<html>
<head>
<title>Journey</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link type="text/css" rel="stylesheet" href={`/css/main` + (css ? css.suffix : '') + '.css'} />
</head>
<body>
<div class="container">
<div data-location="home" class="location l01"><div data-location="home" class="item"><span>Home</span></div></div>
<div data-location="office" class="location l02"><div data-location="office" class="item"><span>Office</span></div></div>
<div data-location="brother" class="location l03"><div data-location="brother" class="item"><span>Brother</span></div></div>
<div data-location="therapist" class="location l04"><div data-location="therapist" class="item"><span>The Rapist</span></div></div>
</div>
<pre></pre>
<script src={"/js/app" + (js ? js.suffix : '') + '.js'} />
</body>
</html>
);
};

10
client/pages/Error.jsx Normal file
View File

@ -0,0 +1,10 @@
import { h } from 'jsx-node';
export default ({ error = {}, regions = {}}) => (
<section className="error page">
<h1>Oops!</h1>
<p>Ett problem har tyvärr uppstått.</p>
<h2>{error.status} {error.statusText}</h2>
<p>{error.message}</p>
</section>
);

1
gulp Submodule

@ -0,0 +1 @@
Subproject commit 1daad4b4629c3ddef1f60710a0f7f8a67af9d714

51
gulpconfig.js Normal file
View File

@ -0,0 +1,51 @@
'use strict';
const fs = require('fs');
const p = require('path');
// modules > native
module.exports = {
// babel: {
// src: 'client/**/*.{js,jsx}',
// dest: 'build',
// babelrc: false,
// presets: ['es2015-node6', 'es2016', 'es2017', 'stage-0'],
// plugins: [
// 'add-module-exports',
// ['transform-react-jsx'],
// ['transform-react-remove-prop-types'],
// ['module-resolver', {
// alias: {
// lowline: 'lodash',
// react: 'jsx-node',
// 'easy-tz': 'easy-tz/cjs',
// 'mini-qs': 'querystring',
// },
// }],
// ],
// },
rollup: {
// plugins: {
// babel: {
// include: [
// 'node_modules/mini-qs/**',
// 'node_modules/easy-path/**',
// 'node_modules/comkit/**',
// 'client/**',
// ],
// babelrc: false,
// presets: ['es2015-rollup', 'es2016', 'es2017', 'stage-0'],
// plugins: [
// ['transform-react-jsx', { pragma: 'h' }],
// ],
// },
// },
entries: [
'index.js',
],
outputs: [
'app.js',
],
},
};

1
gulpfile.js Symbolic link
View File

@ -0,0 +1 @@
gulp/gulpfile.js

90
package.json Normal file
View File

@ -0,0 +1,90 @@
{
"name": "journey",
"version": "0.0.1",
"description": "",
"main": "server/server.js",
"scripts": {
"gulp": "gulp",
"gulp:production": "NODE_ENV=production gulp",
"gulp:development": "NODE_ENV=development gulp",
"gulp:staging": "NODE_ENV=staging gulp",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Linus Miller <lohfu@lohfu.io> (https://lohfu.io/)",
"license": "MIT",
"dependencies": {
"body-parser": "^1.16.1",
"chalk": "^1.1.3",
"cookie-parser": "^1.4.3",
"dollr": "^0.1.2",
"dragula": "^3.7.2",
"express": "^4.14.1",
"express-session": "^1.15.1",
"jsx-node": "^0.2.2",
"lodash": "^4.17.4",
"midwest": "github:thebitmill/midwest",
"midwest-service-errors": "^0.2.0",
"morgan": "^1.8.1",
"pg": "^6.1.2",
"require-dir": "^0.3.1",
"superagent": "^3.5.0",
"useragent": "^2.1.12",
"xml2json": "^0.11.0"
},
"devDependencies": {
"app-module-path": "^1.1.0",
"autoprefixer": "^6.7.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-module-resolver": "^2.5.0",
"babel-plugin-transform-react-jsx": "^6.23.0",
"babel-plugin-transform-react-remove-prop-types": "^0.3.2",
"babel-preset-es2015": "^6.22.0",
"babel-preset-es2015-node6": "^0.4.0",
"babel-preset-es2015-rollup": "^3.0.0",
"babel-preset-es2016": "^6.22.0",
"babel-preset-es2017": "^6.22.0",
"babel-preset-stage-0": "^6.22.0",
"babel-preset-stage-1": "^6.22.0",
"babel-preset-stage-2": "^6.22.0",
"babel-preset-stage-3": "^6.22.0",
"browser-sync": "^2.18.8",
"chalk": "^1.1.3",
"csswring": "^5.1.1",
"eslint": "^3.15.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-config-airbnb-base": "^11.1.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.9.0",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-babel": "^6.1.2",
"gulp-less": "^3.3.0",
"gulp-postcss": "^6.3.0",
"gulp-rename": "^1.2.2",
"gulp-sourcemaps": "^2.4.1",
"gulp-svgmin": "^1.2.3",
"gulp-uglify": "^2.0.1",
"gulp-util": "^3.0.8",
"jsx-node": "^0.2.1",
"less": "^2.7.2",
"lodash": "^4.17.4",
"merge-stream": "^1.0.1",
"mkdirp": "^0.5.1",
"nodemon": "^1.11.0",
"postcss": "^5.2.12",
"pretty-hrtime": "^1.0.3",
"rimraf": "^2.5.4",
"rollup": "^0.41.4",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-commonjs": "^7.0.0",
"rollup-plugin-node-resolve": "^2.0.0",
"rollup-plugin-replace": "^1.1.1",
"serialize-error": "^2.1.0",
"supertest": "^3.0.0",
"tap-spec": "^4.1.1",
"tape": "^4.6.3",
"through2": "^2.0.3",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
}
}

7
server/config/dir.js Normal file
View File

@ -0,0 +1,7 @@
'use strict';
const p = require('path');
module.exports = {
static: p.join(PWD, 'public'),
};

View File

@ -0,0 +1,51 @@
'use strict';
const _ = require('lodash');
const errorTemplate = require('../../build/pages/Error');
const defaults = {
post: (req, res, next) => {
res.template = errorTemplate;
next();
},
mystify: {
properties: ['errors', 'message', 'name', 'status', 'statusText'],
},
log: {
// if database = true there has to be a mongoose model name ErrorModel
ignore: [],
},
};
const store = require('midwest-service-errors/stores/postgres');
module.exports = _.merge(defaults, {
development: {
log: {
store,
console: true,
},
},
testing: {
log: {
store: false,
console: false,
},
},
staging: {
log: {
store,
console: false,
},
},
production: {
log: {
store,
console: false,
},
},
}[ENV]);

4
server/config/globals.js Normal file
View File

@ -0,0 +1,4 @@
'use strict';
// global.LOGIN_USER = 'linus.miller@bitmill.co';
// global.LOGIN_USER = 'zarac@zarac.se';

106
server/config/membership.js Normal file
View File

@ -0,0 +1,106 @@
'use strict';
const _ = require('lodash');
const config = {
site: require('./site'),
};
module.exports = {
invite: {
from: `${config.site.title} Robot <${config.site.emails.robot}>`,
subject: `You have been invited to ${config.site.title}`,
},
changePassword: {
from: `${config.site.title} Robot <${config.site.emails.robot}>`,
subject: `Password Reset Request for ${config.site.title}`,
},
timeouts: {
// 1 day
changePassword: 24 * 60 * 60 * 1000,
// verify email
verifyEmail: 7 * 24 * 60 * 60 * 1000,
},
paths: {
register: '/register',
login: '/login',
forgotPassword: '/forgot',
resetPassword: '/reset',
verifyEmail: '/verify',
},
redirects: {
login: '/',
logout: '/login',
register: '/login',
},
remember: {
// if expires is defined, it will be used. otherwise maxage
expires: new Date('2038-01-19T03:14:07.000Z'),
// expires: Date.now() - 1,
maxAge: 30 * 24 * 60 * 60 * 1000,
},
messages: {
login: {
notLocal: 'Account requires external login.',
wrongPassword: 'Wrong password.',
noUserFound: 'No user registered with that email.',
noExternalUser: 'The account is not connected to this website.',
externalLoginFailed: 'External login failed.',
emailNotVerified: 'This account\'s email has not been verified.',
banned: 'User is banned.',
blocked: 'User is blocked due to too many login attempts.',
},
register: {
missingProperties: 'Oh no missing stuff',
notAuthorized: 'The email is not authorized to create an account.',
duplicateEmail: 'The email has already been registered.',
},
},
passport: {
local: {
usernameField: 'email',
},
scope: ['email'],
//providers: {
// facebook: {
// clientID: 'change-this-fool',
// clientSecret: 'change-this-fool',
// callbackURL: p.join(config.site.domain, '/auth/facebook/callback'),
// passReqToCallback: true
// },
},
userColumns: [
'givenName',
'familyName',
'dateBanned',
'dateBlocked',
'dateMuted',
'dateVerified',
// ['array(SELECT name FROM user_roles LEFT OUTER JOIN roles ON user_roles.role_id = roles.id WHERE user_roles.user_id = users.id)', 'roles'],
[`(SELECT array_to_json(array_agg(row_to_json(d)))
FROM (
SELECT id, name
FROM user_roles
LEFT OUTER JOIN roles ON user_roles.role_id = roles.id WHERE user_roles.user_id = users.id
ORDER BY roles.id DESC
) d
)`, 'roles'],
],
// needs to be even
tokenLength: 64,
// needs to be even
saltLength: 16,
};

10
server/config/port.js Normal file
View File

@ -0,0 +1,10 @@
'use strict';
const basePort = 3060;
module.exports = {
development: basePort,
testing: basePort + 1,
staging: basePort + 2,
production: basePort + 3,
}[ENV];

16
server/config/postgres.js Normal file
View File

@ -0,0 +1,16 @@
'use strict';
const defaults = {
user: 'newseri_supreme', // env var: PGUSER
database: 'newseri', // env var: PGDATABASE
password: 'oh-look-it-is-raining-news', // env var: PGPASSWORD
// host: '192.168.1.11', // Server hosting the postgres database
host: 'hq.bitmill.co', // Server hosting the postgres database
// port: 5432, // env var: PGPORT
port: 6543, // env var: PGPORT
max: 10, // max number of clients in the pool
idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed
};
module.exports = Object.assign(defaults, {
}[ENV]);

38
server/config/session.js Normal file
View File

@ -0,0 +1,38 @@
'use strict';
const chalk = require('chalk');
const session = require('express-session');
let redisStore;
const config = {
secret: 'asdfpoi7u987777777777777777777sdkafjxxjasdhfhsadfhashdfh`1111111khjjashdfkasjhdflGGGGGGGGGGaaa^^^^^^^^^^yaghsdfqw3u7679`',
resave: false,
saveUninitialized: true,
};
const redisConfig = {
host: 'localhost',
port: 6379,
};
if (ENV === 'production') {
const RedisStore = require('connect-redis')(require('express-session'));
redisStore = new RedisStore(redisConfig);
redisStore.on('connect', () => {
console.info(`[${chalk.cyan('INIT')}] Redis connected succcessfully`);
});
redisStore.on('disconnect', () => {
throw new Error('Unable to connect to redis. Has it been started?');
});
config.store = redisStore;
} else {
config.store = new session.MemoryStore();
}
module.exports = config;

34
server/config/shim.js Normal file
View File

@ -0,0 +1,34 @@
'use strict';
module.exports = {
'https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-shim.min.js': [
'chrome <= 12',
'firefox <= 20',
'ie <= 9',
'opera <= 12',
'safari <= 5',
],
'https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.1/es6-shim.min.js': [
// 'https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js': [
// 'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.js': [
'chrome <= 51',
'edge <= 13',
'firefox <= 44',
'ie <= 11',
'safari <= 9',
],
'https://unpkg.com/es7-shim@latest/dist/es7-shim.min.js': [
'chrome <= 50',
'edge <= 14',
'firefox <= 46',
'ie <= 11',
'safari <= 10',
],
'https://cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js': [
'chrome <= 41',
'edge <= 13',
'firefox <= 38',
'ie <= 11',
'safari <= 9',
],
};

51
server/config/site.js Normal file
View File

@ -0,0 +1,51 @@
'use strict';
const _ = require('lodash');
const domain = 'newseri.com';
const defaults = {
domain,
title: 'Newseri Admin',
name: 'newseri-admin',
protocol: 'http',
get host() {
return this.port ? this.hostname + ':' + this.port : this.hostname;
},
get url() {
return this.protocol + '://' + this.host + '/';
},
emails: {
robot: 'no-reply@thecodebureau.com',
info: 'info@thecodebureau.com',
webmaster: 'webmaster@thecodebureau.com',
order: 'info@thecodebureau.com',
},
};
module.exports = _.merge(defaults, {
development: {
hostname: 'localhost',
port: process.env.EXTERNAL_PORT || process.env.PORT || require('./port'),
},
testing: {
hostname: 'localhost',
port: process.env.PORT || require('./port'),
},
staging: {
hostname: `admin.${domain}`,
},
production: {
hostname: `admin.${domain}`,
protocol: 'https',
// emails: {
// robot: 'no-reply@' + domain,
// info: 'info@' + domain,
// webmaster: 'webmaster@' + domain,
// order: 'order@' + domain,
// },
},
}[ENV]);

15
server/config/smtp.js Normal file
View File

@ -0,0 +1,15 @@
'use strict';
const _ = require('lodash');
const defaults = {
auth: {
user: 'SMTP_Injection',
// dev key
pass: '2eec390c5b3f5d593c9f152179bf51e90b073784',
},
host: 'smtp.sparkpostmail.com',
port: 587,
};
module.exports = _.merge(defaults, {}[ENV]);

6
server/db.js Normal file
View File

@ -0,0 +1,6 @@
'use strict';
const factory = require('midwest/util/db');
const conf = require('./config/postgres');
module.exports = factory(conf);

10
server/midwest.js Normal file
View File

@ -0,0 +1,10 @@
'use strict';
// const requireDir = require('require-dir');
// const membership = require('midwest-module-membership');
// const config = requireDir('./config', { camelcase: true });
// const db = require('./db');
// membership.configure(Object.assign({ db, site: config.site, smtp: config.smtp }, config.membership));

32
server/render.js Normal file
View File

@ -0,0 +1,32 @@
'use strict';
const { h } = require('jsx-node');
module.exports = function (Component, Master) {
const locals = Object.assign({ query: this.req.query }, this.app.locals, this.locals);
let html;
if (typeof Master === 'function') {
if (typeof Component === 'function') {
return this.send(
h(Master, locals,
h(Component, locals)
)
);
}
Component = Master;
}
if (typeof Component !== 'function') {
throw new Error('Not a Component');
} else if (Component.prototype && Component.prototype.render) {
const i = new Component(locals);
html = i.render(i.props, i.state);
} else {
html = Component(locals);
}
this.send(html);
};

67
server/routers/api.js Normal file
View File

@ -0,0 +1,67 @@
'use strict';
const request = require('superagent');
// import get from 'get-value';
const _ = require('lodash');
const xml2json = require('xml2json');
// const to = 'Lund Mellanvångsvägen';
// const from = 'Malmö Triangeln';
// request(`http://www.labs.skanetrafiken.se/v2.2/querypage.asp?inpPointFr=${encodeURIComponent(from)}&inpPointTo=${encodeURIComponent(to)}`).then((res) => {
// console.dir(xml2json.toJson(res.text, { object: true }), { colors: true, depth: null });
// });
const stations = {
home: {
id: '81016',
name: 'Lund Idrottsplatsen',
type: 'STOP_AREA',
},
office: {
name: 'Lund John Ericssons väg',
id: 81229,
type: 'STOP_AREA',
},
brother: {
id: '81831',
name: 'Lund Mellanvångsvägen',
type: 'STOP_AREA',
},
therapist: {
id: '80140',
name: 'Malmö Triangeln',
type: 'STOP_AREA',
},
};
const types = {
'STOP_AREA': 0,
}
const router = new (require('express')).Router();
function formatStation(json) {
return `${encodeURIComponent(json.name)}|${json.id}|${types[json.type]}`
}
const journeysPath = [ 'soap:Envelope', 'soap:Body', 'GetJourneyResponse', 'GetJourneyResult', 'Journeys', 'Journey']
// http://www.labs.skanetrafiken.se/v2.2/resultspage.asp?cmdaction=next&selPointFr=malm%F6%20C|80000|0&selPointTo=landskrona|82000|0&LastStart=2017-02-23%2016:38
router.post('/trip', (req, res, next) => {
request(`http://www.labs.skanetrafiken.se/v2.2/resultspage.asp?cmdaction=next&selPointFr=${formatStation(stations[req.body.from])}&selPointTo=${formatStation(stations[req.body.to])}&LastStart=2017-02-23%2016:38`).then((response) =>{
const result = _.get(xml2json.toJson(response.text, { object: true }), journeysPath);
result.forEach((obj) => {
delete obj.Prices
});
res.json(result);
});
});
module.exports = router;

106
server/routers/index.js Normal file
View File

@ -0,0 +1,106 @@
'use strict';
// const masterTemplate = require('../client/public/components/Master');
const masterTemplate = require('../../build/master');
// const loginFormTemplate = require('../build/components/login-form/template');
// const registerFormTemplate = require('../build/components/register-form/template');
// const changePasswordFormTemplate = require('../build/components/change-password-form/template');
// const forgotPasswordFormTemplate = require('../build/components/forgot-password-form/template');
// const bareMasterTemplate = require('../build/bare-master');
const router = new (require('express')).Router();
const startCase = require('lodash/startCase');
const mw = {
// employees: require('midwest-service-employees/middleware'),
// errors: require('midwest-service-errors/middleware'),
// invites: require('midwest-module-membership/services/invites/middleware'),
// organization: require('midwest-service-organization/middleware'),
// permissions: require('midwest-module-membership/services/permissions/middleware'),
// users: require('midwest-module-membership/services/users/middleware'),
// regions: require('midwest-service-regions/middleware'),
// publishers: require('../services/publishers/middleware'),
// roles: require('midwest-module-membership/services/roles/middleware'),
// users: require('../services/users/users-middleware'),
shim: require('midwest/factories/shim')(require('../config/shim')),
};
// const {
// isAuthenticated,
// isAdmin,
// redirectUnauthorized,
// redirectAuthorized,
// } = require('midwest-module-membership/passport/authorization-middleware');
const allowedRoutes = ['forgot', 'reset', 'verify', 'login', 'register'];
// const config = {
// membership: require('../config/membership'),
// };
router
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), isAdmin, redirectUnauthorized(config.membership.paths.login), (req, res, next) => {
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), (req, res, next) => {
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), isAuthenticated, redirectUnauthorized(config.membership.paths.login))
// .get(new RegExp(`/(?=(${allowedRoutes.join('|')}))`), redirectAuthorized(isAuthenticated, '/'))
.get('/', mw.shim, (req, res, next) => {
res.preventFlatten = true;
res.master = masterTemplate;
next();
})
// .get(new RegExp(`/${allowedRoutes.join('|')}`), redirectAuthenticated('/'), (req, res, next) => {
// res.preventFlatten = true;
// res.master = bareMasterTemplate;
// next();
// })
// .get('/login', (req, res, next) => {
// res.locals.scripts = ['/js/login.js'];
// res.template = loginFormTemplate;
// next();
// })
// .get('/register', mw.invites.findByTokenAndEmail, (req, res, next) => {
// res.locals.scripts = ['/js/register.js'];
// res.template = registerFormTemplate;
// next();
// })
// .get('/change-password', (req, res, next) => {
// res.locals.scripts = ['/js/change-password.js'];
// res.template = changePasswordFormTemplate;
// next();
// })
// .get('/forgot-password', (req, res, next) => {
// res.locals.scripts = ['/js/forgot-password.js'];
// res.template = forgotPasswordFormTemplate;
// next();
// .get('/membership/users/:id', mw.publishers.getAll, mw.roles.getAll, mw.users.findById, (req, res, next) => {
// console.log(res.locals.roles);
// // res.locals.allRoles = res.locals.roles;
// // console.log(res.locals);
// // res.locals.allPublishers = res.locals.publishers.filter((publisher) => !res.locals.user.publishers.some((p) => {
// // return publisher._id.toString() === p._id.toString();
// // }));
// // delete res.locals.roles;
// // delete res.locals.publishers;
// next();
// })
// .get('/errors', mw.errors.formatQuery, mw.errors.paginate, mw.errors.find)
// .get('/login')
// .get('/forgot')
// .get('/reset')
// .get('/verify')
;
module.exports = router;

117
server/server.js Normal file
View File

@ -0,0 +1,117 @@
'use strict';
/*
* The main file that sets up the Express instance and node
*
* @module server/server
* @type {Express instance}
*/
global.ENV = process.env.NODE_ENV || 'development';
global.PWD = process.env.NODE_PWD || process.cwd();
// modules > native
const p = require('path');
if (ENV === 'development') {
// output filename in console log and colour console.dir
require('midwest/util/console');
// needed so symlinked modules get access to main projects node_modules/
require('app-module-path').addPath(p.join(PWD, 'node_modules'));
}
// modules > 3rd party
const _ = require('lodash');
const chalk = require('chalk');
const express = require('express');
// const passport = require('passport');
const requireDir = require('require-dir');
// modules > express middlewares
const bodyParser = require('body-parser');
// const session = require('express-session');
// const cookieParser = require('cookie-parser');
// modules > midwest
const colorizeStack = require('midwest/util/colorize-stack');
// make error output stack pretty
process.on('uncaughtException', (err) => {
console.error(chalk.red('UNCAUGHT EXCEPTION'));
if (err.stack) {
console.error(colorizeStack(err.stack));
} else {
console.error(err);
}
process.exit(1);
});
// midwest modules and services configuration
require('./midwest');
const config = requireDir('./config', { camelcase: true });
const prewares = [
express.static(config.dir.static, ENV === 'production' ? { maxAge: '1 year' } : null),
bodyParser.json(),
bodyParser.urlencoded({ extended: true }),
// cookieParser(),
// session(config.session),
// passport.initialize(),
// passport.session(),
];
if (ENV === 'development') {
// only log requests to console in development mode
prewares.unshift(require('morgan')('dev'));
// prewares.push(require('midwest-module-membership/passport/automatic-login'));
}
const postwares = [
require('midwest/middleware/ensure-found'),
// transform and log error
require('midwest/factories/error-handler')(config.errorHandler),
// respond
require('midwest/middleware/responder'),
];
const server = express();
// get IP & whatnot from nginx proxy
server.set('trust proxy', true);
_.extend(server.locals, {
site: require('./config/site'),
});
// override default response render method for
// more convenient use with marko
server.response.render = require('./render');
try {
server.locals.js = require(p.join(PWD, 'public/js.json'));
} catch (e) {}
try {
server.locals.css = require(p.join(PWD, 'public/css.json'));
} catch (e) {}
// load prewares
server.use(...prewares);
// mount routers
server.use(require('./routers/index'));
server.use('/api', require('./routers/api'));
// server.use('/auth', require('midwest-module-membership/passport/router'));
// load postwares
server.use(...postwares);
// Only start Express server when it is the main module (ie not required by test)
if (require.main === module) {
server.http = server.listen(config.port, () => {
console.info(`[${chalk.cyan('INIT')}] HTTP Server listening on port ${chalk.magenta(config.port)} (${chalk.yellow(ENV)})`);
});
}
module.exports = server;