Recv/lib/repository.js

208 lines
3.7 KiB
JavaScript

//const debug = require('debug')('recv:users');
const _ = require('lodash');
const path = require('path');
const mkdirp = require('mkdirp');
const bcrypt = require('bcrypt');
const Datastore = require('nedb');
const shortid = require('shortid');
const retry = require('async-retry')
class Repository
{
constructor(config)
{
var self = this;
const initStore = (filename) =>
{
var store = new Datastore({
filename: path.join(config.path, filename),
autoload: true
});
store.persistence.setAutocompactionInterval(config.autocompactionInterval);
return store;
};
mkdirp(config.path, (err) =>
{
if (err)
{
console.log(err);
return;
}
self.db = {
users: initStore('users.db'),
codes: initStore('codes.db'),
uploads: initStore('uploads.db')
};
// Initialize database if empty
self.db.users.count({}, (err, count) =>
{
if (err)
{
console.log(err);
return;
}
if (count == 0)
self.addUser('admin', null, 'test');
});
});
}
async isValidUser(username, password)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.db.users.findOne({ username: username }, (err, doc) =>
{
if (err)
{
reject(err);
return;
}
if (doc == null)
{
resolve(false);
return;
}
bcrypt.compare(password, doc.password, (err, res) =>
{
if (err)
reject(err)
else
resolve(res);
});
});
});
}
async addUser(username, email, password)
{
var self = this;
return new Promise((resolve, reject) =>
{
bcrypt.hash(password, 10, function(err, hash)
{
if (err)
{
reject(err);
return;
}
var user = {
username: username,
email: email,
password: hash
};
self.db.users.insert(user, (err, dbUser) =>
{
if (err)
{
reject(err);
return;
}
resolve(dbUser._id);
});
});
});
}
async findCodeUserId(code)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.db.codes.findOne({ _id: code }, (err, doc) =>
{
if (err)
{
reject(err);
return;
}
resolve(doc !== null ? doc.userId : null);
});
});
}
async addCode(userId, expiration)
{
var self = this;
return await retry(async bail =>
{
var code = shortid.generate();
if ((await self.findCodeUserId(code)) !== null)
throw new Error('Code ' + code + ' already exists');
self.db.codes.insert({
_id: code,
userId: userId,
expiration: expiration
})
return code;
}, {
retries: 100,
minTimeout: 0,
maxTimeout: 0
});
}
async addUpload(userId, files)
{
var self = this;
return new Promise((resolve, reject) =>
{
var upload = {
files: _.map(_.filter(files,
(file) => file.hasOwnProperty('id') && file.hasOwnProperty('name')),
(file) => { return { id: file.id, name: file.name } })
};
console.log(upload);
if (upload.files.length)
{
self.db.uploads.insert(upload, (err, dbUpload) =>
{
console.log(dbUpload);
if (err)
{
reject(err);
return;
}
resolve(dbUpload._id);
});
}
else
{
reject();
}
});
}
}
module.exports = Repository;