diff --git a/api/src/api/accounts.js b/api/src/api/accounts.js index be05cb6..4de76fc 100644 --- a/api/src/api/accounts.js +++ b/api/src/api/accounts.js @@ -1,39 +1,70 @@ const api = require('../api-utils.js') const db = require('../db.js') const pwd = require('../passwd.js') +const utils = require('../utils.js') module.exports = { + login: { + post: async (req, res) => { + if (req.body.email === undefined || + req.body.password === undefined) + return res.status(400).json({ error: 'invalid_params' }) + + const user = await db.table.users().findOne({ email: req.body.email }) + if (user === null || user.activated !== 1) + return res.status(403).json({ error: 'login_failed' }) + + if (!pwd.comparePassword(req.body.password, user.password)) + return res.status(403).json({ error: 'invalid_password' }) + + const session_id = utils.randomString(128) + const session = await db.table.sessions().insertOne({ + id_user: user._id, + session: session_id + }) + + if (session.insertedCount > 0) { + const dayjs = require('dayjs') + res.cookie('fedilove_session', session_id, { + expires: dayjs().add(2, "months").toDate(), + httpOnly: true, + secure: true, + }) + return res.json({ result: 1 }) + } + return res.status(500).json({ error: 'unknown_error' }) + }, + }, register: { post: async (req, res) => { - if (req.body.username !== undefined && - req.body.email !== undefined && - req.body.password !== undefined && - req.body.password2 !== undefined) { + if (req.body.username === undefined || + req.body.email === undefined || + req.body.password === undefined || + req.body.password2 === undefined) + return res.status(400).json({ error: 'invalid_params' }) - // TODO: validate values, sanitize and check captcha or other registration limitations - console.log(req.body) + // TODO: validate values, sanitize and check captcha or other registration limitations + console.log(req.body) - if (req.body.password !== req.body.password2) - return res.status(400).json({ error: 'passwords_not_match' }) + if (req.body.password !== req.body.password2) + return res.status(400).json({ error: 'passwords_not_match' }) - if (await db.table.users().findOne({ username: req.body.username }) != null) - return res.status(403).json({ error: 'username_already_exists' }) + if (await db.table.users().findOne({ username: req.body.username }) !== null) + return res.status(403).json({ error: 'username_already_exists' }) - if (await db.table.users().findOne({ email: req.body.email }) !== null) - return res.status(403).json({ error: 'email_already_exists' }) + if (await db.table.users().findOne({ email: req.body.email }) !== null) + return res.status(403).json({ error: 'email_already_exists' }) - const documen = await db.table.users().insertOne({ - 'username': req.body.username, - 'email': req.body.email, - 'password': pwd.cryptPassword(req.body.password), - 'activated': 1, // TODO: change to 0 and activate by email verification later - }) + const documen = await db.table.users().insertOne({ + 'username': req.body.username, + 'email': req.body.email, + 'password': pwd.cryptPassword(req.body.password), + 'activated': 1, // TODO: change to 0 and activate by email verification later + }) - if (documen.insertedCount > 0) - return res.json({ result: documen.insertedId }) - return res.status(500).json({ error: 'unknown_error' }) - } - return res.status(400).json({ error: 'invalid_params' }) + if (documen.insertedCount > 0) + return res.json({ result: documen.insertedId }) + return res.status(500).json({ error: 'unknown_error' }) }, } } diff --git a/api/src/db.js b/api/src/db.js index fe5d68d..d57f89a 100644 --- a/api/src/db.js +++ b/api/src/db.js @@ -19,5 +19,6 @@ module.exports = { }, table: { users: () => { return mdb.collection('u__users') }, + sessions: () => { return mdb.collection('u__sessions') }, }, } diff --git a/api/src/package.json b/api/src/package.json index 8a9fb14..f0eaf34 100644 --- a/api/src/package.json +++ b/api/src/package.json @@ -2,6 +2,8 @@ "dependencies": { "activitypub-express": "^2.3.0", "bcrypt": "^5.0.1", + "cookie-parser": "^1.4.6", + "dayjs": "^1.10.7", "deasync": "^0.1.24", "node-gyp": "^8.4.1" } diff --git a/api/src/server.js b/api/src/server.js index dd13ba0..1e29b02 100644 --- a/api/src/server.js +++ b/api/src/server.js @@ -36,6 +36,7 @@ const client = db.conn() // extensions for express app.use(express.json({ type: apex.consts.jsonldTypes }), apex) +app.use(require('cookie-parser')()) app.use(bodyParser.urlencoded({ extended: true })) // define routes using prepacakged middleware collections @@ -70,8 +71,8 @@ app.on('apex-inbox', msg => { }) // API defines -app.route(api.url('/accounts/register')) - .post(api.accounts.register.post) +app.route(api.url('/accounts/register')).post(api.accounts.register.post) +app.route(api.url('/accounts/login')).post(api.accounts.login.post) // initialize diff --git a/api/src/utils.js b/api/src/utils.js new file mode 100644 index 0000000..d7db5f1 --- /dev/null +++ b/api/src/utils.js @@ -0,0 +1,6 @@ +const Crypto = require('crypto') + +exports.randomString = (size) => { + return Crypto.randomBytes(size) + .toString('base64').slice(0, size) +}