Skip to content
Snippets Groups Projects
Commit 8c86ad6c authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Added options to update user data

parent ff85a180
No related branches found
No related tags found
No related merge requests found
......@@ -10,9 +10,54 @@ import { getPublicKey, getPrivateKey } from '../keys';
const auth = express();
export interface Token {
id: string;
}
export async function tokenVerification(req: Request, _res: Response, next: NextFunction) {
const header = req.headers?.authorization;
let token: string | null = null;
if (header) {
const bearer = header.split(' ');
token = bearer[1];
} else if (!req.body) {
req.body = {};
} else if (req.body.token) {
token = req.body.token;
}
if (token) {
try {
const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] });
req.body.token = decoded;
} catch (err) {
delete req.body.token;
}
next();
} else {
next();
}
}
export function requireVerification(req: Request, res: Response, next: NextFunction) {
if (req.body.token) {
next();
} else {
res.status(403).json({
status: 'error',
message: 'authentication failed',
});
}
}
async function generateToken(token: Token) {
return asyncify(sign, token, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 });
}
interface RegisterBody {
username: string;
password: string;
email?: string;
realname?: string;
}
auth.post('/register', async (req, res) => {
......@@ -21,13 +66,17 @@ auth.post('/register', async (req, res) => {
const id = uuid();
const passwdHash = await hash(body.password, 10);
try {
const token = await generateToken({ id: id });
await database('users').insert({
id: id,
user_name: body.username,
passwd_hash: passwdHash
passwd_hash: passwdHash,
email: body.email ?? null,
real_name: body.realname ?? null,
});
res.status(200).json({
status: 'success',
token: token,
});
} catch (e) {
// Fails if unique constraint for username is not met
......@@ -56,9 +105,7 @@ auth.post('/token', async (req, res) => {
const user = await database('users').where({ user_name: body.username });
if (user.length === 1) {
if (await compare(body.password, user[0].passwd_hash)) {
const token = await asyncify(sign, {
id: user[0].id,
}, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 });
const token = await generateToken({ id: user[0].id });
res.status(200).json({
status: 'success',
token: token,
......@@ -76,7 +123,6 @@ auth.post('/token', async (req, res) => {
});
}
} catch (e) {
console.error(e);
res.status(400).json({
status: 'error',
message: 'failed to acquire token',
......@@ -109,40 +155,69 @@ auth.get("/extend", async function (req, res) {
}
});
export async function tokenVerification(req: Request, _res: Response, next: NextFunction) {
const header = req.headers?.authorization;
let token: string | null = null;
if (header) {
const bearer = header.split(' ');
token = bearer[1];
} else if (!req.body) {
req.body = {};
} else if (req.body.token) {
token = req.body.token;
}
if (token) {
interface UsernameBody {
token: Token;
username: string;
}
auth.put("/username", async function (req, res) {
if (isOfType<UsernameBody>(req.body, [['username', 'string']])) {
const body: UsernameBody = req.body;
try {
const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] });
req.body.token = decoded;
} catch (err) {
delete req.body.token;
await database('users').update({
user_name: body.username,
}).where({
id: body.token.id,
});
res.status(200).json({
status: 'success',
});
} catch (e) {
// Fails if unique constraint for username is not met
res.status(400).json({
status: 'error',
message: 'failed to update username',
});
}
next();
} else {
next();
res.status(400).json({
status: 'error',
message: 'missing request fields',
});
}
});
interface PasswordBody {
token: Token;
password: string;
}
export function requireVerification(req: Request, res: Response, next: NextFunction) {
if (req.body.token) {
next();
auth.put("/password", async function (req, res) {
if (isOfType<PasswordBody>(req.body, [['password', 'string']])) {
const body: PasswordBody = req.body;
try {
const passwdHash = await hash(body.password, 10);
await database('users').update({
passwd_hash: passwdHash
}).where({
id: body.token.id,
});
res.status(200).json({
status: 'success',
});
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed to update password',
});
}
} else {
res.status(403).json({
res.status(400).json({
status: 'error',
message: 'authentication failed',
message: 'missing request fields',
});
}
}
});
export default auth;
import express from 'express';
import { validate } from 'uuid';
import database from '../database';
import { requireVerification } from './auth';
import { isOfType } from '../util';
import { requireVerification, Token } from './auth';
const user = express();
......@@ -12,8 +14,6 @@ user.get('/name/:username', async (req, res) => {
.select({
id: 'id',
username: 'user_name',
email: 'email',
realname: 'real_name',
})
.where({ username: req.params.username });
if (user.length === 1) {
......@@ -66,4 +66,83 @@ user.get('/', async (req, res) => {
}
});
interface UserUpdateBody {
token: Token;
realname?: string;
email?: string;
}
user.put('/', async (req, res) => {
if (
isOfType<UserUpdateBody>(req.body, [['realname', 'string']])
|| isOfType<UserUpdateBody>(req.body, [['email', 'string']])
) {
try {
const updated = await database('users')
.update({
email: req.body.email,
real_name: req.body.realname,
})
.where({ id: req.body.token.id });
if (updated === 1) {
res.status(200).json({
status: 'success',
});
} else {
res.status(404).json({
status: 'error',
message: 'user not found',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed to update user',
});
}
} else {
res.status(400).json({
status: 'error',
message: 'missing request fields',
});
}
});
user.get('/:uuid', async (req, res) => {
try {
const id = req.params.uuid;
if (validate(id)) {
const user = await database('users')
.select({
id: 'id',
username: 'user_name',
email: 'email',
realname: 'real_name',
})
.where({ id: id });
if (user.length === 1) {
res.status(200).json({
status: 'success',
user: user[0],
});
} else {
res.status(404).json({
status: 'error',
message: 'user not found',
});
}
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed get user',
});
}
});
export default user;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment