feat: added meta set/del, user del, and get all users to API

Merge branch '0.14.1/mod-del-users' into 0.14.1/stage
pull/190/head
tycrek 1 year ago
commit 5c89d67922
No known key found for this signature in database
GPG Key ID: FF8A54DCE404885A

@ -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

@ -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';
@ -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
@ -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
@ -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;
}

Loading…
Cancel
Save