From 894d773e8c93a91bd0f2c72fcdb327ac2f96686a Mon Sep 17 00:00:00 2001 From: tycrek Date: Sun, 25 Dec 2022 22:53:52 -0700 Subject: [PATCH] feat: added setting and deleting user meta keys via API --- src/auth.ts | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/routers/api.ts | 31 +++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 611cd3c..45dfea3 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -187,6 +187,58 @@ export const deleteUser = (unid: string): Promise => new Promise((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 => 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 => 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 diff --git a/src/routers/api.ts b/src/routers/api.ts index dd26867..74b83ca 100644 --- a/src/routers/api.ts +++ b/src/routers/api.ts @@ -5,7 +5,7 @@ */ import { Router, Request, Response, NextFunction } from 'express'; -import { findFromToken, setUserPassword, users, createNewUser, deleteUser, 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'; @@ -102,11 +102,34 @@ function buildUserRouter() { .catch((err) => errorHandler(res, err)); }); - // Update a user + // Update a user meta key/value // Admin only - userRouter.put('/:id', adminAuthMiddleware, (req: Request, res: Response) => { + userRouter.put('/meta/:id', adminAuthMiddleware, (req: Request, res: Response) => { const id = req.params.id; - //WIP + 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;