1
0

Auth is working again with express-session for user tracking

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-04-07 16:36:56 -07:00
parent d21946cb9e
commit 4c6040e3bc
11 changed files with 285 additions and 132 deletions

1
.env
View File

@ -1,2 +1,3 @@
REACT_APP_basePath="/" REACT_APP_basePath="/"
NODE_CONFIG_ENV='production' NODE_CONFIG_ENV='production'
LOG_LINE=1

View File

@ -2,3 +2,4 @@ PORT=3001
PUBLIC_URL=/ PUBLIC_URL=/
HOST=nuc.ketrenos.com HOST=nuc.ketrenos.com
DANGEROUSLY_DISABLE_HOST_CHECK='true' DANGEROUSLY_DISABLE_HOST_CHECK='true'
LOG_LINE=1

View File

@ -24,6 +24,7 @@ import { base } from "./Common.js";
const App = () => { const App = () => {
const [ user, setUser ] = useState(null); const [ user, setUser ] = useState(null);
const [ csrfToken, setCsrfToken ] = useState(undefined); const [ csrfToken, setCsrfToken ] = useState(undefined);
const [ loading, setLoading ] = useState(true);
useEffect(() => { useEffect(() => {
const effect = async () => { const effect = async () => {
@ -43,7 +44,7 @@ const App = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (csrfToken) { if (!csrfToken) {
return; return;
} }
const effect = async () => { const effect = async () => {
@ -57,6 +58,12 @@ const App = () => {
}, },
}); });
const data = await res.json(); const data = await res.json();
setLoading(false);
if (res.status >= 400) {
console.log(data.message ? data.message : res.statusText);
return;
}
setUser(data); setUser(data);
}; };
@ -83,9 +90,12 @@ const App = () => {
<Route path="/" element={ <Route path="/" element={
<Paper style={{padding: "0.5rem"}}>You need to verify your email via the link sent to {user.email}.</Paper>}/> <Paper style={{padding: "0.5rem"}}>You need to verify your email via the link sent to {user.email}.</Paper>}/>
} }
{ !user && { !user && !loading &&
<Route path="/" element={<SignIn />} /> <Route path="/" element={<SignIn />} />
} }
{ !user && loading &&
<Route path="/" element={<div>Loading...</div>} />
}
</Routes> </Routes>
</Container> </Container>
</GlobalContext.Provider> </GlobalContext.Provider>

View File

@ -23,7 +23,7 @@ function Dashboard() {
const effect = async () => { const effect = async () => {
const res = await window.fetch( const res = await window.fetch(
`${base}/api/v1/groups`, { `${base}/api/v1/groups`, {
method: 'POST', method: 'GET',
cache: 'no-cache', cache: 'no-cache',
credentials: 'same-origin', credentials: 'same-origin',
headers: { headers: {

View File

@ -1,4 +1,4 @@
import React, { useContext, useState } from 'react'; import React, { useContext, useState, useCallback } from 'react';
import Avatar from '@mui/material/Avatar'; import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline'; import CssBaseline from '@mui/material/CssBaseline';
@ -37,10 +37,10 @@ export default function SignIn() {
const [ error, setError ] = useState(undefined); const [ error, setError ] = useState(undefined);
const navigate = useNavigate(); const navigate = useNavigate();
const handleSubmit = (event) => { const handleSubmit = useCallback(async (event) => {
event.preventDefault(); event.preventDefault();
const data = new FormData(event.currentTarget); const form = new FormData(event.currentTarget);
window.fetch(`${base}/api/v1/users/signin`, { const res = await window.fetch(`${base}/api/v1/users/signin`, {
method: 'POST', method: 'POST',
cache: 'no-cache', cache: 'no-cache',
credentials: 'same-origin', credentials: 'same-origin',
@ -49,28 +49,22 @@ export default function SignIn() {
'CSRF-Token': csrfToken 'CSRF-Token': csrfToken
}, },
body: JSON.stringify({ body: JSON.stringify({
email: data.get('email'), email: form.get('email'),
password: data.get('password') password: form.get('password')
}) })
}) });
.then(async (res) => { const data = await res.json();
return [ res.status, res.statusText, await res.json() ]; if (res.status >= 400) {
}) setError(data.message ? data.message : res.statusText);
.then(([ status, statusText, data ]) => {
if (status >= 400) {
setError(data.message ? data.message : statusText);
return null; return null;
} if (!data) { }
if (!data) {
return; return;
} }
setUser(data); setUser(data);
navigate("/"); navigate("/");
}) }, [csrfToken, navigate, setUser ]);
.catch((error) => {
console.error(`Error: `, error);
setError(`Error authenticating.`);
});
};
return ( return (
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>

View File

@ -11,6 +11,9 @@
"indent": [ "indent": [
"error", "error",
2 2
] ],
"quotes": [ 2, "single", {
"allowTemplateLiterals": true
} ]
} }
} }

View File

@ -8,12 +8,16 @@ const express = require('express'),
bodyParser = require('body-parser'), bodyParser = require('body-parser'),
config = require('config'), config = require('config'),
session = require('express-session'), session = require('express-session'),
sqliteStoreFactory = require('express-session-sqlite').default,
basePath = require('./basepath'), basePath = require('./basepath'),
cookieParser = require('cookie-parser'),
app = express(), app = express(),
csrf = require('csurf'), csrf = require('csurf'),
http = require('http'), http = require('http'),
{ goodTimesDB } = require('./db.js'); methodOverride = require('method-override'),
cookieParser = require('cookie-parser'),
{ goodTimesDB } = require('./db.js'),
sqlite3 = require('sqlite3'),
SqliteStore = sqliteStoreFactory(session);
require('./console-line.js'); /* Monkey-patch console.log with line numbers */ require('./console-line.js'); /* Monkey-patch console.log with line numbers */
@ -21,12 +25,27 @@ require('./console-line.js'); /* Monkey-patch console.log with line numbers */
* set in the headers */ * set in the headers */
app.set('trust proxy', true); app.set('trust proxy', true);
app.use(session({ app.use(session({
secret: 'm@g1x!', secret: 'm@g1x!c00k13$',
resave: false, maxAge: 14 * 24 * 60 * 60 * 1000, /* 2 weeks */
resave: true,
saveUninitialized: false, saveUninitialized: false,
cookie: { secure: true } cookie: { secure: true },
store: new SqliteStore({
driver: sqlite3.Database,
path: config.get('sessions.db'),
ttl: 5000,
cleanupInterval: 300000
}),
})); }));
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next) => {
console.log('CSRF debug: ', {
token: req.header('CSRF-Token'),
method: req.method
});
next();
});
app.use(cookieParser()); app.use(cookieParser());
app.use(csrf({ app.use(csrf({
cookie: true cookie: true
@ -35,22 +54,30 @@ app.use(bodyParser.json());
//const ws = require('express-ws')(app, server); //const ws = require('express-ws')(app, server);
app.use(function (err, req, res) {
console.error(err.message);
res.status(err.status || 500).json({
message: err.message,
error: {}
});
});
/* Initialize the data base, configure routes, and open server */ /* Initialize the data base, configure routes, and open server */
goodTimesDB.init().then((db) => { goodTimesDB.init().then((db) => {
console.log('DB connected. Configuring routes.'); console.log('DB connected. Configuring routes.');
app.locals.db = db; app.locals.db = db;
app.set('basePath', basePath); app.set('basePath', basePath);
app.use(`${basePath}api/v1/groups`, require('./routes/groups')); app.use(`${basePath}api/v1/groups`, require('./routes/groups'));
app.use(`${basePath}api/v1/users`, require('./routes/users')); app.use(`${basePath}api/v1/users`, require('./routes/users'));
/* Error handler and catch for 404 */
app.use(methodOverride());
app.use((err, req, res, next) => {
console.log('CSRF debug: ', {
token: req.header('CSRF-Token'),
csrf: req.csrfToken(),
method: req.method
});
console.error(err);
res.status(err.status || 500).json({
message: err.message,
error: {}
});
});
}).then(() => { }).then(() => {
const server = http.createServer(app), const server = http.createServer(app),
serverConfig = config.get('server'); serverConfig = config.get('server');

126
server/package-lock.json generated
View File

@ -18,9 +18,11 @@
"csurf": "^1.11.0", "csurf": "^1.11.0",
"express": "^4.17.3", "express": "^4.17.3",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"express-session-sqlite": "^2.0.10",
"express-ws": "^5.0.2", "express-ws": "^5.0.2",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"method-override": "^3.0.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
@ -31,7 +33,7 @@
"pluralize": "^8.0.0", "pluralize": "^8.0.0",
"random-words": "^1.1.2", "random-words": "^1.1.2",
"sequelize": "^5.21.6", "sequelize": "^5.21.6",
"sqlite3": "^4.1.1", "sqlite3": "^4.2.0",
"typeface-roboto": "0.0.75", "typeface-roboto": "0.0.75",
"ws": "^8.5.0" "ws": "^8.5.0"
}, },
@ -1135,6 +1137,37 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/express-session-sqlite": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/express-session-sqlite/-/express-session-sqlite-2.0.10.tgz",
"integrity": "sha512-VBNvSlVUqAHHYU4Cca4Q1waJe1CeW2VFlW/PDtGY/cyJUV5Zy+qkN4A18SNvNR//SDZO+Pc3qd/AgVVQw2/W2Q==",
"dependencies": {
"debug": "^4.2.0",
"sql-template-strings": "^2.2.2",
"sqlite": "^4.0.14"
}
},
"node_modules/express-session-sqlite/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/express-session-sqlite/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/express-ws": { "node_modules/express-ws": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz",
@ -1990,6 +2023,28 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
}, },
"node_modules/method-override": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz",
"integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==",
"dependencies": {
"debug": "3.1.0",
"methods": "~1.1.2",
"parseurl": "~1.3.2",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/method-override/node_modules/debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/methods": { "node_modules/methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -3003,6 +3058,19 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/sql-template-strings": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/sql-template-strings/-/sql-template-strings-2.2.2.tgz",
"integrity": "sha1-PxFQiiWt384hejBCqdMAwxk7lv8=",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/sqlite": {
"version": "4.0.25",
"resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.0.25.tgz",
"integrity": "sha512-gqCEcLF8FOTeW/na3SRYWLQkw2jZXgVj1DdgRJbm0jvrhnUgBIuNDUUm649AnBNDNHhI5XskwT8dvc8vearRLQ=="
},
"node_modules/sqlite3": { "node_modules/sqlite3": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz",
@ -4330,6 +4398,31 @@
"uid-safe": "~2.1.5" "uid-safe": "~2.1.5"
} }
}, },
"express-session-sqlite": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/express-session-sqlite/-/express-session-sqlite-2.0.10.tgz",
"integrity": "sha512-VBNvSlVUqAHHYU4Cca4Q1waJe1CeW2VFlW/PDtGY/cyJUV5Zy+qkN4A18SNvNR//SDZO+Pc3qd/AgVVQw2/W2Q==",
"requires": {
"debug": "^4.2.0",
"sql-template-strings": "^2.2.2",
"sqlite": "^4.0.14"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"express-ws": { "express-ws": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz",
@ -4939,6 +5032,27 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
}, },
"method-override": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz",
"integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==",
"requires": {
"debug": "3.1.0",
"methods": "~1.1.2",
"parseurl": "~1.3.2",
"vary": "~1.1.2"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
}
}
},
"methods": { "methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -5728,6 +5842,16 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}, },
"sql-template-strings": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/sql-template-strings/-/sql-template-strings-2.2.2.tgz",
"integrity": "sha1-PxFQiiWt384hejBCqdMAwxk7lv8="
},
"sqlite": {
"version": "4.0.25",
"resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.0.25.tgz",
"integrity": "sha512-gqCEcLF8FOTeW/na3SRYWLQkw2jZXgVj1DdgRJbm0jvrhnUgBIuNDUUm649AnBNDNHhI5XskwT8dvc8vearRLQ=="
},
"sqlite3": { "sqlite3": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz",

View File

@ -18,9 +18,11 @@
"csurf": "^1.11.0", "csurf": "^1.11.0",
"express": "^4.17.3", "express": "^4.17.3",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"express-session-sqlite": "^2.0.10",
"express-ws": "^5.0.2", "express-ws": "^5.0.2",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"method-override": "^3.0.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
@ -31,7 +33,7 @@
"pluralize": "^8.0.0", "pluralize": "^8.0.0",
"random-words": "^1.1.2", "random-words": "^1.1.2",
"sequelize": "^5.21.6", "sequelize": "^5.21.6",
"sqlite3": "^4.1.1", "sqlite3": "^4.2.0",
"typeface-roboto": "0.0.75", "typeface-roboto": "0.0.75",
"ws": "^8.5.0" "ws": "^8.5.0"
}, },

View File

@ -2,22 +2,6 @@ const express = require('express'),
router = express.Router(), router = express.Router(),
crypto = require('crypto'); crypto = require('crypto');
/* Simple NO-OP to set session cookie so user-id can use it as the
* index */
router.get('/', (req, res/*, next*/) => {
let userId;
if (!req.cookies.user) {
userId = crypto.randomBytes(16).toString('hex');
res.cookie('user', userId);
} else {
userId = req.cookies.user;
}
console.log(`[${userId.substring(0, 8)}]: Browser hand-shake achieved.`);
return res.status(200).send({ user: userId });
});
router.get('/', async (req, res/*, next*/) => { router.get('/', async (req, res/*, next*/) => {
console.log('GET /groups/', req.session.userId); console.log('GET /groups/', req.session.userId);
return res.status(200).send( return res.status(200).send(

View File

@ -8,17 +8,18 @@ const express = require('express'),
const router = express.Router(); const router = express.Router();
const autoAuthenticate = 1; const autoAuthenticate = 1;
router.get('/', function(req, res/*, next*/) { router.get('/', (req, res/*, next*/) => {
console.log('GET /users/'); console.log('GET /users/');
return getSessionUser(req).then((user) => { return getSessionUser(req).then((user) => {
if (typeof user === 'string') {
return res.status(403).send({ message: user });
}
return res.status(200).send(user); return res.status(200).send(user);
}).catch((error) => {
console.log('User not logged in: ' + error);
return res.status(200).send({});
}); });
}); });
router.put('/password', function(req, res) { router.put('/password', async (req, res) => {
console.log('/users/password'); console.log('/users/password');
const db = req.app.locals.db; const db = req.app.locals.db;
@ -28,14 +29,19 @@ router.put('/password', function(req, res) {
}; };
if (!changes.currentPassword || !changes.newPassword) { if (!changes.currentPassword || !changes.newPassword) {
return res.status(400).send('Missing current password and/or new password.'); return res.status(400).send(
'Missing current password and/or new password.');
} }
if (changes.currentPassword == changes.newPassword) { if (changes.currentPassword == changes.newPassword) {
return res.status(400).send('Attempt to set new password to current password.'); return res.status(400).send(
'Attempt to set new password to current password.');
} }
return getSessionUser(req).then(function(user) { const user = await getSessionUser(req);
if (typeof user === 'string') {
return res.status(403).send({ message: user });
}
return db.sequelize.query('SELECT id FROM users ' + return db.sequelize.query('SELECT id FROM users ' +
'WHERE uid=:username AND password=:password', { 'WHERE uid=:username AND password=:password', {
replacements: { replacements: {
@ -49,7 +55,6 @@ router.put('/password', function(req, res) {
return null; return null;
} }
return user; return user;
});
}).then(function(user) { }).then(function(user) {
if (!user) { if (!user) {
console.log('Invalid password'); console.log('Invalid password');
@ -74,8 +79,9 @@ router.put('/password', function(req, res) {
}); });
router.get('/csrf', (req, res) => { router.get('/csrf', (req, res) => {
console.log('/users/csrf'); const token = req.csrfToken();
res.json({ csrfToken: req.csrfToken() }); console.log('/users/csrf', token);
res.json({ csrfToken: token });
}); });
router.post('/signup', function(req, res) { router.post('/signup', function(req, res) {
@ -141,6 +147,9 @@ router.post('/signup', function(req, res) {
req.session.userId = metadata.lastID; req.session.userId = metadata.lastID;
} }
return getSessionUser(req).then(function(user) { return getSessionUser(req).then(function(user) {
if (typeof user === 'string') {
return res.status(403).send({ message: user });
}
res.status(200).send(user); res.status(200).send(user);
user.id = req.session.userId; user.id = req.session.userId;
return sendVerifyMail(db, req, user); return sendVerifyMail(db, req, user);
@ -151,44 +160,40 @@ router.post('/signup', function(req, res) {
}); });
}); });
const getSessionUser = function(req) { const getSessionUser = async (req) => {
const db = req.app.locals.db; const db = req.app.locals.db;
return Promise.resolve().then(function() {
console.log(req.session);
if (!req.session || !req.session.userId) { if (!req.session || !req.session.userId) {
throw 'Unauthorized. You must be logged in.'; return 'Unauthorized. You must be logged in.';
} }
let query = 'SELECT ' + let query = 'SELECT ' +
'uid AS username,firstName,familyName,mailVerified,authenticated,memberSince,email,md5 ' + 'uid AS username,firstName,familyName,mailVerified,authenticated,memberSince,email,md5 ' +
'FROM users WHERE id=:id'; 'FROM users WHERE id=:id';
return db.sequelize.query(query, { const results = await db.sequelize.query(query, {
replacements: { replacements: {
id: req.session.userId id: req.session.userId
}, },
type: db.Sequelize.QueryTypes.SELECT, type: db.Sequelize.QueryTypes.SELECT,
raw: true raw: true
}).then(function(results) { });
if (results.length != 1) { if (results.length != 1) {
throw 'Invalid account.'; return 'Invalid account.';
} }
let user = results[0]; const user = results[0];
if (!user.mailVerified) { if (!user.mailVerified) {
user.restriction = user.restriction || 'Email address not verified.'; user.restriction = user.restriction || 'Email address not verified.';
return user; } else if (!user.authenticated) {
}
if (!user.authenticated) {
user.restriction = user.restriction || 'Accout not authorized.'; user.restriction = user.restriction || 'Accout not authorized.';
return user;
} }
return user; /* Strip out any fields that shouldn't be there.
}); * The allowed fields are: */
}).then(function(user) { const allowed = [
/* Strip out any fields that shouldn't be there. The allowed fields are: */
let allowed = [
'maintainer', 'username', 'firstName', 'familyName', 'mailVerified', 'authenticated', 'name', 'email', 'restriction', 'md5' 'maintainer', 'username', 'firstName', 'familyName', 'mailVerified', 'authenticated', 'name', 'email', 'restriction', 'md5'
]; ];
for (let field in user) { for (let field in user) {
@ -197,7 +202,6 @@ const getSessionUser = function(req) {
} }
} }
return user; return user;
});
}; };
router.post('/verify-email', async (req, res) => { router.post('/verify-email', async (req, res) => {
@ -254,13 +258,16 @@ router.post('/verify-email', async (req, res) => {
req.session.userId = user.id; req.session.userId = user.id;
}).then(() => { }).then(() => {
return getSessionUser(req).then((user) => { return getSessionUser(req).then((user) => {
if (typeof user === 'string') {
return res.status(403).send({ message: user });
}
return res.status(200).send(user); return res.status(200).send(user);
}); });
}); });
} }
}); });
router.post('/signin', function(req, res) { router.post('/signin', (req, res) => {
console.log('/users/signin'); console.log('/users/signin');
const db = req.app.locals.db; const db = req.app.locals.db;
@ -310,12 +317,12 @@ router.post('/signin', function(req, res) {
console.log(message); console.log(message);
} }
return getSessionUser(req).then(function(user) { return getSessionUser(req).then((user) => {
if (typeof user === 'string') {
return res.status(403).send({ message: user });
}
return res.status(200).send(user); return res.status(200).send(user);
}); });
}).catch(function(error) {
console.log(error);
return res.status(403).send(error);
}); });
}); });