No docs found...
}
{!error ? null :
+ {!pending || error ? null : (
+
+ )}
+ {docs.length < 1 || pending || error ? null : (
+
- |
- Doc Modified
- |
+
+ |
+ Doc Modified
+ |
+
{docs.map(doc => )}
-
- {pages < 2 ? null
- :
+ {pages < 2 ? null : (
+
- }
+ )}
- }
-
+ )}
+
- );
+ )
}
}
-export default connect(mapUser)(Index);
\ No newline at end of file
+export default connect(mapUser)(Index)
diff --git a/pages/k.js b/pages/k.js
index 1f48e2a..6da01a1 100644
--- a/pages/k.js
+++ b/pages/k.js
@@ -1,53 +1,64 @@
-import React, { Component } from 'react';
-import Link from 'next/link';
-import Router from 'next/router';
-import fetch from 'isomorphic-unfetch';
-import Page from '../comps/Page';
-import Markdown from '../comps/Markdown';
-import AddDoc from '../comps/AddDoc';
-import getUrl from '../util/getUrl';
-import getJwt from '../util/getJwt';
+import React, { Component } from 'react'
+import Link from 'next/link'
+import Router from 'next/router'
+import fetch from 'isomorphic-unfetch'
+import Page from '../comps/Page'
+import Markdown from '../comps/Markdown'
+import AddDoc from '../comps/AddDoc'
+import getUrl from '../util/getUrl'
+import getJwt from '../util/getJwt'
class k extends Component {
delete = async () => {
- const sure = window.confirm('Are you sure you want to delete this doc? This can not be undone.');
- if(!sure) return;
+ const sure = window.confirm(
+ 'Are you sure you want to delete this doc? This can not be undone.'
+ )
+ if (!sure) return
const del = await fetch(getUrl('docs/' + this.props.id), {
headers: { Authorization: getJwt() },
- method: 'DELETE'
- }).catch(({ message }) => ({ ok: false, message }));
- if(del.ok) Router.push('/');
+ method: 'DELETE',
+ }).catch(({ message }) => ({ ok: false, message }))
+ if (del.ok) Router.push('/')
else {
- if(!del.message) {
- const data = await del.json();
- del.message = data.message;
+ if (!del.message) {
+ const data = await del.json()
+ del.message = data.message
}
- window.alert(`Could not delete doc, ${del.message}`);
+ window.alert(`Could not delete doc, ${del.message}`)
}
}
render() {
- const { found, id, doc } = this.props;
- if(!found) return (
-
- Doc not found...
-
- );
+ const { found, id, doc } = this.props
+ if (!found)
+ return (
+
+ Doc not found...
+
+ )
return (
- {doc.dir}{doc.dir.length > 0 ? '/' : ''}{doc.name}{' - '}
- 0 ? '/' : ''}
+ {doc.name}
+ {' - '}
+
- edit
+ edit
-
+ >
+ Delete
+
-
+
- );
+ )
}
}
-export default AddDoc(k);
\ No newline at end of file
+export default AddDoc(k)
diff --git a/pages/new.js b/pages/new.js
index c568dfa..3fa2af4 100644
--- a/pages/new.js
+++ b/pages/new.js
@@ -1,2 +1,2 @@
-import MngDoc from '../comps/MngDoc';
-export default MngDoc;
\ No newline at end of file
+import MngDoc from '../comps/MngDoc'
+export default MngDoc
diff --git a/pages/settings.js b/pages/settings.js
index 10346ba..df79983 100644
--- a/pages/settings.js
+++ b/pages/settings.js
@@ -1,13 +1,13 @@
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import fetch from 'isomorphic-unfetch';
-import Page from '../comps/Page';
-import PaddedRow from '../comps/PaddedRow';
-import Spinner from '../comps/Spinner';
-import updStateFromId from '../util/updStateFromId';
-import mapUser from '../util/mapUser';
-import getUrl from '../util/getUrl';
-import getJwt from '../util/getJwt';
+import React, { Component } from 'react'
+import { connect } from 'react-redux'
+import fetch from 'isomorphic-unfetch'
+import Page from '../comps/Page'
+import PaddedRow from '../comps/PaddedRow'
+import Spinner from '../comps/Spinner'
+import updStateFromId from '../util/updStateFromId'
+import mapUser from '../util/mapUser'
+import getUrl from '../util/getUrl'
+import getJwt from '../util/getJwt'
class Settings extends Component {
state = {
@@ -15,54 +15,56 @@ class Settings extends Component {
passErr: null,
curPass: '',
newPass: '',
- confPass: ''
+ confPass: '',
}
- updVal = updStateFromId.bind(this);
+ updVal = updStateFromId.bind(this)
submit = async e => {
- e.preventDefault();
- const { pending, curPass, newPass, confPass } = this.state;
- const { email, _id } = this.props.user;
- if(pending) return;
- const doErr = passErr => this.setState({ pending: false, passErr });
- const vals = {
- 'Current password': curPass,
- 'New password': newPass,
- 'Confirm new password': confPass
- };
- const keys = Object.keys(vals);
- for(let i = 0; i < keys.length; i++) {
- let key = keys[i], val = vals[key];
- if(val.length === 0) return doErr(`${key} is required`);
+ e.preventDefault()
+ const { pending, curPass, newPass, confPass } = this.state
+ const { email, _id } = this.props.user
+ if (pending) return
+ const doErr = passErr => this.setState({ pending: false, passErr })
+ const vals = {
+ 'Current password': curPass,
+ 'New password': newPass,
+ 'Confirm new password': confPass,
}
- if(newPass !== confPass) return doErr('New passwords don\'t match');
-
- this.setState({ passErr: null, pending: true });
+ const keys = Object.keys(vals)
+ for (let i = 0; i < keys.length; i++) {
+ let key = keys[i],
+ val = vals[key]
+ if (val.length === 0) return doErr(`${key} is required`)
+ }
+ if (newPass !== confPass) return doErr("New passwords don't match")
+
+ this.setState({ passErr: null, pending: true })
const updRes = await fetch(getUrl('users/' + _id), {
method: 'PATCH',
headers: { 'Content-Type': 'application/json', Authorization: getJwt() },
- body: JSON.stringify({ email, password: curPass, newPassword: newPass })
- }).catch(doErr);
- if(updRes.ok) {
- this.setState({
- curPass: '', newPass: '', confPass: '',
- passErr: 'Password updated successfully',
- pending: false
- });
+ body: JSON.stringify({ email, password: curPass, newPassword: newPass }),
+ }).catch(doErr)
+ if (updRes.ok) {
+ this.setState({
+ curPass: '',
+ newPass: '',
+ confPass: '',
+ passErr: 'Password updated successfully',
+ pending: false,
+ })
} else {
- let message = 'failed to update password';
- try {
- const data = await updRes.json();
- message = data.message || message;
- } catch (err) { doErr(err.message); }
- doErr(message);
+ let message = 'failed to update password'
+ try {
+ const data = await updRes.json()
+ message = data.message || message
+ } catch (err) {
+ doErr(err.message)
+ }
+ doErr(message)
}
}
render() {
- const {
- pending, passErr, curPass,
- newPass, confPass
- } = this.state;
-
+ const { pending, passErr, curPass, newPass, confPass } = this.state
+
return (
@@ -71,20 +73,33 @@ class Settings extends Component {
- );
+ )
}
}
-export default connect(mapUser)(Settings);
\ No newline at end of file
+export default connect(mapUser)(Settings)
diff --git a/redux/actions/userAct.js b/redux/actions/userAct.js
index 028d759..9a25b0e 100644
--- a/redux/actions/userAct.js
+++ b/redux/actions/userAct.js
@@ -1,74 +1,82 @@
-import fetch from 'isomorphic-unfetch';
-import store from '../store';
-import getUrl from '../../util/getUrl';
+import fetch from 'isomorphic-unfetch'
+import store from '../store'
+import getUrl from '../../util/getUrl'
// define action types
-export const SET_USER = 'SET_USER';
-export const LOGIN_PENDING = 'LOGIN_PENDING';
-export const LOGIN_FAILED = 'LOGIN_FAILED';
-export const LOGOUT = 'LOGOUT';
+export const SET_USER = 'SET_USER'
+export const LOGIN_PENDING = 'LOGIN_PENDING'
+export const LOGIN_FAILED = 'LOGIN_FAILED'
+export const LOGOUT = 'LOGOUT'
export const setUser = user => {
store.dispatch({
type: SET_USER,
- data: user
- });
-}; // setUser
+ data: user,
+ })
+} // setUser
export const doLogout = () => {
- if(typeof window !== 'undefined') {
- window.localStorage.removeItem('jwt');
- document.cookie = 'jwt=; expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;';
+ if (typeof window !== 'undefined') {
+ window.localStorage.removeItem('jwt')
+ document.cookie = 'jwt=; expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;'
}
- store.dispatch({ type: LOGOUT });
-}; // doLogout
+ store.dispatch({ type: LOGOUT })
+} // doLogout
-export async function doLogin (creds, jwt, noPend) {
- !noPend && store.dispatch({ type: LOGIN_PENDING });
- const authReqOpts = { method: 'POST', credentials: 'include' };
- const authReqHead = { headers: jwt ? { Authorization: jwt } : {
- 'Content-Type': 'application/json' }
- };
- const authReqBody = jwt ? null : {
- body: JSON.stringify({...creds, strategy: 'local'})
- };
- const authReq = new Request(getUrl('auth'), {
- ...authReqOpts, ...authReqHead, ...authReqBody
- });
- const authRes = await fetch(authReq).catch(err => {
- store.dispatch({ type: LOGIN_FAILED, data: err.message });
- });
- if(!authRes.ok) {
- let error;
- try {
- error = await authRes.json();
- error = error.message;
- }
- catch (err) {
- error = authRes.status === 429
- ? 'Max login attempts reached'
- : 'An error occurred during login';
- }
- return store.dispatch({
- type: LOGIN_FAILED,
- data: error
- });
+export async function doLogin(creds, jwt, noPend) {
+ !noPend && store.dispatch({ type: LOGIN_PENDING })
+ const authReqOpts = { method: 'POST', credentials: 'include' }
+ const authReqHead = {
+ headers: jwt
+ ? { Authorization: jwt }
+ : {
+ 'Content-Type': 'application/json',
+ },
}
- const { accessToken } = await authRes.json();
- const payload = accessToken.split('.')[1];
- const { userId } = JSON.parse(atob(payload));
- const userReq = new Request(getUrl(`/users/${userId}`), {
- headers: {
- Authorization: accessToken
+ const authReqBody = jwt
+ ? null
+ : {
+ body: JSON.stringify({ ...creds, strategy: 'local' }),
+ }
+ const authReq = new Request(getUrl('auth'), {
+ ...authReqOpts,
+ ...authReqHead,
+ ...authReqBody,
+ })
+ const authRes = await fetch(authReq).catch(err => {
+ store.dispatch({ type: LOGIN_FAILED, data: err.message })
+ })
+ if (!authRes.ok) {
+ let error
+ try {
+ error = await authRes.json()
+ error = error.message
+ } catch (err) {
+ error =
+ authRes.status === 429
+ ? 'Max login attempts reached'
+ : 'An error occurred during login'
}
- });
- const userRes = await fetch(userReq);
- if(!userRes.ok) {
return store.dispatch({
type: LOGIN_FAILED,
- data: 'failed to get user'
- });
+ data: error,
+ })
}
- window.localStorage.setItem('jwt', accessToken);
- setUser(await userRes.json());
-} // doLogin
\ No newline at end of file
+ const { accessToken } = await authRes.json()
+ const payload = accessToken.split('.')[1]
+ const { userId } = JSON.parse(atob(payload))
+ const userReq = new Request(getUrl(`/users/${userId}`), {
+ headers: {
+ Authorization: accessToken,
+ },
+ })
+ const userRes = await fetch(userReq)
+ if (!userRes.ok) {
+ return store.dispatch({
+ type: LOGIN_FAILED,
+ data: 'failed to get user',
+ })
+ }
+ window.localStorage.setItem('jwt', accessToken)
+ setUser(await userRes.json())
+} // doLogin
diff --git a/redux/reducers/userRed.js b/redux/reducers/userRed.js
index 8a7ea5d..34bf012 100644
--- a/redux/reducers/userRed.js
+++ b/redux/reducers/userRed.js
@@ -1,9 +1,9 @@
-import {
- SET_USER,
+import {
+ SET_USER,
LOGIN_PENDING,
LOGIN_FAILED,
- LOGOUT
-} from '../actions/userAct';
+ LOGOUT,
+} from '../actions/userAct'
const initState = {
setup: false,
@@ -11,35 +11,36 @@ const initState = {
email: null,
admin: null,
pending: false,
- error: null
-};
+ error: null,
+}
-function user(state=initState, action) {
- switch(action.type) {
- case SET_USER: {
- return {
- ...initState,
- ...action.data
- };
- }
- case LOGIN_PENDING: {
- return {
- ...initState,
- pending: true
- };
- }
- case LOGIN_FAILED: {
- return {
- ...state,
- pending: false,
- error: action.data
- };
- }
- case LOGOUT: {
- return initState;
- }
- default: return state;
+function user(state = initState, action) {
+ switch (action.type) {
+ case SET_USER: {
+ return {
+ ...initState,
+ ...action.data,
+ }
+ }
+ case LOGIN_PENDING: {
+ return {
+ ...initState,
+ pending: true,
+ }
+ }
+ case LOGIN_FAILED: {
+ return {
+ ...state,
+ pending: false,
+ error: action.data,
+ }
+ }
+ case LOGOUT: {
+ return initState
+ }
+ default:
+ return state
}
}
-export default user;
\ No newline at end of file
+export default user
diff --git a/redux/store.js b/redux/store.js
index 38478f0..961ef53 100644
--- a/redux/store.js
+++ b/redux/store.js
@@ -1,23 +1,19 @@
-import {
- applyMiddleware,
- combineReducers,
- createStore
-} from 'redux';
+import { applyMiddleware, combineReducers, createStore } from 'redux'
-import user from './reducers/userRed';
+import user from './reducers/userRed'
-let middleware;
-if(process.env.NODE_ENV !== 'production') {
- const logger = require('redux-logger').default;
- if(typeof window !== 'undefined') {
- middleware = applyMiddleware(logger);
+let middleware
+if (process.env.NODE_ENV !== 'production') {
+ const logger = require('redux-logger').default
+ if (typeof window !== 'undefined') {
+ middleware = applyMiddleware(logger)
}
}
const reducers = combineReducers({
- user
-});
+ user,
+})
-export default middleware
- ? createStore(reducers, middleware)
- : createStore(reducers);
\ No newline at end of file
+export default (middleware
+ ? createStore(reducers, middleware)
+ : createStore(reducers))
diff --git a/src/app.hooks.js b/src/app.hooks.js
index 4bda808..4372dea 100644
--- a/src/app.hooks.js
+++ b/src/app.hooks.js
@@ -1,34 +1,34 @@
// Application hooks that run for every service
-const logger = require('./hooks/logger');
+const logger = require('./hooks/logger')
module.exports = {
before: {
- all: [ logger() ],
+ all: [logger()],
find: [],
get: [],
create: [],
update: [],
patch: [],
- remove: []
+ remove: [],
},
after: {
- all: [ logger() ],
+ all: [logger()],
find: [],
get: [],
create: [],
update: [],
patch: [],
- remove: []
+ remove: [],
},
error: {
- all: [ logger() ],
+ all: [logger()],
find: [],
get: [],
create: [],
update: [],
patch: [],
- remove: []
- }
-};
+ remove: [],
+ },
+}
diff --git a/src/app.js b/src/app.js
index 4496e5a..d09b6e5 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1,131 +1,126 @@
-const favicon = require('serve-favicon');
-const fs = require('fs');
-const path = require('path');
-const compress = require('compression');
-const cors = require('cors');
-const helmet = require('helmet');
-const cookieParser = require('cookie-parser')();
-const RateLimit = require('express-rate-limit');
-const trustIPs = require('./trustIPs');
-const logger = require('winston');
+const favicon = require('serve-favicon')
+const fs = require('fs')
+const path = require('path')
+const compress = require('compression')
+const cors = require('cors')
+const helmet = require('helmet')
+const cookieParser = require('cookie-parser')()
+const RateLimit = require('express-rate-limit')
+const trustIPs = require('./trustIPs')
+const logger = require('winston')
-const feathers = require('@feathersjs/feathers');
-const express = require('@feathersjs/express');
-const configuration = require('@feathersjs/configuration');
-const hostConfig = require('../config/host.json');
+const feathers = require('@feathersjs/feathers')
+const express = require('@feathersjs/express')
+const configuration = require('@feathersjs/configuration')
+const hostConfig = require('../config/host.json')
-const middleware = require('./middleware');
-const services = require('./services');
-const appHooks = require('./app.hooks');
-const channels = require('./channels');
-const authentication = require('./authentication');
+const middleware = require('./middleware')
+const services = require('./services')
+const appHooks = require('./app.hooks')
+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 getUrl = require('../util/getUrl');
-const { parse } = require('url');
-const nxt = require('next')({ dev, quiet: true });
-const nxtHandler = nxt.getRequestHandler();
+const dev = process.env.NODE_ENV !== 'production'
+const basePath = require('../util/basePath')
+const stripBase = require('../util/stripBase')
+const getUrl = require('../util/getUrl')
+const { parse } = require('url')
+const nxt = require('next')({ dev, quiet: true })
+const nxtHandler = nxt.getRequestHandler()
-const app = express(feathers());
+const app = express(feathers())
app.run = async port => {
- const server = app.listen(port);
- await nxt.prepare();
+ const server = app.listen(port)
+ await nxt.prepare()
- if(dev) {
+ if (dev) {
server.on('upgrade', (req, socket) => {
- nxtHandler(req, socket, parse(stripBase(req.url), true));
- });
+ nxtHandler(req, socket, parse(stripBase(req.url), true))
+ })
}
- return server;
-};
+ return server
+}
// Load app configuration
-app.configure(configuration());
+app.configure(configuration())
// load host config
-Object.keys(hostConfig).forEach(key => (
- app.set(key, hostConfig[key])
-));
-app.set('didSetup', false);
+Object.keys(hostConfig).forEach(key => app.set(key, hostConfig[key]))
+app.set('didSetup', false)
try {
- fs.statSync(path.join(__dirname, '..', 'db', '.didSetup'));
- app.set('didSetup', true);
-}
-catch(err) {
+ fs.statSync(path.join(__dirname, '..', 'db', '.didSetup'))
+ app.set('didSetup', true)
+} catch (err) {
app.use((req, res, next) => {
- req.doSetup = !app.get('didSetup');
- next();
- });
-}
+ req.doSetup = !app.get('didSetup')
+ next()
+ })
+}
const authLimit = new RateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes
max: 5, // 5 attempts then block
delayAfter: 3, // slow down after 3 fails
- delayMs: 2 * 1000
-});
-app.authLimit = authLimit;
-app.use(getUrl('auth'), authLimit);
-app.patch(getUrl('users/*'), authLimit);
+ delayMs: 2 * 1000,
+})
+app.authLimit = authLimit
+app.use(getUrl('auth'), authLimit)
+app.patch(getUrl('users/*'), authLimit)
// Enable CORS, security, compression, favicon and body parsing
-trustIPs(app);
-app.use(cors());
-app.use(helmet({
- hidePoweredBy: { setTo: 'hamsters' }
-}));
+trustIPs(app)
+app.use(cors())
+app.use(
+ helmet({
+ hidePoweredBy: { setTo: 'hamsters' },
+ })
+)
-if(!dev) app.use(compress());
-app.use(express.json()); // use { limit } option to increase max post size
-app.use(express.urlencoded({ extended: true }));
-app.use(getUrl('/'), favicon('favicon.ico'));
-app.configure(express.rest()); // Set up Plugins and providers
-app.configure(middleware); // middleware/index.js
-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)
+if (!dev) app.use(compress())
+app.use(express.json()) // use { limit } option to increase max post size
+app.use(express.urlencoded({ extended: true }))
+app.use(getUrl('/'), favicon('favicon.ico'))
+app.configure(express.rest()) // Set up Plugins and providers
+app.configure(middleware) // middleware/index.js
+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)
const checkJWT = async (req, res, next) => {
- const result = await req.app.authenticate('jwt', {})(req);
- if(result.success) {
- req.jwt = req.cookies.jwt;
- delete result.data.user.password;
- req.user = result.data.user;
+ const result = await req.app.authenticate('jwt', {})(req)
+ if (result.success) {
+ req.jwt = req.cookies.jwt
+ delete result.data.user.password
+ req.user = result.data.user
}
- next();
-};
-nxt.setAssetPrefix(basePath); // setup next.js routes
+ 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)
+ nxt.render(req, res, route, query)
+ })
+})
+;['/k', '/edit'].forEach(route => {
+ app.get(getUrl(route + '/:id'), cookieParser, checkJWT, (req, res) => {
+ nxt.render(req, res, route, { id: req.params.id })
+ })
+})
-[ '/', '/logout', '/new', '/settings' ]
- .forEach(route => {
- app.get(getUrl(route), cookieParser, checkJWT, (req, res) => {
- const { query } = parse(req.url, true);
- nxt.render(req, res, route, query);
- });
- });
-
-[ '/k', '/edit' ]
- .forEach(route => {
- app.get(getUrl(route + '/:id'), cookieParser, checkJWT, (req, res) => {
- nxt.render(req, res, route, { id: req.params.id });
- });
- });
-
-const notFound = express.notFound();
+const notFound = express.notFound()
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)
- return nxt.render404(req, res);
- nxtHandler(req, res, parse(stripBase(req.url), true));
-});
+ let accept = req.get('accept')
+ if (accept && accept.toLowerCase() === 'application/json')
+ return notFound(req, res, next)
+ if (req.url.substr(0, basePath.length) !== basePath)
+ return nxt.render404(req, res)
+ nxtHandler(req, res, parse(stripBase(req.url), true))
+})
-app.use(express.errorHandler({ logger }));
-app.hooks(appHooks);
+app.use(express.errorHandler({ logger }))
+app.hooks(appHooks)
-module.exports = app;
\ No newline at end of file
+module.exports = app
diff --git a/src/authentication.js b/src/authentication.js
index c1d3dc6..f743dde 100644
--- a/src/authentication.js
+++ b/src/authentication.js
@@ -1,26 +1,28 @@
-const authentication = require('@feathersjs/authentication');
-const jwt = require('@feathersjs/authentication-jwt');
-const local = require('@feathersjs/authentication-local');
-const getUrl = require('../util/getUrl');
+const authentication = require('@feathersjs/authentication')
+const jwt = require('@feathersjs/authentication-jwt')
+const local = require('@feathersjs/authentication-local')
+const getUrl = require('../util/getUrl')
-module.exports = function (app) {
- const config = app.get('authentication');
- config.path = getUrl(config.path);
- config.service = getUrl('users');
+module.exports = function(app) {
+ const config = app.get('authentication')
+ config.path = getUrl(config.path)
+ config.service = getUrl('users')
// Set up authentication with the secret
- app.configure(authentication(
- Object.assign({}, config, {
- cookie: {
- enabled: true,
- httpOnly: false,
- secure: false,
- name: 'jwt',
- }
- })
- ));
- app.configure(jwt());
- app.configure(local());
+ app.configure(
+ authentication(
+ Object.assign({}, config, {
+ cookie: {
+ enabled: true,
+ httpOnly: false,
+ secure: false,
+ name: 'jwt',
+ },
+ })
+ )
+ )
+ app.configure(jwt())
+ app.configure(local())
// The `authentication` service is used to create a JWT.
// The before `create` hook registers strategies that can be used
@@ -30,13 +32,11 @@ module.exports = function (app) {
create: [
authentication.hooks.authenticate(config.strategies),
ctx => {
- ctx.app.authLimit.resetKey(ctx.params.ip);
- return ctx;
- }
+ ctx.app.authLimit.resetKey(ctx.params.ip)
+ return ctx
+ },
],
- remove: [
- authentication.hooks.authenticate('jwt')
- ]
- }
- });
-};
+ remove: [authentication.hooks.authenticate('jwt')],
+ },
+ })
+}
diff --git a/src/channels.js b/src/channels.js
index 4f2851d..2c6b3a6 100644
--- a/src/channels.js
+++ b/src/channels.js
@@ -1,56 +1,59 @@
module.exports = function(app) {
- if(typeof app.channel !== 'function') {
+ if (typeof app.channel !== 'function') {
// If no real-time functionality has been configured just return
- return;
+ return
}
app.on('connection', connection => {
// On a new real-time connection, add it to the anonymous channel
- app.channel('anonymous').join(connection);
- });
+ app.channel('anonymous').join(connection)
+ })
app.on('login', (authResult, { connection }) => {
// connection can be undefined if there is no
// real-time connection, e.g. when logging in via REST
- if(connection) {
+ if (connection) {
// Obtain the logged in user from the connection
// const user = connection.user;
-
+
// The connection is no longer anonymous, remove it
- app.channel('anonymous').leave(connection);
+ app.channel('anonymous').leave(connection)
// Add it to the authenticated user channel
- app.channel('authenticated').join(connection);
+ app.channel('authenticated').join(connection)
+
+ // Channels can be named anything and joined on any condition
- // Channels can be named anything and joined on any condition
-
// E.g. to send real-time events only to admins use
// if(user.isAdmin) { app.channel('admins').join(connection); }
// If the user has joined e.g. chat rooms
// if(Array.isArray(user.rooms)) user.rooms.forEach(room => app.channel(`rooms/${room.id}`).join(channel));
-
+
// Easily organize users by email and userid for things like messaging
// app.channel(`emails/${user.email}`).join(channel);
// app.channel(`userIds/$(user.id}`).join(channel);
}
- });
+ })
// eslint-disable-next-line no-unused-vars
app.publish((data, hook) => {
// Here you can add event publishers to channels set up in `channels.js`
// To publish only for a specific event use `app.publish(eventname, () => {})`
- console.log('Publishing all events to all authenticated users. See `channels.js` and https://docs.feathersjs.com/api/channels.html for more information.'); // eslint-disable-line
+ // eslint-disable-next-line
+ console.log(
+ 'Publishing all events to all authenticated users. See `channels.js` and https://docs.feathersjs.com/api/channels.html for more information.'
+ )
// e.g. to publish all service events to all authenticated users use
- return app.channel('authenticated');
- });
+ return app.channel('authenticated')
+ })
// Here you can also add service specific event publishers
// e..g the publish the `users` service `created` event to the `admins` channel
// app.service('users').publish('created', () => app.channel('admins'));
-
+
// With the userid and email organization from above you can easily select involved users
// app.service('messages').publish(() => {
// return [
@@ -58,4 +61,4 @@ module.exports = function(app) {
// app.channel(`emails/${data.recipientEmail}`)
// ];
// });
-};
+}
diff --git a/src/hooks/logger.js b/src/hooks/logger.js
index 5310827..943080f 100644
--- a/src/hooks/logger.js
+++ b/src/hooks/logger.js
@@ -1,23 +1,25 @@
// A hook that logs service method before, after and error
// See https://github.com/winstonjs/winston for documentation
// about the logger.
-const logger = require('winston');
+const logger = require('winston')
// To see more detailed messages, uncomment the following line
// logger.level = 'debug';
-module.exports = function () {
+module.exports = function() {
return context => {
// This debugs the service call and a stringified version of the hook context
// You can customize the mssage (and logger) to your needs
- logger.debug(`${context.type} app.service('${context.path}').${context.method}()`);
-
- if(typeof context.toJSON === 'function') {
- logger.debug('Hook Context', JSON.stringify(context, null, ' '));
+ logger.debug(
+ `${context.type} app.service('${context.path}').${context.method}()`
+ )
+
+ if (typeof context.toJSON === 'function') {
+ logger.debug('Hook Context', JSON.stringify(context, null, ' '))
}
-
+
if (context.error) {
- logger.error(context.error);
+ logger.error(context.error)
}
- };
-};
+ }
+}
diff --git a/src/index.js b/src/index.js
index 955b0ce..8356177 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
-const logger = require('winston');
-const app = require('./app');
-const port = app.get('port');
+const logger = require('winston')
+const app = require('./app')
+const port = app.get('port')
app.run(port).then(() => {
logger.info('MYKB listening at http://%s:%d', app.get('host'), port)
@@ -8,4 +8,4 @@ app.run(port).then(() => {
process.on('unhandledRejection', (reason, p) =>
logger.error('Unhandled Rejection at: Promise ', p, reason)
-);
\ No newline at end of file
+)
diff --git a/src/middleware/index.js b/src/middleware/index.js
index 8cd9d69..deecc0f 100644
--- a/src/middleware/index.js
+++ b/src/middleware/index.js
@@ -1,11 +1,11 @@
// eslint-disable-next-line no-unused-vars
-module.exports = function (app) {
+module.exports = function(app) {
// Add your custom middleware here. Remember, that
// in Express the order matters
-
+
// add req.ip to feathers
app.use((req, res, next) => {
- req.feathers.ip = req.ip;
- next();
- });
-};
+ req.feathers.ip = req.ip
+ next()
+ })
+}
diff --git a/src/models/users.model.js b/src/models/users.model.js
index ef70063..c3dc8bb 100644
--- a/src/models/users.model.js
+++ b/src/models/users.model.js
@@ -1,14 +1,14 @@
-const NeDB = require('nedb');
-const path = require('path');
+const NeDB = require('nedb')
+const path = require('path')
-module.exports = function (app) {
- const dbPath = app.get('nedb');
+module.exports = function(app) {
+ const dbPath = app.get('nedb')
const Model = new NeDB({
filename: path.join(dbPath, 'users.db'),
- autoload: true
- });
+ autoload: true,
+ })
- Model.ensureIndex({ fieldName: 'email', unique: true });
-
- return Model;
-};
+ Model.ensureIndex({ fieldName: 'email', unique: true })
+
+ return Model
+}
diff --git a/src/services/docs/docs.class.js b/src/services/docs/docs.class.js
index 427095f..245d56a 100644
--- a/src/services/docs/docs.class.js
+++ b/src/services/docs/docs.class.js
@@ -1,225 +1,233 @@
-const errors = require('@feathersjs/errors');
-const gitP = require('simple-git/promise');
-const fs = require('fs-extra');
-const path = require('path');
-const loadDocs = require('./loadDocs');
-const comparableFields = [ 'name', 'dir' ];
-let git;
+const errors = require('@feathersjs/errors')
+const gitP = require('simple-git/promise')
+const fs = require('fs-extra')
+const path = require('path')
+const loadDocs = require('./loadDocs')
+const comparableFields = ['name', 'dir']
+let git
class Service {
- constructor (options) {
- this.options = options || {};
- this.docsDir = this.options.docsDir;
- this.$limit = this.options.paginate.default;
- this.useGit = this.options.useGit;
- this.maxDocSize = 1024 * 100; // 100 kb (don't try sending if bigger)
- this.docs = {};
- this.updTimeouts = {};
- loadDocs.bind(this)();
+ constructor(options) {
+ this.options = options || {}
+ this.docsDir = this.options.docsDir
+ this.$limit = this.options.paginate.default
+ this.useGit = this.options.useGit
+ this.maxDocSize = 1024 * 100 // 100 kb (don't try reading if bigger)
+ this.docs = {}
+ this.updTimeouts = {}
+ loadDocs.bind(this)()
- if(this.useGit) {
- git = gitP(this.docsDir);
+ if (this.useGit) {
+ git = gitP(this.docsDir)
fs.stat(path.join(this.docsDir, '.git'), async err => {
- if(err && err.code === 'ENOENT') {
+ if (err && err.code === 'ENOENT') {
git.init().then(() => {
- if(this.numInitDocs === 0) return;
- git.add('./*').then(() => git.commit('initial commit'));
- });
+ if (this.numInitDocs === 0) return
+ git.add('./*').then(() => git.commit('initial commit'))
+ })
}
- });
+ })
}
}
- async getMd (id) {
- const doc = this.docs[id];
- if(doc.md) return doc.md;
- const docPath = path.join(this.docsDir, doc.dir, doc.name);
- const { size } = await fs.stat(docPath);
- if(size > this.maxDocSize) return 'Document is too big to display...';
- const buff = await fs.readFile(docPath);
- return buff.toString();
+ async getMd(id) {
+ const doc = this.docs[id]
+ if (doc.md) return doc.md
+ const docPath = path.join(this.docsDir, doc.dir, doc.name)
+ const { size } = await fs.stat(docPath)
+ if (size > this.maxDocSize) return 'Document is too big to display...'
+ const buff = await fs.readFile(docPath)
+ return buff.toString()
}
- async isMatch (id, $search) {
- const doc = this.docs[id];
- const name = doc.name.toLowerCase();
+ async isMatch(id, $search) {
+ const doc = this.docs[id]
+ const name = doc.name.toLowerCase()
- if(name.indexOf($search) > -1) return true;
- const dir = doc.dir.toLowerCase();
-
- if(dir.indexOf($search) > -1) return true;
- const relPath = dir + (dir.length > 0 ? '/' : '') + name;
-
- if(relPath.toLowerCase().indexOf($search) > -1) return true;
- let md = await this.getMd(id);
- md = md.toLowerCase();
+ if (name.indexOf($search) > -1) return true
+ const dir = doc.dir.toLowerCase()
- if(md.indexOf($search) > -1) return true;
- return false;
+ if (dir.indexOf($search) > -1) return true
+ const relPath = dir + (dir.length > 0 ? '/' : '') + name
+
+ if (relPath.toLowerCase().indexOf($search) > -1) return true
+ let md = await this.getMd(id)
+ md = md.toLowerCase()
+
+ if (md.indexOf($search) > -1) return true
+ return false
}
- async checkRmDir (dir) {
- if(dir === '') return;
- const parts = dir.split('/');
- const n = parts.length;
- for(let i = 0; i < n; i++) {
- const dir = parts.filter((p, pIdx) => pIdx < (n - i)).join('/');
- const docsInDir = await this.find({ query: { dir } });
- if(docsInDir.total === 0) {
+ async checkRmDir(dir) {
+ if (dir === '') return
+ const parts = dir.split('/')
+ const n = parts.length
+ for (let i = 0; i < n; i++) {
+ const dir = parts.filter((p, pIdx) => pIdx < n - i).join('/')
+ const docsInDir = await this.find({ query: { dir } })
+ if (docsInDir.total === 0) {
try {
- await fs.rmdir(path.join(this.docsDir, dir));
- } catch(err) { return; }
- } else return;
+ await fs.rmdir(path.join(this.docsDir, dir))
+ } catch (err) {
+ return
+ }
+ } else return
}
}
- async find (params) {
- const { query } = params;
- let { $limit, $skip, $search, $select, $sort } = query;
- if($skip < 0) $skip = 0;
- $limit = $limit || this.$limit;
- if($search) {
- $search = $search.toLowerCase().trim();
+ async find(params) {
+ const { query } = params
+ let { $limit, $skip, $search, $select, $sort } = query
+ if ($skip < 0) $skip = 0
+ $limit = $limit || this.$limit
+ if ($search) {
+ $search = $search.toLowerCase().trim()
}
- let ids = Object.keys(this.docs);
- const data = [];
- const toComp = comparableFields.filter(f => typeof query[f] !== 'undefined');
- if(toComp.length > 0) {
+ let ids = Object.keys(this.docs)
+ const data = []
+ const toComp = comparableFields.filter(f => typeof query[f] !== 'undefined')
+ if (toComp.length > 0) {
ids = ids.filter(id => {
- const doc = this.docs[id];
- return !toComp.some(f => doc[f] !== query[f]);
- });
+ const doc = this.docs[id]
+ return !toComp.some(f => doc[f] !== query[f])
+ })
}
- if($search) {
+ if ($search) {
ids = await Promise.all(
- ids.map(async id => await this.isMatch(id, $search) ? id : null)
- );
- ids = ids.filter(Boolean);
+ ids.map(async id => ((await this.isMatch(id, $search)) ? id : null))
+ )
+ ids = ids.filter(Boolean)
}
- if(ids.length === 0) return { total: 0, data };
- if($sort) {
- const sortKey = Object.keys($sort).pop();
- const ascDesc = $sort[sortKey];
- if(this.docs[ids[0]][sortKey] || sortKey === 'dirName') { // make sure valid key
+ if (ids.length === 0) return { total: 0, data }
+ if ($sort) {
+ const sortKey = Object.keys($sort).pop()
+ const ascDesc = $sort[sortKey]
+
+ if (this.docs[ids[0]][sortKey] || sortKey === 'dirName') {
ids.sort((a, b) => {
- let val1, val2, parseVals;
- const docA = this.docs[a],
- docB = this.docs[b];
- if(sortKey === 'dirName') {
- parseVals = doc => path.join(doc.dir, doc.name);
+ a = this.docs[a]
+ b = this.docs[b]
+ let parseVal
+ if (sortKey === 'dirName') {
+ parseVal = doc => path.join(doc.dir, doc.name)
+ } else {
+ parseVal = doc => doc[sortKey]
}
- else {
- parseVals = doc => doc[sortKey];
- }
- [val1, val2] = [docA, docB].map(parseVals);
- let c = 0;
- if(val1 < val2) c = -1;
- else if(val1 > val2) c = 1;
- return c * ascDesc;
- });
+ a = parseVal(a)
+ b = parseVal(b)
+ let c = 0
+ if (a < b) c = -1
+ else if (a > b) c = 1
+ return c * ascDesc
+ })
}
}
- for(let i = $skip || 0; i < ids.length && data.length < $limit; i++) {
- const id = ids[i];
- let doc = $select && !$select.md ? this.docs[id] : this.get(id);
- if($select) {
- let _doc = {};
- $select.forEach(k => _doc[k] = doc[k]);
- doc = _doc;
+ for (let i = $skip || 0; i < ids.length && data.length < $limit; i++) {
+ const id = ids[i]
+ let doc = $select && !$select.md ? this.docs[id] : this.get(id)
+ if ($select) {
+ let _doc = {}
+ $select.forEach(k => (_doc[k] = doc[k]))
+ doc = _doc
}
- data.push(doc);
+ data.push(doc)
}
- return { total: ids.length, data };
+ return { total: ids.length, data }
}
- async get (id, params) { // eslint-disable-line no-unused-vars
- const doc = this.docs[id];
- if(!doc) throw new errors.NotFound(`No record found for id '${id}'`);
- if(!doc.md) doc.md = await this.getMd(id);
- return this.docs[id];
+ // eslint-disable-next-line no-unused-vars
+ async get(id, params) {
+ const doc = this.docs[id]
+ if (!doc) throw new errors.NotFound(`No record found for id '${id}'`)
+ if (!doc.md) doc.md = await this.getMd(id)
+ return this.docs[id]
}
- async create (data, params) { // eslint-disable-line no-unused-vars
- if(Array.isArray(data)) {
- return await Promise.all(data.map(current => this.create(current)));
+ // eslint-disable-next-line no-unused-vars
+ async create(data, params) {
+ if (Array.isArray(data)) {
+ return await Promise.all(data.map(current => this.create(current)))
}
- const { name, dir, md } = data;
+ const { name, dir, md } = data
try {
- const rPath = path.join(dir, name);
- const docPath = path.join(this.docsDir, rPath);
- await fs.outputFile(docPath, md);
-
- if(this.useGit) {
- git.add(rPath).then(() => git.commit(`added doc ${rPath}`));
+ const rPath = path.join(dir, name)
+ const docPath = path.join(this.docsDir, rPath)
+ await fs.outputFile(docPath, md)
+
+ if (this.useGit) {
+ git.add(rPath).then(() => git.commit(`added doc ${rPath}`))
}
- const ts = new Date().toJSON();
- return this.setDoc(path.join(dir, name), ts, md, ts);
- }
- catch (err) {
- throw new errors.GeneralError('could not create doc');
+ const ts = new Date().toJSON()
+ return this.setDoc(path.join(dir, name), ts, md, ts)
+ } catch (err) {
+ throw new errors.GeneralError('could not create doc')
}
}
- async update (id, data, params) { // eslint-disable-line no-unused-vars
- throw new errors.MethodNotAllowed('can not update on docs service');
+ // eslint-disable-next-line no-unused-vars
+ async update(id, data, params) {
+ throw new errors.MethodNotAllowed('can not update on docs service')
}
- async patch (id, data, params) { // eslint-disable-line no-unused-vars
- const doc = this.docs[id];
- if(!doc) throw new errors.NotFound(`No record found for id '${id}'`);
- let { name, dir, md } = data;
- let diffDir = Boolean(doc.dir !== dir);
- if(!name) name = doc.name;
- if(typeof dir !== 'string') {
- dir = doc.dir;
- diffDir = false;
+ // eslint-disable-next-line no-unused-vars
+ async patch(id, data, params) {
+ const doc = this.docs[id]
+ if (!doc) throw new errors.NotFound(`No record found for id '${id}'`)
+ let { name, dir, md } = data
+ let diffDir = Boolean(doc.dir !== dir)
+ if (!name) name = doc.name
+ if (typeof dir !== 'string') {
+ dir = doc.dir
+ diffDir = false
}
- const rPath = path.join(dir, name);
- const docPath = path.join(this.docsDir, rPath);
- if(name !== doc.name || diffDir) {
- const oldRPath = path.join(doc.dir, doc.name);
- const oldPath = path.join(this.docsDir, oldRPath);
- await fs.ensureDir(path.join(this.docsDir, dir));
- await fs.move(oldPath, docPath);
-
- if(this.useGit) {
- git.rm(oldRPath)
+ const rPath = path.join(dir, name)
+ const docPath = path.join(this.docsDir, rPath)
+ if (name !== doc.name || diffDir) {
+ const oldRPath = path.join(doc.dir, doc.name)
+ const oldPath = path.join(this.docsDir, oldRPath)
+ await fs.ensureDir(path.join(this.docsDir, dir))
+ await fs.move(oldPath, docPath)
+
+ if (this.useGit) {
+ git
+ .rm(oldRPath)
.then(() => git.add(rPath))
- .then(() => git.commit(`renamed doc ${oldRPath} ${rPath}`));
+ .then(() => git.commit(`renamed doc ${oldRPath} ${rPath}`))
}
- id = this.getId(path.join(dir, name));
- this.docs[id] = Object.assign({}, doc, { id, name, dir });
- delete this.docs[doc.id];
- if(diffDir) this.checkRmDir(doc.dir);
+ id = this.getId(path.join(dir, name))
+ this.docs[id] = Object.assign({}, doc, { id, name, dir })
+ delete this.docs[doc.id]
+ if (diffDir) this.checkRmDir(doc.dir)
}
- if(md) {
- await fs.writeFile(docPath, md);
- if(this.useGit) {
- git.add(rPath).then(() => git.commit(`updated doc ${rPath}`));
+ if (md) {
+ await fs.writeFile(docPath, md)
+ if (this.useGit) {
+ git.add(rPath).then(() => git.commit(`updated doc ${rPath}`))
}
- this.docs[id].md = md;
+ this.docs[id].md = md
}
- return this.docs[id];
+ return this.docs[id]
}
- async remove (id, params) { // eslint-disable-line no-unused-vars
- const doc = this.docs[id];
- if(!id) throw new errors.NotFound(`No record found for id '${id}'`);
- const rPath = path.join(doc.dir, doc.name);
- const docPath = path.join(this.docsDir, rPath);
- await fs.unlink(docPath);
-
- if(this.useGit) {
- git.rm(rPath).then(() => git.commit(`removed doc ${rPath}`));
+ // eslint-disable-next-line no-unused-vars
+ async remove(id, params) {
+ const doc = this.docs[id]
+ if (!id) throw new errors.NotFound(`No record found for id '${id}'`)
+ const rPath = path.join(doc.dir, doc.name)
+ const docPath = path.join(this.docsDir, rPath)
+ await fs.unlink(docPath)
+
+ if (this.useGit) {
+ git.rm(rPath).then(() => git.commit(`removed doc ${rPath}`))
}
- delete this.docs[id];
- this.checkRmDir(doc.dir);
- return doc;
+ delete this.docs[id]
+ this.checkRmDir(doc.dir)
+ return doc
}
}
-module.exports = function (options) {
- return new Service(options);
-};
+module.exports = function(options) {
+ return new Service(options)
+}
-module.exports.Service = Service;
\ No newline at end of file
+module.exports.Service = Service
diff --git a/src/services/docs/docs.hooks.js b/src/services/docs/docs.hooks.js
index de76c28..7d0d383 100644
--- a/src/services/docs/docs.hooks.js
+++ b/src/services/docs/docs.hooks.js
@@ -1,72 +1,81 @@
-const { authenticate } = require('@feathersjs/authentication').hooks;
-const { checkDir, checkName } = require('../../../util/checkDirParts');
-const { disable, invalid, adminOnly } = require('../hooksUtil');
-const getUrl = require('../../../util/getUrl');
+const { authenticate } = require('@feathersjs/authentication').hooks
+const { checkDir, checkName } = require('../../../util/checkDirParts')
+const { disable, invalid, adminOnly } = require('../hooksUtil')
+const getUrl = require('../../../util/getUrl')
const nameIsValid = name => {
- name = checkName(name);
- if(!name) return invalid('name');
- if(name.substr(name.length - 3).toLowerCase() !== '.md') {
- name += '.md';
+ name = checkName(name)
+ if (!name) return invalid('name')
+ if (name.substr(name.length - 3).toLowerCase() !== '.md') {
+ name += '.md'
}
- return name;
-};
+ return name
+}
const dirIsValid = dir => {
- dir = checkDir(dir);
- if(!dir && dir !== 0) return invalid('dir');
- else if(dir === 0) return '';
- return dir;
-};
+ dir = checkDir(dir)
+ if (!dir && dir !== 0) return invalid('dir')
+ else if (dir === 0) return ''
+ return dir
+}
const mdIsValid = md => {
- if(typeof md !== 'string' || md.trim().length === 0) {
- return invalid('md');
+ if (typeof md !== 'string' || md.trim().length === 0) {
+ return invalid('md')
}
- return md;
-};
+ return md
+}
const pathTaken = async (name, dir, app) => {
- const matches = await app.service(getUrl('docs')).find({ query: { name, dir } });
- if(matches.total > 0) {
- return invalid(null, 'filename is taken');
+ const matches = await app
+ .service(getUrl('docs'))
+ .find({ query: { name, dir } })
+ if (matches.total > 0) {
+ return invalid(null, 'filename is taken')
}
-};
+}
module.exports = {
before: {
- all: [ authenticate('jwt') ],
+ all: [authenticate('jwt')],
find: [],
get: [],
- create: [ async ctx => {
- const { app, data } = ctx;
- let { name, dir, md } = data;
- const k = {};
- k.name = nameIsValid(name);
- k.dir = dirIsValid(dir);
- k.md = mdIsValid(md);
- await pathTaken(k.name, k.dir, app);
- ctx.data = k;
- return ctx;
- }],
- update: [ disable ],
- patch: [ async ctx => {
- const { data, app } = ctx;
- const { name, dir, md } = data;
- const k = {};
- if(name) k.name = nameIsValid(name);
- if(typeof dir === 'string') k.dir = dirIsValid(dir); // allow empty string
- if(name || typeof dir === 'string') {
- let checkName, checkDir;
- if(!name || typeof dir !== 'string') {
- const doc = await app.service(getUrl('docs')).get(ctx.id);
- if(!name) checkName = doc.name;
- if(typeof dir !== 'string') checkDir = doc.dir;
+ create: [
+ async ctx => {
+ const { app, data } = ctx
+ let { name, dir, md } = data
+ const k = {}
+ k.name = nameIsValid(name)
+ k.dir = dirIsValid(dir)
+ k.md = mdIsValid(md)
+ await pathTaken(k.name, k.dir, app)
+ ctx.data = k
+ return ctx
+ },
+ ],
+ update: [disable],
+ patch: [
+ async ctx => {
+ const { data, app } = ctx
+ const { name, dir, md } = data
+ const k = {}
+ if (name) k.name = nameIsValid(name)
+ if (typeof dir === 'string') k.dir = dirIsValid(dir) // allow empty string
+ if (name || typeof dir === 'string') {
+ let checkName, checkDir
+ if (!name || typeof dir !== 'string') {
+ const doc = await app.service(getUrl('docs')).get(ctx.id)
+ if (!name) checkName = doc.name
+ if (typeof dir !== 'string') checkDir = doc.dir
+ }
+ await pathTaken(
+ k.name || checkName,
+ typeof k.dir === 'string' ? k.dir : checkDir,
+ app
+ )
}
- await pathTaken(k.name || checkName,
- typeof k.dir === 'string' ? k.dir : checkDir, app);
- }
- if(md) k.md = mdIsValid(md);
- if(Object.keys(k).length === 0) invalid(null, 'nothing to update');
- ctx.data = k;
- return ctx;
- }],
- remove: [ adminOnly ]
+ if (md) k.md = mdIsValid(md)
+ if (Object.keys(k).length === 0) invalid(null, 'nothing to update')
+ ctx.data = k
+ return ctx
+ },
+ ],
+ remove: [adminOnly],
},
after: {
@@ -76,7 +85,7 @@ module.exports = {
create: [],
update: [],
patch: [],
- remove: []
+ remove: [],
},
error: {
@@ -86,6 +95,6 @@ module.exports = {
create: [],
update: [],
patch: [],
- remove: []
- }
-};
+ remove: [],
+ },
+}
diff --git a/src/services/docs/docs.service.js b/src/services/docs/docs.service.js
index a88eccb..9f21782 100644
--- a/src/services/docs/docs.service.js
+++ b/src/services/docs/docs.service.js
@@ -1,29 +1,28 @@
// Initializes the `docs` service on path `/docs`
-const createService = require('./docs.class.js');
-const hooks = require('./docs.hooks');
-const getUrl = require('../../../util/getUrl');
+const createService = require('./docs.class.js')
+const hooks = require('./docs.hooks')
+const getUrl = require('../../../util/getUrl')
-module.exports = function (app) {
-
- const paginate = app.get('paginate');
- const docsDir = app.get('docsDir');
- const cacheSize = app.get('cacheSize');
- const useGit = app.get('useGit');
+module.exports = function(app) {
+ const paginate = app.get('paginate')
+ const docsDir = app.get('docsDir')
+ const cacheSize = app.get('cacheSize')
+ const useGit = app.get('useGit')
const options = {
name: 'docs',
paginate,
docsDir,
cacheSize,
- useGit
- };
- const url = getUrl('docs');
+ useGit,
+ }
+ const url = getUrl('docs')
// Initialize our service with any options it requires
- app.use(url, createService(options));
+ app.use(url, createService(options))
// Get our initialized service so that we can register hooks and filters
- const service = app.service(url);
+ const service = app.service(url)
- service.hooks(hooks);
-};
\ No newline at end of file
+ service.hooks(hooks)
+}
diff --git a/src/services/docs/loadDocs.js b/src/services/docs/loadDocs.js
index 019cbd6..c6a2491 100644
--- a/src/services/docs/loadDocs.js
+++ b/src/services/docs/loadDocs.js
@@ -1,64 +1,78 @@
-const chokidar = require('chokidar');
-const fs = require('fs-extra');
-const path = require('path');
-const glob = require('glob');
-const crypto = require('crypto');
+const chokidar = require('chokidar')
+const fs = require('fs-extra')
+const path = require('path')
+const glob = require('glob')
+const crypto = require('crypto')
async function loadDocs() {
- const { docsDir, cacheSize } = this.options;
- this.numInitDocs = glob.sync(path.join(docsDir, '**/*.md')).length;
- this.cached = 0;
- this.loaded = false;
+ const { docsDir, cacheSize } = this.options
+ this.numInitDocs = glob.sync(path.join(docsDir, '**/*.md')).length
+ this.cached = 0
+ this.loaded = false
+
+ const getId = relPath =>
+ crypto
+ .createHash('sha1')
+ .update(relPath)
+ .digest()
+ .toString('base64')
+ .substr(0, 16)
+ .split('/')
+ .join('_')
+ this.getId = getId
- const getId = relPath => (crypto.createHash('sha1')
- .update(relPath).digest().toString('base64')
- .substr(0, 16).split('/').join('_')
- );
- this.getId = getId;
-
const setDoc = (relPath, created, md, updated) => {
- const id = getId(relPath);
- let dir = relPath.split('/');
- const name = dir.pop();
- dir = dir.join('/');
+ const id = getId(relPath)
+ let dir = relPath.split('/')
+ const name = dir.pop()
+ dir = dir.join('/')
const doc = {
- id, name, dir, created, md, updated
- };
- this.docs[id] = doc;
- return doc;
- };
- this.setDoc = setDoc;
+ id,
+ name,
+ dir,
+ created,
+ md,
+ updated,
+ }
+ this.docs[id] = doc
+ return doc
+ }
+ this.setDoc = setDoc
- const watcher = chokidar.watch(path.join(docsDir, '/**/*.md'), { persistent: true });
+ const watcher = chokidar.watch(path.join(docsDir, '/**/*.md'), {
+ persistent: true,
+ })
const relPath = path => {
- path = path.split(docsDir).pop();
- if(path.substr(0, 1) === '/') path = path.substr(1);
- return path;
- };
+ path = path.split(docsDir).pop()
+ if (path.substr(0, 1) === '/') path = path.substr(1)
+ return path
+ }
const handleDoc = async (path, stats) => {
- const rPath = relPath(path);
- if(!stats) stats = await fs.stat(path);
- else { // stats was set so it's a change event
- const changedDoc = this.docs[getId(rPath)];
- if(changedDoc && changedDoc.md) this.cached -= changedDoc.md.length;
+ const rPath = relPath(path)
+ if (!stats) stats = await fs.stat(path)
+ else {
+ // stats was set so it's a change event
+ const changedDoc = this.docs[getId(rPath)]
+ if (changedDoc && changedDoc.md) this.cached -= changedDoc.md.length
}
- const { birthtime, size, mtime } = stats;
- let md = null;
- if(size < this.maxDocSize && (this.cached + size) < cacheSize) {
- md = await fs.readFile(path);
- md = md.toString();
- this.cached += md.length;
+ const { birthtime, size, mtime } = stats
+ let md = null
+ if (size < this.maxDocSize && this.cached + size < cacheSize) {
+ md = await fs.readFile(path)
+ md = md.toString()
+ this.cached += md.length
}
- setDoc(rPath, birthtime, md, mtime);
- };
- watcher.on('add', handleDoc); // file added
- watcher.on('change', handleDoc); // file changed (rename triggers unlink then add)
- watcher.on('unlink', path => { // file removed
- const id = getId(relPath(path));
- if(this.docs[id] && this.docs[id].md) {
- this.cached -= this.docs[id].md.length;
+ setDoc(rPath, birthtime, md, mtime)
+ }
+ watcher.on('add', handleDoc) // file added
+ watcher.on('change', handleDoc) // file changed (rename triggers unlink then add)
+ watcher.on('unlink', path => {
+ // file removed
+ const id = getId(relPath(path))
+ if (this.docs[id] && this.docs[id].md) {
+ this.cached -= this.docs[id].md.length
}
- delete this.docs[id];
- });
+ delete this.docs[id]
+ })
}
-module.exports = loadDocs;
\ No newline at end of file
+module.exports = loadDocs
diff --git a/src/services/hooksUtil.js b/src/services/hooksUtil.js
index 5046700..b839910 100644
--- a/src/services/hooksUtil.js
+++ b/src/services/hooksUtil.js
@@ -1,23 +1,23 @@
-const { BadRequest, Forbidden } = require('@feathersjs/errors');
+const { BadRequest, Forbidden } = require('@feathersjs/errors')
const isAdmin = ctx => {
- const { params } = ctx;
- return Boolean(params.user && params.user.admin);
-};
+ const { params } = ctx
+ return Boolean(params.user && params.user.admin)
+}
module.exports = {
disable: () => {
- throw new BadRequest('method not allowed');
+ throw new BadRequest('method not allowed')
},
invalid: (field, msg) => {
- throw new BadRequest(msg || `invalid ${field} value`);
+ throw new BadRequest(msg || `invalid ${field} value`)
},
isAdmin: isAdmin,
adminOnly: ctx => {
- if(!isAdmin(ctx)) throw new Forbidden('invalid permission');
- return ctx;
- }
-};
\ No newline at end of file
+ if (!isAdmin(ctx)) throw new Forbidden('invalid permission')
+ return ctx
+ },
+}
diff --git a/src/services/index.js b/src/services/index.js
index b2554cf..1fc9d57 100644
--- a/src/services/index.js
+++ b/src/services/index.js
@@ -1,6 +1,6 @@
-const users = require('./users/users.service.js');
-const docs = require('./docs/docs.service.js');
-module.exports = function (app) {
- app.configure(users);
- app.configure(docs);
-};
+const users = require('./users/users.service.js')
+const docs = require('./docs/docs.service.js')
+module.exports = function(app) {
+ app.configure(users)
+ app.configure(docs)
+}
diff --git a/src/services/users/users.hooks.js b/src/services/users/users.hooks.js
index d365c4a..ba69ac8 100644
--- a/src/services/users/users.hooks.js
+++ b/src/services/users/users.hooks.js
@@ -1,71 +1,76 @@
-const { authenticate } = require('@feathersjs/authentication').hooks;
-const { Forbidden } = require('@feathersjs/errors');
-const fs = require('fs');
-const path = require('path');
-const { disable, invalid, isAdmin, adminOnly } = require('../hooksUtil');
-const {
- hashPassword, protect
-} = require('@feathersjs/authentication-local').hooks;
+const { authenticate } = require('@feathersjs/authentication').hooks
+const { Forbidden } = require('@feathersjs/errors')
+const fs = require('fs')
+const path = require('path')
+const { disable, invalid, isAdmin, adminOnly } = require('../hooksUtil')
+const {
+ hashPassword,
+ protect,
+} = require('@feathersjs/authentication-local').hooks
-const invalidStr = str => Boolean(
- typeof str !== 'string' || str.trim().length === 0);
+const invalidStr = str =>
+ Boolean(typeof str !== 'string' || str.trim().length === 0)
module.exports = {
before: {
all: [],
- find: [ authenticate('jwt') ],
- get: [ authenticate('jwt') ],
- create: [
+ find: [authenticate('jwt')],
+ get: [authenticate('jwt')],
+ create: [
async ctx => {
- const { data, app } = ctx;
- if(app.get('didSetup') && !isAdmin(ctx)) {
- throw new Forbidden('invalid permission');
+ const { data, app } = ctx
+ if (app.get('didSetup') && !isAdmin(ctx)) {
+ throw new Forbidden('invalid permission')
}
- const { email, password, admin } = data;
- if(invalidStr(email)) invalid('email');
- if(invalidStr(password)) invalid('password');
- if(typeof admin !== 'boolean') invalid('admin');
-
- ctx.data = { email, password, admin };
- return ctx;
+ const { email, password, admin } = data
+ if (invalidStr(email)) invalid('email')
+ if (invalidStr(password)) invalid('password')
+ if (typeof admin !== 'boolean') invalid('admin')
+
+ ctx.data = { email, password, admin }
+ return ctx
},
- hashPassword()
+ hashPassword(),
],
- update: [ disable ],
- patch: [ authenticate('local'),
+ update: [disable],
+ patch: [
+ authenticate('local'),
async ctx => {
- const { newPassword } = ctx.data;
- if(invalidStr(newPassword)) invalid('newPassword');
- ctx.data = { password: newPassword };
- await hashPassword()(ctx);
- ctx.app.authLimit.resetKey(ctx.params.ip);
- return ctx;
- }
+ const { newPassword } = ctx.data
+ if (invalidStr(newPassword)) invalid('newPassword')
+ ctx.data = { password: newPassword }
+ await hashPassword()(ctx)
+ ctx.app.authLimit.resetKey(ctx.params.ip)
+ return ctx
+ },
],
- remove: [ authenticate('jwt'), adminOnly ]
+ remove: [authenticate('jwt'), adminOnly],
},
after: {
- all: [
+ all: [
// Make sure the password field is never sent to the client
// Always must be the last hook
- protect('password')
+ protect('password'),
],
find: [],
get: [],
create: [
async ctx => {
- const { app } = ctx;
- if(app.get('didSetup')) return ctx;
- app.set('didSetup', true);
- fs.writeFileSync( // create empty file so we cant stat it
- path.join(__dirname, '..', '..', '..', 'db', '.didSetup'), '');
- return ctx;
- }
+ const { app } = ctx
+ if (app.get('didSetup')) return ctx
+ app.set('didSetup', true)
+ fs.writeFileSync(
+ // create empty file so we cant stat it
+ path.join(__dirname, '..', '..', '..', 'db', '.didSetup'),
+ ''
+ )
+ return ctx
+ },
],
update: [],
patch: [],
- remove: []
+ remove: [],
},
error: {
@@ -75,6 +80,6 @@ module.exports = {
create: [],
update: [],
patch: [],
- remove: []
- }
-};
+ remove: [],
+ },
+}
diff --git a/src/services/users/users.service.js b/src/services/users/users.service.js
index d47409b..8ac179f 100644
--- a/src/services/users/users.service.js
+++ b/src/services/users/users.service.js
@@ -1,25 +1,25 @@
// Initializes the `users` service on path `/users`
-const createService = require('feathers-nedb');
-const createModel = require('../../models/users.model');
-const hooks = require('./users.hooks');
-const getUrl = require('../../../util/getUrl');
+const createService = require('feathers-nedb')
+const createModel = require('../../models/users.model')
+const hooks = require('./users.hooks')
+const getUrl = require('../../../util/getUrl')
-module.exports = function (app) {
- const Model = createModel(app);
- const paginate = app.get('paginate');
+module.exports = function(app) {
+ const Model = createModel(app)
+ const paginate = app.get('paginate')
const options = {
name: 'users',
Model,
- paginate
- };
- const url = getUrl('users');
+ paginate,
+ }
+ const url = getUrl('users')
// Initialize our service with any options it requires
- app.use(url, createService(options));
+ app.use(url, createService(options))
// Get our initialized service so that we can register hooks and filters
- const service = app.service(url);
+ const service = app.service(url)
- service.hooks(hooks);
-};
+ service.hooks(hooks)
+}
diff --git a/src/trustIPs.js b/src/trustIPs.js
index b59d993..c3aa5b9 100644
--- a/src/trustIPs.js
+++ b/src/trustIPs.js
@@ -1,50 +1,49 @@
/* eslint-disable no-console */
-const fs = require('fs');
-const path = require('path');
-const fetch = require('isomorphic-unfetch');
-const ips = require('../config/trustIPs.json');
-ips.push('loopback');
+const fs = require('fs')
+const path = require('path')
+const fetch = require('isomorphic-unfetch')
+const ips = require('../config/trustIPs.json')
+ips.push('loopback')
-const cfv4 = 'https://www.cloudflare.com/ips-v4';
-const cfv6 = 'https://www.cloudflare.com/ips-v6';
-const cfConf = path.join(__dirname, '../config/cfIPs.json');
-const refreshInterval = 24 * 60 * 60 * 1000;
+const cfv4 = 'https://www.cloudflare.com/ips-v4'
+const cfv6 = 'https://www.cloudflare.com/ips-v6'
+const cfConf = path.join(__dirname, '../config/cfIPs.json')
+const refreshInterval = 24 * 60 * 60 * 1000
const getIps = str => {
- str = str.split('\n').map(ip => ip.trim());
- str = str.filter(ip => ip.length !== 0);
- return str;
-};
+ str = str.split('\n').map(ip => ip.trim())
+ str = str.filter(ip => ip.length !== 0)
+ return str
+}
const getCfIps = async app => {
- const cfIps = [];
- let res = await fetch(cfv4);
- if(res.ok) {
- cfIps.push(...getIps(await res.text()));
- }
- res = await fetch(cfv6);
- if(res.ok) {
- cfIps.push(...getIps(await res.text()));
+ const cfIps = []
+ let res = await fetch(cfv4)
+ if (res.ok) {
+ cfIps.push(...getIps(await res.text()))
+ }
+ res = await fetch(cfv6)
+ if (res.ok) {
+ cfIps.push(...getIps(await res.text()))
}
fs.writeFile(cfConf, JSON.stringify(cfIps, null, 2), err => {
- if(err) console.error(err);
- });
- app.set('trust proxy', [...ips, ...cfIps]);
-};
+ if (err) console.error(err)
+ })
+ app.set('trust proxy', [...ips, ...cfIps])
+}
module.exports = app => {
- if(!app.get('trustCloudflare')) {
- return app.set('trust proxy', ips);
+ if (!app.get('trustCloudflare')) {
+ return app.set('trust proxy', ips)
}
fs.readFile(cfConf, async (err, buff) => {
- if(err) {
- if(err.code === 'ENOENT') getCfIps(app);
- else return console.error(err);
+ if (err) {
+ if (err.code === 'ENOENT') getCfIps(app)
+ else return console.error(err)
+ } else {
+ const cfIps = JSON.parse(buff.toString())
+ app.set('trust proxy', [...ips, ...cfIps])
}
- else {
- const cfIps = JSON.parse(buff.toString());
- app.set('trust proxy', [...ips, ...cfIps]);
- }
- setInterval(() => getCfIps(app), refreshInterval);
- });
-};
\ No newline at end of file
+ setInterval(() => getCfIps(app), refreshInterval)
+ })
+}
diff --git a/test/app.test.js b/test/app.test.js
index 4fce51b..16a9700 100644
--- a/test/app.test.js
+++ b/test/app.test.js
@@ -1,55 +1,56 @@
-const assert = require('assert');
-const rp = require('request-promise');
-const url = require('url');
-const app = require('../src/app');
-const getUrlPath = require('../util/getUrl');
+const assert = require('assert')
+const rp = require('request-promise')
+const url = require('url')
+const app = require('../src/app')
+const getUrlPath = require('../util/getUrl')
-const port = app.get('port') || 3030;
-const getUrl = pathname => url.format({
- hostname: app.get('host') || 'localhost',
- protocol: 'http',
- port,
- pathname: getUrlPath(pathname)
-});
+const port = app.get('port') || 3030
+const getUrl = pathname =>
+ url.format({
+ hostname: app.get('host') || 'localhost',
+ protocol: 'http',
+ port,
+ pathname: getUrlPath(pathname),
+ })
describe('Feathers application tests', () => {
before(async () => {
- this.server = await app.run(port);
- });
+ this.server = await app.run(port)
+ })
after(done => {
- this.server.close(done);
- });
+ this.server.close(done)
+ })
it('starts and shows the index page', () => {
return rp(getUrl('/')).then(body =>
assert.ok(body.indexOf('') !== -1)
- );
- });
+ )
+ })
describe('404', function() {
it('shows a 404 HTML page', () => {
return rp({
url: getUrl('path/to/nowhere'),
headers: {
- 'Accept': 'text/html'
- }
+ Accept: 'text/html',
+ },
}).catch(res => {
- assert.equal(res.statusCode, 404);
- assert.ok(res.error.indexOf('') !== -1);
- });
- });
+ assert.equal(res.statusCode, 404)
+ assert.ok(res.error.indexOf('') !== -1)
+ })
+ })
it('shows a 404 JSON error without stack trace', () => {
return rp({
url: getUrl('path/to/nowhere'),
- json: true
+ json: true,
}).catch(res => {
- assert.equal(res.statusCode, 404);
- assert.equal(res.error.code, 404);
- assert.equal(res.error.message, 'Page not found');
- assert.equal(res.error.name, 'NotFound');
- });
- });
- });
-});
\ No newline at end of file
+ assert.equal(res.statusCode, 404)
+ assert.equal(res.error.code, 404)
+ assert.equal(res.error.message, 'Page not found')
+ assert.equal(res.error.name, 'NotFound')
+ })
+ })
+ })
+})
diff --git a/test/services/docs.test.js b/test/services/docs.test.js
index 9640698..e541593 100644
--- a/test/services/docs.test.js
+++ b/test/services/docs.test.js
@@ -1,10 +1,10 @@
-const assert = require('assert');
-const app = require('../../src/app');
-const getUrl = require('../../util/getUrl');
+const assert = require('assert')
+const app = require('../../src/app')
+const getUrl = require('../../util/getUrl')
-describe('\'docs\' service', () => {
+describe("'docs' service", () => {
it('registered the service', () => {
- const service = app.service(getUrl('docs'));
- assert.ok(service, 'Registered the service');
- });
-});
+ const service = app.service(getUrl('docs'))
+ assert.ok(service, 'Registered the service')
+ })
+})
diff --git a/test/services/users.test.js b/test/services/users.test.js
index 3e0cfb9..6986226 100644
--- a/test/services/users.test.js
+++ b/test/services/users.test.js
@@ -1,10 +1,10 @@
-const assert = require('assert');
-const app = require('../../src/app');
-const getUrl = require('../../util/getUrl');
+const assert = require('assert')
+const app = require('../../src/app')
+const getUrl = require('../../util/getUrl')
-describe('\'users\' service', () => {
+describe("'users' service", () => {
it('registered the service', () => {
- const service = app.service(getUrl('users'));
- assert.ok(service, 'Registered the service');
- });
-});
\ No newline at end of file
+ const service = app.service(getUrl('users'))
+ assert.ok(service, 'Registered the service')
+ })
+})
diff --git a/util/basePath.js b/util/basePath.js
index 126675f..901a3ed 100644
--- a/util/basePath.js
+++ b/util/basePath.js
@@ -1,8 +1,8 @@
// make sure basePath doesn't end with /
-let { basePath } = require('../config/host.json');
-const urlChars = basePath.split('');
+let { basePath } = require('../config/host.json')
+const urlChars = basePath.split('')
-if(basePath.length > 1 && urlChars.pop() === '/') {
- basePath = urlChars.join('');
+if (basePath.length > 1 && urlChars.pop() === '/') {
+ basePath = urlChars.join('')
}
-module.exports = basePath;
\ No newline at end of file
+module.exports = basePath
diff --git a/util/checkDirParts.js b/util/checkDirParts.js
index 8a9ed95..388d8bc 100644
--- a/util/checkDirParts.js
+++ b/util/checkDirParts.js
@@ -1,48 +1,52 @@
const isOkDirPart = str => {
- if(str.length > 255 || str.length === 0) return false;
- const end = str.length - 1;
- for(let i = 0; i < str.length; i++) {
- const c = str.charCodeAt(i);
- if(!(c > 47 && c < 58) && // 0-9
- !(c > 64 && c < 91) && // A-Z
- !(c > 96 && c < 123) && // a-z
- !(c === 95) && !(c === 45) && // _ and -
- !((c === 46 || c === 32) && // period or space if not first or last
- i !== 0 && i !== end)) {
- return false;
+ if (str.length > 255 || str.length === 0) return false
+ const end = str.length - 1
+ for (let i = 0; i < str.length; i++) {
+ const c = str.charCodeAt(i)
+ if (
+ !(c > 47 && c < 58) && // 0-9
+ !(c > 64 && c < 91) && // A-Z
+ !(c > 96 && c < 123) && // a-z
+ !(c === 95) &&
+ !(c === 45) && // _ and -
+ !(
+ (c === 46 || c === 32) && // period or space if not first or last
+ i !== 0 &&
+ i !== end
+ )
+ ) {
+ return false
}
}
- return true;
-};
+ return true
+}
module.exports = {
-
checkDir: dir => {
- if(typeof dir !== 'string') return false;
- dir = dir.trim();
- if(dir.length === 0) return 0;
- if(dir.indexOf('/') > -1) {
- dir = dir.split('/').filter(p => p.length !== 0);
- if(dir.length === 1) {
- if(!isOkDirPart(dir[0])) false;
- dir = dir[0];
- } else if(dir.length === 0) {
- dir = '';
- } else if(dir.some(part => !isOkDirPart(part))) {
- return false;
+ if (typeof dir !== 'string') return false
+ dir = dir.trim()
+ if (dir.length === 0) return 0
+ if (dir.indexOf('/') > -1) {
+ dir = dir.split('/').filter(p => p.length !== 0)
+ if (dir.length === 1) {
+ if (!isOkDirPart(dir[0])) false
+ dir = dir[0]
+ } else if (dir.length === 0) {
+ dir = ''
+ } else if (dir.some(part => !isOkDirPart(part))) {
+ return false
}
- } else if(!isOkDirPart(dir)) {
- return false;
+ } else if (!isOkDirPart(dir)) {
+ return false
}
- return Array.isArray(dir) ? dir.join('/') : dir;
+ return Array.isArray(dir) ? dir.join('/') : dir
},
checkName: name => {
- if(typeof name !== 'string') return false;
- name = name.trim();
- if(name.length === 0) return 0;
- if(!isOkDirPart(name)) return false;
- return name;
+ if (typeof name !== 'string') return false
+ name = name.trim()
+ if (name.length === 0) return 0
+ if (!isOkDirPart(name)) return false
+ return name
},
-
-};
\ No newline at end of file
+}
diff --git a/util/freezeSSR.js b/util/freezeSSR.js
index 1210772..b416c3d 100644
--- a/util/freezeSSR.js
+++ b/util/freezeSSR.js
@@ -1,21 +1,21 @@
const freezeSSR = selector => {
const FrozenSSR = () => {
- let __html = '';
- let props = {};
- if(typeof document !== 'undefined') {
- let el = document.querySelector(selector);
- if(el) {
- __html = el.innerHTML;
+ let __html = ''
+ let props = {}
+ if (typeof document !== 'undefined') {
+ let el = document.querySelector(selector)
+ if (el) {
+ __html = el.innerHTML
el.getAttributeNames().forEach(attr => {
- const attrKey = attr === 'class' ? 'className' : attr;
- props[attrKey] = el.getAttribute(attr);
- });
- }
+ const attrKey = attr === 'class' ? 'className' : attr
+ props[attrKey] = el.getAttribute(attr)
+ })
+ }
}
- return
;
- };
+ return
+ }
- return { loading: FrozenSSR };
-};
+ return { loading: FrozenSSR }
+}
-export default freezeSSR;
\ No newline at end of file
+export default freezeSSR
diff --git a/util/getDocs.js b/util/getDocs.js
index 452312b..47848bc 100644
--- a/util/getDocs.js
+++ b/util/getDocs.js
@@ -1,36 +1,39 @@
-import fetch from 'isomorphic-unfetch';
-import parseSort from './parseSort';
-import getUrl from './getUrl';
-import getJwt from './getJwt';
+import fetch from 'isomorphic-unfetch'
+import parseSort from './parseSort'
+import getUrl from './getUrl'
+import getJwt from './getJwt'
-export const $limit = 12; // number of docs per page
-export const select = ['id', 'name', 'updated', 'dir']
- .map((f, i) => ({ [`$select[${i}]`]: f }));
+export const $limit = 12 // number of docs per page
+export const select = ['id', 'name', 'updated', 'dir'].map((f, i) => ({
+ [`$select[${i}]`]: f,
+}))
export const getDocs = async (q, jwt) => {
const docsRes = await fetch(getUrl('docs', Boolean(jwt)) + q, {
- headers: { Authorization: jwt || getJwt() }
- }).catch(({ message }) => ({ ok: false, error: message }));
- if(docsRes.ok) {
- const res = await docsRes.json();
- const total = res.total || 0;
- const docs = res.data || [];
- return { docs, total };
+ headers: { Authorization: jwt || getJwt() },
+ }).catch(({ message }) => ({ ok: false, error: message }))
+ if (docsRes.ok) {
+ const res = await docsRes.json()
+ const total = res.total || 0
+ const docs = res.data || []
+ return { docs, total }
}
- return { total: 0, docs: [], error: docsRes.message };
-};
+ return { total: 0, docs: [], error: docsRes.message }
+}
export const buildQ = q => {
- if(!q.$search) delete q.$search;
- if(!q.$skip) delete q.$skip;
+ if (!q.$search) delete q.$search
+ if (!q.$skip) delete q.$skip
else {
- q.$skip = (q.$skip - 1) * $limit;
+ q.$skip = (q.$skip - 1) * $limit
}
- const $sort = parseSort(q.$sort ? q.$sort : 'updated:-1');
- delete q.$sort;
- select.forEach(sel => q = {...q, ...sel});
- q = { $limit, ...q };
- let url = Object.keys(q).map(k => `${k}=${encodeURIComponent(q[k])}`).join('&');
- url = `?${url}&${$sort}`;
- return url;
-};
\ No newline at end of file
+ const $sort = parseSort(q.$sort ? q.$sort : 'updated:-1')
+ delete q.$sort
+ select.forEach(sel => (q = { ...q, ...sel }))
+ q = { $limit, ...q }
+ let url = Object.keys(q)
+ .map(k => `${k}=${encodeURIComponent(q[k])}`)
+ .join('&')
+ url = `?${url}&${$sort}`
+ return url
+}
diff --git a/util/getJwt.js b/util/getJwt.js
index 8c7c117..ab697bd 100644
--- a/util/getJwt.js
+++ b/util/getJwt.js
@@ -1,6 +1,6 @@
export default req => {
- if(req) return req.jwt;
- if(typeof window !== 'undefined') {
- return window.localStorage.getItem('jwt');
+ if (req) return req.jwt
+ if (typeof window !== 'undefined') {
+ return window.localStorage.getItem('jwt')
}
-};
\ No newline at end of file
+}
diff --git a/util/getUrl.js b/util/getUrl.js
index 6ff706c..bff9cef 100644
--- a/util/getUrl.js
+++ b/util/getUrl.js
@@ -1,15 +1,15 @@
-const url = require('url');
-const urljoin = require('url-join');
-const basePath = require('./basePath');
-const { host, port, protocol } = require('../config/host.json');
+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);
- if(!absolute) return path;
+ path = urljoin(basePath, path)
+ if (!absolute) return path
return url.format({
hostname: host,
port,
protocol,
pathname: path,
- });
-};
\ No newline at end of file
+ })
+}
diff --git a/util/keys.js b/util/keys.js
index 385b23f..1e88e1d 100644
--- a/util/keys.js
+++ b/util/keys.js
@@ -1,4 +1,4 @@
module.exports = {
getKey: e => e.which || e.keyCode,
- isCtrlKey: key => key === 91 || key === 93 || key === 17
-};
\ No newline at end of file
+ isCtrlKey: key => key === 91 || key === 93 || key === 17,
+}
diff --git a/util/mapUser.js b/util/mapUser.js
index 509305d..a6c2c5c 100644
--- a/util/mapUser.js
+++ b/util/mapUser.js
@@ -1,3 +1,3 @@
-export default ({ user }) => {
- return { user };
-};
\ No newline at end of file
+export default ({ user }) => {
+ return { user }
+}
diff --git a/util/parseSort.js b/util/parseSort.js
index 70bb77a..e93b8f1 100644
--- a/util/parseSort.js
+++ b/util/parseSort.js
@@ -1,18 +1,19 @@
export default sort => {
- let key, ascDesc;
- switch(typeof sort) {
- case 'object': {
- key = Object.keys(sort).pop();
- ascDesc = sort[key];
- break;
+ let key, ascDesc
+ switch (typeof sort) {
+ case 'object': {
+ key = Object.keys(sort).pop()
+ ascDesc = sort[key]
+ break
+ }
+ case 'string': {
+ const parts = sort.split(':')
+ key = parts[0]
+ ascDesc = parts[1]
+ break
+ }
+ default:
+ break
}
- case 'string': {
- const parts = sort.split(':');
- key = parts[0];
- ascDesc = parts[1];
- break;
- }
- default: break;
- }
- return `$sort[${key}]=${ascDesc}`;
-};
\ No newline at end of file
+ return `$sort[${key}]=${ascDesc}`
+}
diff --git a/util/stripBase.js b/util/stripBase.js
index 77ed467..876ef72 100644
--- a/util/stripBase.js
+++ b/util/stripBase.js
@@ -1,8 +1,8 @@
-const basePath = require('./basePath');
+const basePath = require('./basePath')
module.exports = url => {
- if(basePath !== '/') {
- url = url.split(basePath).join('');
+ if (basePath !== '/') {
+ url = url.split(basePath).join('')
}
- return url;
-};
\ No newline at end of file
+ return url
+}
diff --git a/util/updStateFromId.js b/util/updStateFromId.js
index 9808764..c59fd5f 100644
--- a/util/updStateFromId.js
+++ b/util/updStateFromId.js
@@ -1,4 +1,4 @@
-export default function updateStateFromId(e){
- const el = e.target;
- this.setState({ [el.id]: el.value });
-}
\ No newline at end of file
+export default function updateStateFromId(e) {
+ const el = e.target
+ this.setState({ [el.id]: el.value })
+}