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:
JJ Kasper
2018-06-01 20:56:02 -05:00
parent 017a9993ee
commit e35f6f74eb
12 changed files with 80 additions and 54 deletions

View File

@@ -1,4 +1,7 @@
{
"globals": {
"app": false
},
"parser": "babel-eslint",
"plugins": [
"react"

View File

@@ -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

View File

@@ -1,6 +1,5 @@
{
"host": "localhost",
"port": 3030,
"protocol": "http",
"basePath": "/"
"pathPrefix": "/"
}

View File

@@ -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 />

View File

@@ -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)

View File

@@ -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()

View File

@@ -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 }))

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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
View File

@@ -0,0 +1,8 @@
const pathPrefix = require('./pathPrefix')
module.exports = url => {
if (pathPrefix !== '/') {
url = url.split(pathPrefix).join('')
}
return url
}