Skip to content

Commit

Permalink
feat: add creating users via API
Browse files Browse the repository at this point in the history
Merge branch '0.14.0/create-new-user-via-api' into 0.14.0/stage
  • Loading branch information
tycrek committed Dec 25, 2022
2 parents d7b57e5 + 371e5fc commit 76fdaaf
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
11 changes: 4 additions & 7 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,6 @@ For HTTPS support, you must configure a reverse proxy. I recommend Caddy but any
[Caddy]: https://caddyserver.com/
[my tutorial]: https://old.jmoore.dev/tutorials/2021/03/caddy-express-reverse-proxy/

## Generating new tokens

If you need to generate a new token at any time, run `npm run new-token <username>`. This will **automatically** load the new token so there is no need to restart ass. Username field is optional; if left blank, a random username will be created.

## Cloudflare users

In your Cloudflare DNS dashboard, set your domain/subdomain to **DNS Only** if you experience issues with **Proxied**.
Expand Down Expand Up @@ -355,7 +351,7 @@ S3 servers are generally very fast & have very good uptime, though this will dep

The user system was overhauled in v0.14.0 to allow more features and flexibility. New fields on users include `admin`, `passhash`, `unid`, and `meta` (these will be documented more once the system is finalized).

ass will automatically convert your old `auth.json` to the new format. **Always backup your `auth.json` and `data.json` before updating**. By default, the original user (named `ass`) will be marked as an admin. Adding new users via `npm run new-token <username>` should work as expected, though you'll need to re-launch ass to load the new file.
ass will automatically convert your old `auth.json` to the new format. **Always backup your `auth.json` and `data.json` before updating**. By default, the original user (named `ass`) will be marked as an admin. Adding new users via `npm run new-token <username>` is currently not supported. Please see the API below for how to add a new user via the API.

**Things still borked:**

Expand All @@ -382,8 +378,10 @@ Other things to note:
| **`GET /user/all`** | Returns a list of all users | Yes |
| **`GET /user/self`** | Returns the current user | No |
| **`GET /user/token/:token`** | Returns the user with the given token | No |
| **`POST /user/reset`** | Resets the current user's **password** (token resets coming soon) | No |
| **`POST /user/reset`** | Resets the current user's **password** (token resets coming soon). Request body must be a JSON object including `username` and `password`. | No |
| **`GET /user/:id`** | Returns the user with the given ID | Yes |
| **`POST /user/new`** | Creates a new user. Request body must be a JSON object including `username` and `password`. You may optionally include `admin` (boolean) or `meta` (object). Returns 400 if fails. | Yes |


## Custom frontends - OUTDATED

Expand Down Expand Up @@ -445,7 +443,6 @@ ass has a number of pre-made npm scripts for you to use. **All** of these script
| `setup` | Starts the easy setup process. Should be run after any updates that introduce new config options. |
| `metrics` | Runs the metrics script. This is a simple script that outputs basic resource statistics. |
| `purge` | Purges all uploads & data associated with them. This does **not** delete any users, however. |
| `new-token` | Generates a new API token. Accepts one parameter for specifying a username, like `npm run new-token <username>`. ass automatically detects the new token & reloads it, so there's no need to restart the server. |
| `engine-check` | Ensures your environment meets the minimum Node & npm version requirements. |

[`FORCE_COLOR`]: https://nodejs.org/dist/latest-v16.x/docs/api/cli.html#cli_force_color_1_2_3
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"start": "node dist/ass.js",
"setup": "node dist/setup.js",
"metrics": "node dist/metrics.js",
"new-token": "node dist/generators/token.js",
"engine-check": "node dist/checkEngine.js",
"prestart": "npm run engine-check",
"presetup": "npm run engine-check",
Expand Down
8 changes: 4 additions & 4 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ const migrate = (authFileName = 'auth.json'): Promise<Users> => new Promise(asyn
/**
* This is a WIP
*/
export const createNewUser = (username: string, password: string, admin: boolean, meta?: { [key: string]: User }): Promise<User> => new Promise(async (resolve, reject) => {

// todo: finish this
export const createNewUser = (username: string, password: string, admin: boolean, meta?: { [key: string]: any }): Promise<User> => new Promise(async (resolve, reject) => {

// Create a new user object
const newUser: User = {
Expand All @@ -115,7 +113,9 @@ export const createNewUser = (username: string, password: string, admin: boolean
const authPath = path('auth.json');
const authData = fs.readJsonSync(authPath) as Users;
authData.users.push(newUser);
fs.writeJson(authPath, authData, { spaces: '\t' });
fs.writeJson(authPath, authData, { spaces: '\t' })
.then(() => resolve(newUser))
.catch(reject);
});

export const setUserPassword = (unid: string, password: string): Promise<User> => new Promise(async (resolve, reject) => {
Expand Down
20 changes: 19 additions & 1 deletion src/routers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import { Router, Request, Response, NextFunction } from 'express';
import { findFromToken, setUserPassword, users } from '../auth';
import { findFromToken, setUserPassword, users, createNewUser } from '../auth';
import { log } from '../utils';
import { data } from '../data';
import { User } from '../types/auth';

Expand Down Expand Up @@ -56,6 +57,23 @@ function buildUserRouter() {
.catch(() => res.sendStatus(500));
});

// Create a new user
// Admin only
userRouter.post('/new', adminAuthMiddleware, (req: Request, res: Response) => {
const username: string | undefined = req.body.username;
const password: string | undefined = req.body.password;
const admin = req.body.admin ?? false;
const meta: any = req.body.meta ?? {};

// Block if username or password is empty, or if username is already taken
if (username == null || username.length === 0 || password == null || password.length == 0 || users.find(user => user.username === username))
return res.sendStatus(400);

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

// Get a user (must be last as it's a catch-all)
// Admin only
userRouter.get('/:id', adminAuthMiddleware, (req: Request, res: Response) =>
Expand Down

0 comments on commit 76fdaaf

Please # to comment.