Skip to content

Commit

Permalink
feat: added meta set/del, user del, and get all users to API
Browse files Browse the repository at this point in the history
Merge branch '0.14.1/mod-del-users' into 0.14.1/stage
  • Loading branch information
tycrek committed Dec 26, 2022
2 parents 47fa061 + 30505f8 commit 5c89d67
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 3 deletions.
75 changes: 75 additions & 0 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,81 @@ export const setUserPassword = (unid: string, password: string): Promise<User> =
.catch(reject);
});

/**
* Deletes a user account
* @since v0.14.1
*/
export const deleteUser = (unid: string): Promise<void> => new Promise((resolve, reject) => {

// Find the user
const user = users.find((user) => user.unid === unid);
if (!user) return reject(new Error('User not found'));

// Remove the user from the users map
users.splice(users.indexOf(user), 1);

// Save the new user to auth.json
const authPath = path('auth.json');
const authData = fs.readJsonSync(authPath) as Users;
const userIndex = authData.users.findIndex((user) => user.unid === unid);
authData.users.splice(userIndex, 1);
fs.writeJson(authPath, authData, { spaces: '\t' })
.then(() => resolve())
.catch(reject);
});

/**
* Sets a meta value for a user
* @since v0.14.1
*/
export const setUserMeta = (unid: string, key: string, value: any, force = false): Promise<User> => new Promise((resolve, reject) => {

// Find the user
const user = users.find((user) => user.unid === unid);
if (!user) return reject(new Error('User not found'));

// Set the meta value
if (user.meta[key] && !force) return reject(new Error('Meta key already exists'));

user.meta[key] = value;

// Save the new user to auth.json
const authPath = path('auth.json');
const authData = fs.readJsonSync(authPath) as Users;
const userIndex = authData.users.findIndex((user) => user.unid === unid);
authData.users[userIndex] = user;
fs.writeJson(authPath, authData, { spaces: '\t' })
.then(() => log.info('Set meta value for', user.unid, `${key}=${value}`))
.then(() => resolve(user))
.catch(reject);
});

/**
* Deletes a meta value for a user
* @since v0.14.1
*/
export const deleteUserMeta = (unid: string, key: string): Promise<User> => new Promise((resolve, reject) => {

// Find the user
const user = users.find((user) => user.unid === unid);
if (!user) return reject(new Error('User not found'));

// Delete the meta value
if (!user.meta[key]) return reject(new Error('Meta key does not exist'));

delete user.meta[key];

// Save the new user to auth.json
const authPath = path('auth.json');
const authData = fs.readJsonSync(authPath) as Users;
const userIndex = authData.users.findIndex((user) => user.unid === unid);
authData.users[userIndex] = user;
fs.writeJson(authPath, authData, { spaces: '\t' })
.then(() => log.info('Deleted meta value for', user.unid, key))
.then(() => resolve(user))
.catch(reject);
});

/**
* Called by ass.ts on startup
* @since v0.14.0
Expand Down
63 changes: 60 additions & 3 deletions src/routers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { Router, Request, Response, NextFunction } from 'express';
import { findFromToken, setUserPassword, users, createNewUser, verifyCliKey } from '../auth';
import { findFromToken, setUserPassword, users, createNewUser, deleteUser, setUserMeta, deleteUserMeta, verifyCliKey } from '../auth';
import { log } from '../utils';
import { data } from '../data';
import { User } from '../types/auth';
Expand All @@ -15,6 +15,19 @@ import { User } from '../types/auth';
*/
const RouterApi = Router();

/**
* Logs an error and sends a 500 (404 if 'User not found' error)
* @since v0.14.1
*/
const errorHandler = (res: Response, err: Error | any) => {
log.error(err);
switch (err.message) {
case 'User not found': return res.sendStatus(404);
case 'Meta key already exists': return res.sendStatus(409);
default: return res.sendStatus(500);
}
};

/**
* Token authentication middleware for Admins
* @since v0.14.0
Expand Down Expand Up @@ -56,7 +69,7 @@ function buildUserRouter() {

setUserPassword(id, newPassword)
.then(() => res.sendStatus(200))
.catch((err) => (log.error(err), res.sendStatus(500)));
.catch((err) => errorHandler(res, err));
});

// Create a new user
Expand All @@ -73,14 +86,58 @@ function buildUserRouter() {

createNewUser(username, password, admin, meta)
.then((user) => res.send(user))
.catch((err) => (log.error(err), res.sendStatus(500)));
.catch((err) => errorHandler(res, err));
});

// Get all users
// Admin only
userRouter.get('/all', adminAuthMiddleware, (req: Request, res: Response) => res.json(users));

// Get a user (must be last as it's a catch-all)
// Admin only
userRouter.get('/:id', adminAuthMiddleware, (req: Request, res: Response) =>
userFinder(res, users.find(user => user.unid === req.params.id || user.username === req.params.id)));

// Delete a user
// Admin only
userRouter.delete('/:id', adminAuthMiddleware, (req: Request, res: Response) => {
const id = req.params.id;

deleteUser(id)
.then(() => res.sendStatus(200))
.catch((err) => errorHandler(res, err));
});

// Update a user meta key/value (/meta can be after /:id because they are not HTTP GET)
// Admin only
userRouter.put('/meta/:id', adminAuthMiddleware, (req: Request, res: Response) => {
const id = req.params.id;
const key: string | undefined = req.body.key;
const value: any = req.body.value;
const force = req.body.force ?? false;

if (key == null || key.length === 0 || value == null || value.length === 0)
return res.sendStatus(400);

setUserMeta(id, key, value, force)
.then(() => res.sendStatus(200))
.catch((err) => errorHandler(res, err));
});

// Delete a user meta key
// Admin only
userRouter.delete('/meta/:id', adminAuthMiddleware, (req: Request, res: Response) => {
const id = req.params.id;
const key: string | undefined = req.body.key;

if (key == null || key.length === 0)
return res.sendStatus(400);

deleteUserMeta(id, key)
.then(() => res.sendStatus(200))
.catch((err) => errorHandler(res, err));
});

return userRouter;
}

Expand Down

0 comments on commit 5c89d67

Please # to comment.