You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
4.4 KiB

import fastifySession from '@fastify/session'
import fastifyCookie from 'fastify-cookie'
import PouchDB from 'pouchdb'
import PouchDBfind from 'pouchdb-find'
/**
* pouchdb storage
*
*
* @extends Store
*
*/
class PouchdbStore extends Store
{
/**
*
*
* @param {Object}
*
*/
constructor()
{
super()
PouchDB.plugin(PouchDBfind)
// create db if not already exists
this.db = new PouchDB('./../../storage/session', {
revs_limit: 0
})
}
/**
*
* @param {[type]} sessionId [description]
* @param {Function} callback [description]
*/
async set(sessionId, session, callback)
{
const result = await this.db.find({
'selector': {
'_id': sessionId
}
})
if (result.docs.length === 0) {
session._id = sessionId
await this.db.post(session)
}
callback()
}
/**
*
* @param {[type]} sessionId [description]
* @param {Function} callback [description]
* @return {[type]} [description]
*/
async get(sessionId, callback)
{
const result = await this.db.find({
'selector': {
'_id': sessionId
}
})
let session = null
if (result.docs.length > 0) {
session = result.docs[0]
}
callback(null, session)
}
/**
*
* @param {[type]} sessionId [description]
* @param {Function} callback [description]
* @return {[type]} [description]
*/
async destroy(sessionId, callback)
{
const result = await this.db.find({
'selector': {
'_id': sessionId
}
})
if (result.docs.length > 0) {
await this.db.remove(result.docs[0])
}
callback()
}
}
/**
*
*
*
*/
const loginSchema = {
schema: {
body: {
username: { type: 'string' },
password: { type: 'string' }
},
response: {
200: {
type: 'object',
properties: {
token: { type: 'string' }
}
}
}
}
}
/**
* create Plugin
*
*
*/
function plugin(fastify, options, next) {
{
// create cookie
fastify
.register(fastifyCookie)
.register(fastifySession, {
secret: options.secret,
cookieName: 'session',
cookie: {
path: '/',
maxAge: options.secret,
secure: true,
httpOnly: true,
sameSite: 'Strict'
},
store: new PouchdbStore()
})
/**
* route: logout user and destroy session
*
*
*/
fastify.get('/logout', async function(request, response)
{
request.destroySession(() => {
response.redirect('/')
})
})
/**
* route: auth
*
* @param {object} request
* @param {object} response
*
*/
fastify.post('/auth', loginSchema, async function (request, reply)
{
let { username, password } = request.body
// strip crap from strings
username = DOMPurify.sanitize(username)
password = DOMPurify.sanitize(password)
const userRepository = new UserRepository()
const user = await userRepository.findOneByUsername(username)
// add header for json
reply.header('Content-Type', 'application/json; charset=utf-8')
// user not found
if (!user) {
return reply
.code(404)
.send()
}
// password wrong
if (!bcrypt.compareSync(password, user.password)) {
return reply
.code(401)
.send()
}
// setting session to store and set cookie
request.sessionStore.set(request.session.sessionId, request.session, async function() {
user.sessionId = request.session.sessionId
await userRepository.update(user)
// send 200 and send set-token
reply
.code(200)
.send()
})
})
done()
}
module.exports = plugin