diff --git a/.eslintrc.json b/.eslintrc.json
index 932a783..51fc6b5 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,4 +1,7 @@
{
+ "globals": {
+ "app": false
+ },
"parser": "babel-eslint",
"plugins": [
"react"
diff --git a/README.md b/README.md
index bfc6a13..250f357 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ host.json
| ---- | ----------- |
| host | The host to listen on |
| port | The port to listen on |
-| basePath | Used to prefix all urls for reverse proxies |
+| prefixPath | Used to prefix all urls for reverse proxies |
production.json (overrides default.json with production NODE_ENV var)
@@ -85,12 +85,6 @@ Lint both
npm lint
```
-## Changelog
-
-__0.1.0__
-
-- Initial release
-
## License
Copyright (c) 2017
diff --git a/config/host.json b/config/host.json
index a424690..b9297cc 100644
--- a/config/host.json
+++ b/config/host.json
@@ -1,6 +1,5 @@
{
"host": "localhost",
"port": 3030,
- "protocol": "http",
- "basePath": "/"
+ "pathPrefix": "/"
}
\ No newline at end of file
diff --git a/pages/_document.js b/pages/_document.js
index 13ab210..ddeb8b2 100644
--- a/pages/_document.js
+++ b/pages/_document.js
@@ -3,7 +3,7 @@ import getUrl from '../util/getUrl'
export default class MyDocument extends Document {
render() {
- const favicon = getUrl('favicon.ico')
+ const favicon = getUrl('favicon.icon')
return (
@@ -16,6 +16,11 @@ export default class MyDocument extends Document {
My Knowledge Base
+
diff --git a/pages/index.js b/pages/index.js
index 7a4b587..17f0979 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -2,12 +2,14 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'
import Router from 'next/router'
import Paginate from 'react-paginate'
+import { format } from 'url'
import Page from '../comps/Page'
import PaddedRow from '../comps/PaddedRow'
import Spinner from '../comps/Spinner'
import DocItem from '../comps/DocItem'
import { $limit, getDocs, buildQ } from '../util/getDocs'
import getJwt from '../util/getJwt'
+import getUrl from '../util/getUrl'
import mapUser from '../util/mapUser'
class Index extends Component {
@@ -20,6 +22,7 @@ class Index extends Component {
total: 0,
docs: [],
}
+
static async getInitialProps({ req, query }) {
let page = 1,
$search = ''
@@ -33,6 +36,25 @@ class Index extends Component {
const data = await getDocs(q, req ? jwt : false)
return { ...data, page, $search }
}
+
+ static getDerivedStateFromProps(nextProps, prevState) {
+ let { docs, total, page, $search } = nextProps
+ if (
+ docs.length !== prevState.docs.length ||
+ page !== prevState.page ||
+ $search !== prevState.$search
+ ) {
+ return { total, docs, page, $search, pending: false }
+ }
+ return null
+ }
+
+ pushQuery = query =>
+ Router.push(
+ { pathname: '/', query },
+ format({ pathname: getUrl('/'), query })
+ )
+
updDocs = (time, doSearch) => {
clearTimeout(this.docsTime)
this.docsTime = setTimeout(async () => {
@@ -40,7 +62,7 @@ class Index extends Component {
if (doSearch) {
const query = { search: $search }
if (!$search) delete query.search
- Router.push({ pathname: '/', query })
+ this.pushQuery(query)
}
this.setState({ error: null })
this.docsTime = setTimeout(() => {
@@ -53,10 +75,12 @@ class Index extends Component {
this.setState({ ...data, pending: false })
}, time || 275)
}
+
updQuery = e => {
this.setState({ [e.target.id]: e.target.value })
this.updDocs(0, e.target.id === '$search')
}
+
handlePage = ({ selected }) => {
const { $search } = this.state
const page = selected + 1
@@ -64,25 +88,16 @@ class Index extends Component {
this.setState({ page })
if (page > 1) query.page = page
if ($search) query.search = $search
- Router.push({ pathname: '/', query })
+ this.pushQuery(query)
this.updDocs(1)
}
- static getDerivedStateFromProps(nextProps, prevState) {
- let { docs, total, page, $search } = nextProps
- if (
- docs.length !== prevState.docs.length ||
- page !== prevState.page ||
- $search !== prevState.$search
- ) {
- return { total, docs, page, $search, pending: false }
- }
- return null
- }
+
componentDidUpdate(prevProps) {
const { user, docs } = this.props
if (prevProps.user.email === user.email) return
if (user.email && docs.length === 0) this.updDocs(1)
}
+
render() {
const { $sort, $search, pending, error, docs, total, page } = this.state
const pages = Math.ceil(total / $limit)
diff --git a/pages/k.js b/pages/k.js
index 6da01a1..01a409b 100644
--- a/pages/k.js
+++ b/pages/k.js
@@ -18,7 +18,7 @@ class k extends Component {
headers: { Authorization: getJwt() },
method: 'DELETE',
}).catch(({ message }) => ({ ok: false, message }))
- if (del.ok) Router.push('/')
+ if (del.ok) Router.push('/', getUrl('/'))
else {
if (!del.message) {
const data = await del.json()
diff --git a/src/app.js b/src/app.js
index d09b6e5..2ee5dc0 100644
--- a/src/app.js
+++ b/src/app.js
@@ -21,14 +21,15 @@ const channels = require('./channels')
const authentication = require('./authentication')
const dev = process.env.NODE_ENV !== 'production'
-const basePath = require('../util/basePath')
-const stripBase = require('../util/stripBase')
+const pathPrefix = require('../util/pathPrefix')
+const stripBase = require('../util/stripPrefix')
const getUrl = require('../util/getUrl')
const { parse } = require('url')
const nxt = require('next')({ dev, quiet: true })
const nxtHandler = nxt.getRequestHandler()
const app = express(feathers())
+global.app = app
app.run = async port => {
const server = app.listen(port)
@@ -36,7 +37,8 @@ app.run = async port => {
if (dev) {
server.on('upgrade', (req, socket) => {
- nxtHandler(req, socket, parse(stripBase(req.url), true))
+ req.url = stripBase(req.url)
+ nxtHandler(req, socket, parse(req.url, true))
})
}
return server
@@ -45,10 +47,12 @@ app.run = async port => {
// Load app configuration
app.configure(configuration())
-// load host config
+// load host and setup settings
Object.keys(hostConfig).forEach(key => app.set(key, hostConfig[key]))
+app.set('kbConf', {
+ pathPrefix,
+})
app.set('didSetup', false)
-
try {
fs.statSync(path.join(__dirname, '..', 'db', '.didSetup'))
app.set('didSetup', true)
@@ -88,6 +92,8 @@ app.configure(authentication) // Set up authentication
app.configure(services) // Set up our services (see `services/index.js`)
app.configure(channels) // Set up event channels (see channels.js)
+nxt.setAssetPrefix(pathPrefix)
+
const checkJWT = async (req, res, next) => {
const result = await req.app.authenticate('jwt', {})(req)
if (result.success) {
@@ -97,7 +103,6 @@ const checkJWT = async (req, res, next) => {
}
next()
}
-nxt.setAssetPrefix(basePath) // setup next.js routes
;['/', '/logout', '/new', '/settings'].forEach(route => {
app.get(getUrl(route), cookieParser, checkJWT, (req, res) => {
const { query } = parse(req.url, true)
@@ -115,9 +120,11 @@ app.use((req, res, next) => {
let accept = req.get('accept')
if (accept && accept.toLowerCase() === 'application/json')
return notFound(req, res, next)
- if (req.url.substr(0, basePath.length) !== basePath)
+ if (req.url.substr(0, pathPrefix.length) !== pathPrefix)
return nxt.render404(req, res)
- nxtHandler(req, res, parse(stripBase(req.url), true))
+
+ req.url = stripBase(req.url)
+ nxtHandler(req, res, parse(req.url, true))
})
app.use(express.errorHandler({ logger }))
diff --git a/util/basePath.js b/util/basePath.js
deleted file mode 100644
index 901a3ed..0000000
--- a/util/basePath.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// make sure basePath doesn't end with /
-let { basePath } = require('../config/host.json')
-const urlChars = basePath.split('')
-
-if (basePath.length > 1 && urlChars.pop() === '/') {
- basePath = urlChars.join('')
-}
-module.exports = basePath
diff --git a/util/getUrl.js b/util/getUrl.js
index bff9cef..b9e1594 100644
--- a/util/getUrl.js
+++ b/util/getUrl.js
@@ -1,15 +1,18 @@
const url = require('url')
const urljoin = require('url-join')
-const basePath = require('./basePath')
-const { host, port, protocol } = require('../config/host.json')
module.exports = (path, absolute) => {
- path = urljoin(basePath, path)
+ const { pathPrefix } =
+ typeof window === 'undefined' ? app.get('kbConf') : window.kbConf
+
+ path = urljoin(pathPrefix, path)
if (!absolute) return path
+
+ // absolute should only be used during ssr
return url.format({
- hostname: host,
- port,
- protocol,
+ hostname: app.get('host'),
+ port: app.get('port'),
pathname: path,
+ protocol: 'http',
})
}
diff --git a/util/pathPrefix.js b/util/pathPrefix.js
new file mode 100644
index 0000000..e758666
--- /dev/null
+++ b/util/pathPrefix.js
@@ -0,0 +1,8 @@
+// make sure basePath doesn't end with /
+let { pathPrefix } = require('../config/host.json')
+const urlChars = pathPrefix.split('')
+
+if (pathPrefix.length > 1 && urlChars.pop() === '/') {
+ pathPrefix = urlChars.join('')
+}
+module.exports = pathPrefix
diff --git a/util/stripBase.js b/util/stripBase.js
deleted file mode 100644
index 876ef72..0000000
--- a/util/stripBase.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const basePath = require('./basePath')
-
-module.exports = url => {
- if (basePath !== '/') {
- url = url.split(basePath).join('')
- }
- return url
-}
diff --git a/util/stripPrefix.js b/util/stripPrefix.js
new file mode 100644
index 0000000..b42b53a
--- /dev/null
+++ b/util/stripPrefix.js
@@ -0,0 +1,8 @@
+const pathPrefix = require('./pathPrefix')
+
+module.exports = url => {
+ if (pathPrefix !== '/') {
+ url = url.split(pathPrefix).join('')
+ }
+ return url
+}