Fixed route changes not using getUrl causing invalid url to be used when
using pathPrefix, renamed basePath to prefixPath, updated how getUrl gets the prefixPath to prevent the need for rebuilding when its changed now just requires restart
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"globals": {
|
||||
"app": false
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"plugins": [
|
||||
"react"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 3030,
|
||||
"protocol": "http",
|
||||
"basePath": "/"
|
||||
"pathPrefix": "/"
|
||||
}
|
||||
@@ -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 (
|
||||
<html>
|
||||
<Head>
|
||||
@@ -16,6 +16,11 @@ export default class MyDocument extends Document {
|
||||
<link rel="icon" href={favicon} type="image/x-icon" />
|
||||
<link rel="stylesheet" href={getUrl('/_next/static/style.css')} />
|
||||
<title>My Knowledge Base</title>
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: 'window.kbConf=' + JSON.stringify(app.get('kbConf')),
|
||||
}}
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
23
src/app.js
23
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 }))
|
||||
|
||||
@@ -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
|
||||
@@ -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',
|
||||
})
|
||||
}
|
||||
|
||||
8
util/pathPrefix.js
Normal file
8
util/pathPrefix.js
Normal file
@@ -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
|
||||
@@ -1,8 +0,0 @@
|
||||
const basePath = require('./basePath')
|
||||
|
||||
module.exports = url => {
|
||||
if (basePath !== '/') {
|
||||
url = url.split(basePath).join('')
|
||||
}
|
||||
return url
|
||||
}
|
||||
8
util/stripPrefix.js
Normal file
8
util/stripPrefix.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const pathPrefix = require('./pathPrefix')
|
||||
|
||||
module.exports = url => {
|
||||
if (pathPrefix !== '/') {
|
||||
url = url.split(pathPrefix).join('')
|
||||
}
|
||||
return url
|
||||
}
|
||||
Reference in New Issue
Block a user