summaryrefslogtreecommitdiff
path: root/app/server
diff options
context:
space:
mode:
Diffstat (limited to 'app/server')
-rw-r--r--app/server/db/model.js55
-rw-r--r--app/server/db/models.js4
-rw-r--r--app/server/site.js34
-rw-r--r--app/server/util/auth.js168
4 files changed, 231 insertions, 30 deletions
diff --git a/app/server/db/model.js b/app/server/db/model.js
index dd851bf..c829c85 100644
--- a/app/server/db/model.js
+++ b/app/server/db/model.js
@@ -17,9 +17,8 @@ module.exports = function modelScope(type, db_model, _props) {
crud: crud,
index: (query) => {
-
- return new Promise( (resolve, reject) => {
- crud.index(query).then( (data) => {
+ return new Promise((resolve, reject) => {
+ crud.index(query).then(data => {
if (! props.hasOne) {
resolve(data ? data.toJSON() : [])
@@ -27,13 +26,13 @@ module.exports = function modelScope(type, db_model, _props) {
else {
let recs = data.toJSON()
const loader = new Loader ()
- loader.onReady( () => {
+ loader.onReady(() => {
// console.log(type, 'ready')
resolve(recs)
})
// console.log('hasOne')
loader.register('hasOne')
- Object.keys(props.hasOne).forEach( (key,i) => {
+ Object.keys(props.hasOne).forEach((key, i) => {
loader.register(key)
// console.log('register', key)
const type = props.hasOne[key]
@@ -45,7 +44,7 @@ module.exports = function modelScope(type, db_model, _props) {
})
// console.log('\n\n%%%%%%%%%%%%%%%%%%%%%%%% index > hasOne ' + key + '\n\n\n')
// console.log(recs.length, Object.keys(id_lookup).length)
- db_crud(type).show_ids(Object.keys(id_lookup)).then( (sub_recs) => {
+ db_crud(type).show_ids(Object.keys(id_lookup)).then(sub_recs => {
// console.log(key, 'sub_recs', sub_recs)
const short_key = key.replace('_id','')
sub_recs.toJSON().forEach(rec => {
@@ -57,49 +56,51 @@ module.exports = function modelScope(type, db_model, _props) {
})
loader.ready('hasOne')
}
- }) // }).catch( () => res.sendStatus(500) )
+ })
})
},
- show: (id) => {
- return new Promise( (resolve, reject) => {
- crud.show(id).then( (data) => {
- if (! props.hasOne) {
+ show: (id, field = 'id') => {
+ return new Promise((resolve, reject) => {
+ crud.show(id, field).then(data => {
+ if (!data) {
+ resolve()
+ } else if (! props.hasOne) {
resolve(data.toJSON())
}
else {
let rec = data.toJSON()
const loader = new Loader ()
- loader.onReady( () => {
+ loader.onReady(() => {
resolve(rec)
})
loader.register('hasOne')
- Object.keys(props.hasOne).forEach( (key,i) => {
+ Object.keys(props.hasOne).forEach((key, i) => {
loader.register(key)
const type = props.hasOne[key]
- db_crud(type).show(rec[key + '_id']).then( (sub_rec) => {
+ db_crud(type).show(rec[key + '_id']).then((sub_rec) => {
rec[key] = sub_rec
loader.ready(key)
})
})
loader.ready('hasOne')
}
- }) // .catch( (err) => res.sendStatus(500) )
+ })
})
},
findOrCreate: (data) => {
- return new Promise( (resolve, reject) => {
+ return new Promise((resolve, reject) => {
let query = Object.assign({}, data)
query.limit = 1
- crud.index(query).then( (recs) => {
+ crud.index(query).then((recs) => {
if (recs && recs.length) {
const rec = recs.at(0)
// console.log('found rec', data.name)
return resolve(rec)
}
// console.log('creating rec', data.name)
- model.create(data).then( (rec) => {
+ model.create(data).then((rec) => {
resolve(rec)
})
})
@@ -107,12 +108,12 @@ module.exports = function modelScope(type, db_model, _props) {
},
create: (data) => {
- return new Promise( (resolve, reject) => {
+ return new Promise((resolve, reject) => {
const should_relay = data.should_relay === 'true'
- crud.create( model.sanitize(data) ).then( (rec) => {
+ crud.create( model.sanitize(data) ).then((rec) => {
resolve(rec.toJSON())
props.afterCreate && props.afterCreate(rec, should_relay)
- }).catch( (e) => {
+ }).catch(e => {
console.error('error creating', e)
reject()
})
@@ -121,10 +122,10 @@ module.exports = function modelScope(type, db_model, _props) {
update: (id, data) => {
// console.log('update', id)
- return new Promise( (resolve, reject) => {
- crud.update(id, model.sanitize(data)).then( (data) => {
+ return new Promise((resolve, reject) => {
+ crud.update(id, model.sanitize(data)).then(data => {
resolve(data.toJSON())
- }).catch( (e) => {
+ }).catch(e => {
console.error('error updating', e)
reject()
})
@@ -132,7 +133,7 @@ module.exports = function modelScope(type, db_model, _props) {
},
destroy: (id) => {
- return new Promise( (resolve, reject) => {
+ return new Promise((resolve, reject) => {
crud.show(id).then( data => {
if (! data) {
console.error('no record found', id)
@@ -141,9 +142,9 @@ module.exports = function modelScope(type, db_model, _props) {
if (type === 'file') {
upload.destroyFile(data)
}
- crud.destroy(id).then( (destroyData) => {
+ crud.destroy(id).then((destroyData) => {
resolve(data.toJSON())
- })// .catch( () => res.sendStatus(500) )
+ })
})
})
},
diff --git a/app/server/db/models.js b/app/server/db/models.js
index 24be774..8bf6d9a 100644
--- a/app/server/db/models.js
+++ b/app/server/db/models.js
@@ -21,7 +21,7 @@ let Task = bookshelf.Model.extend({
jsonColumns: ['opt'],
})
let User = bookshelf.Model.extend({
- tableName: 'user',
+ tableName: 'users',
hasTimestamps: true,
}, {
jsonColumns: ['profile'],
@@ -61,7 +61,7 @@ module.exports = {
// bridge.processTasks()
}
}),
- user: model('user', Task, {
+ user: model('user', User, {
fields: "username password realname level avatar lastseen profile created_at updated_at".split(" "),
afterCreate: (user) => {
console.log('created user')
diff --git a/app/server/site.js b/app/server/site.js
index 85c932f..717e42b 100644
--- a/app/server/site.js
+++ b/app/server/site.js
@@ -2,12 +2,18 @@ const express = require('express')
const http = require('http')
const path = require('path')
const multer = require('multer')()
-const upload = require('./util/upload')
+const sessionstore = require('sessionstore')
+const session = require('express-session')
const bodyParser = require('body-parser')
+const cookieParser = require('cookie-parser')
+const MongoStore = require('connect-mongo')(session);
const compression = require('compression')
// const multer = require('multer')
// const upload = multer({ dest: 'uploads/' })
+const upload = require('./util/upload')
+const auth = require('./util/auth')
+
export const app = new express()
export const server = http.createServer(app)
@@ -17,6 +23,32 @@ app.use(bodyParser.urlencoded({ extended: false, limit: '100mb', }))
app.use(express.query())
app.use(express.static(path.join(__dirname, '../../public')))
app.use(compression())
+app.use(cookieParser())
+var sessionSettings = {
+ secret: 'argonauts',
+ proxy: true,
+ key: 'cortex.sid',
+ cookie: {
+ secure: process.env.NODE_ENV === 'production',
+ domain: '.' + process.env.HOST_NAME,
+ maxAge: 43200000000,
+ },
+ resave: true,
+ saveUninitialized: false,
+}
+if (!process.env.SESSIONS_IN_MEMORY) {
+ sessionSettings.store = new MongoStore({
+ url: 'mongodb://127.0.0.1:28108/cortexSessionDb'
+ // type: 'mongodb',
+ // host: 'localhost',
+ // port: 27017,
+ // dbName: 'buckySessionDb',
+ // collectionName: 'sessions',
+ // timeout: 10000,
+ })
+}
+app.use(session(sessionSettings))
+auth.route(app, serve_index)
export const io = require('socket.io').listen(server)
diff --git a/app/server/util/auth.js b/app/server/util/auth.js
new file mode 100644
index 0000000..1515bb4
--- /dev/null
+++ b/app/server/util/auth.js
@@ -0,0 +1,168 @@
+import passport from 'passport'
+import { Strategy as LocalStrategy } from 'passport-local'
+import crypto from 'crypto'
+import db from '../db'
+
+const { user: userModel } = db.models
+
+export function route(app, serve_index){
+ app.use(passport.initialize())
+ app.use(passport.session())
+ passport.serializeUser(serializeUser)
+ passport.deserializeUser(deserializeUser)
+ passport.use(new LocalStrategy(verifyLocalUser))
+
+ app.get("/login", serve_index)
+ app.get("/signup", serve_index)
+ app.get("/logout", logout)
+
+ app.put("/api/signup",
+ checkIfUserExists,
+ createUser,
+ login)
+ app.put("/api/login",
+ passport.authenticate("local"),
+ login)
+ app.put("/api/checkin",
+ ensureAuthenticated,
+ checkin)
+}
+
+export function ensureAuthenticated(req, res, next) {
+ if (!req.isAuthenticated()) {
+ if (req.session) req.session.returnTo = req.path
+ return res.redirect('/login')
+ }
+ next()
+}
+
+export function getUserByUsername(username) {
+ return userModel.show(sanitizeName(username), 'username')
+}
+
+export function checkIfUserExists(req, res, next) {
+ getUserByUsername(req.body.username)
+ .then((user) => {
+ console.log('gotta user?', !!user);
+ user ? res.json({ error: "user exists" }) : next()
+ }).catch(err => {
+ console.error('error', err)
+ })
+}
+
+export function sanitizeName(s) { return (s || "").replace(new RegExp('[^-_a-zA-Z0-9]', 'g'), "") }
+export function sanitizeUser(req_user) {
+ // sanitize user object
+ let user = JSON.parse(JSON.stringify(req_user))
+ try {
+ user.profile = JSON.parse(user.profile)
+ } catch (e) {
+ console.error('error decoding profile')
+ user.profile = {}
+ }
+ delete user.password
+ return user
+}
+
+export function createUser(req, res, next) {
+ const { username, password, password2 } = req.body
+ if (password !== password2) {
+ return res.json({ error: "passwords don't match" })
+ }
+ let data = {
+ username: sanitizeName(username),
+ realname: sanitizeName(username),
+ password: makePassword(password),
+ lastseen: new Date(),
+ level: 0,
+ profile: {},
+ }
+ userModel.create(data)
+ .then(user => {
+ console.log('created userrrrr', user)
+ req.login(user, err => {
+ console.log(err)
+ err ? next(err) : next()
+ })
+ })
+ .catch(err => {
+ res.json({ error })
+ })
+}
+
+export function login(req, res) {
+ console.log(req.user)
+ if (req.isAuthenticated()) {
+ let returnTo = req.session.returnTo
+ delete req.session.returnTo
+ console.log(">> logged in", req.user.username)
+ return res.json({
+ status: "OK",
+ user: sanitizeUser(req.user),
+ returnTo: returnTo || "/",
+ })
+ }
+ res.json({
+ error: 'bad credentials',
+ })
+}
+
+export function serializeUser(user, done) {
+ done(null, user.id)
+}
+
+export function deserializeUser(id, done) {
+ userModel.show(id).then(user => {
+ done(!user, user)
+ }).catch(done)
+}
+
+export function makePassword(password) {
+ let shasum = crypto.createHash('sha1')
+ shasum.update(password)
+ return shasum.digest('hex')
+}
+
+export function validPassword(user, password) {
+ return user.password === makePassword(password)
+}
+
+export function changePassword(req, res, next) {
+ if (!req.body.oldpassword && !req.body.newpassword) return next()
+ if (req.body.newpassword !== req.body.newpassword2) {
+ return res.send({ error: 'Passwords don\'t match.' })
+ }
+ if (!validPassword(res.user, req.body.oldpassword)) {
+ return res.send({ error: 'Password is incorrect.' })
+ }
+ let username = req.user.username
+ let newPassword = makePassword(req.body.newpassword)
+ res.user.password = newPassword
+ res.user.save()
+ .then(next)
+ .catch(err => res.send({ error: err }))
+}
+
+export function verifyLocalUser(username, password, done) {
+ // handle passwords!!
+ getUserByUsername(username)
+ .then(user => {
+ console.log(user)
+ // if (err) { return done(err) }
+ if (! user) { return done("no user") }
+ if (! user || !validPassword(user, password)) {
+ return done(null, false, { error: { message: 'Bad username/password.' } })
+ }
+ return done(null, user)
+ })
+}
+
+export function checkin(req, res) {
+ console.log(req.user)
+ res.json({ user: sanitizeUser(req.user) })
+}
+
+export const logout = (req, res) => {
+ req.logout()
+ res.redirect('/')
+} \ No newline at end of file