Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit 812eb4f

Browse files
✨ Endpoints for admin interface
1 parent 3309011 commit 812eb4f

File tree

6 files changed

+61
-4
lines changed

6 files changed

+61
-4
lines changed

src/crud/organization.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,10 @@ export const deleteOrganization = async (id: number) => {
6262
deleteItemFromCache(CacheCategories.ORGANIZATION, id);
6363
return await query("DELETE FROM organizations WHERE id = ?", [id]);
6464
};
65+
66+
/*
67+
* Get all organizations
68+
*/
69+
export const getAllOrganizations = async () => {
70+
return <Organization[]>await query("SELECT * FROM organizations");
71+
};

src/crud/user.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import md5 from "md5";
2626
/**
2727
* Get a list of all users
2828
*/
29-
export const listAllUsers = async () => {
29+
export const getAllUsers = async () => {
3030
return <User[]>await query("SELECT * from users");
3131
};
3232

src/helpers/authorization.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,25 @@ const canUserMembership = async (
138138
return allowed;
139139
};
140140

141+
/**
142+
* Whether a user can perform an action for the backend
143+
*/
144+
const canUserGeneral = async (user: User, action: Authorizations) => {
145+
// A super user can do anything
146+
if (user.role == UserRole.ADMIN) return true;
147+
148+
return false;
149+
};
150+
141151
/**
142152
* Whether a user has authorization to perform an action
143153
* @param ipAddress IP address for the new location
144154
*/
145155
export const can = async (
146156
user: User | number,
147157
action: Authorizations,
148-
targetType: "user" | "organization" | "membership",
149-
target: User | Organization | Membership | number
158+
targetType: "user" | "organization" | "membership" | "general",
159+
target?: User | Organization | Membership | number
150160
) => {
151161
let userObject;
152162
if (typeof user === "number") {
@@ -174,9 +184,11 @@ export const can = async (
174184
return await canUserOrganization(userObject, action, <Organization>(
175185
targetObject
176186
));
177-
} else {
187+
} else if (targetType === "membership") {
178188
return await canUserMembership(userObject, action, <Membership>(
179189
targetObject
180190
));
191+
} else {
192+
return await canUserGeneral(userObject, action);
181193
}
182194
};

src/rest/admin.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { can } from "../helpers/authorization";
2+
import { Authorizations, ErrorCode } from "../interfaces/enum";
3+
import { getAllOrganizations } from "../crud/organization";
4+
import { getAllUsers } from "../crud/user";
5+
6+
export const getAllOrganizationForUser = async (tokenUserId: number) => {
7+
if (await can(tokenUserId, Authorizations.READ, "general"))
8+
return await getAllOrganizations();
9+
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
10+
};
11+
12+
export const getAllUsersForUser = async (tokenUserId: number) => {
13+
if (await can(tokenUserId, Authorizations.READ, "general"))
14+
return await getAllUsers();
15+
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
16+
};

src/routes/admin.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Request, Response } from "express";
2+
import { ErrorCode } from "../interfaces/enum";
3+
import { getAllOrganizationForUser, getAllUsersForUser } from "../rest/admin";
4+
5+
export const routeAdminOrganizations = async (req: Request, res: Response) => {
6+
const userId = res.locals.token.id;
7+
if (!userId) throw new Error(ErrorCode.MISSING_FIELD);
8+
res.json(await getAllOrganizationForUser(userId));
9+
};
10+
11+
export const routeAdminUsers = async (req: Request, res: Response) => {
12+
const userId = res.locals.token.id;
13+
if (!userId) throw new Error(ErrorCode.MISSING_FIELD);
14+
res.json(await getAllUsersForUser(userId));
15+
};

src/routes/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
routeMembershipDelete,
4545
routeMembershipUpdate
4646
} from "./membership";
47+
import { routeAdminUsers, routeAdminOrganizations } from "./admin";
4748

4849
export const router = (app: Application) => {
4950
app.get("/", (req, res) => res.json({ hello: "world" }));
@@ -53,6 +54,7 @@ export const router = (app: Application) => {
5354
routesEmail(app);
5455
routesOrganization(app);
5556
routesMembership(app);
57+
routesAdmin(app);
5658

5759
return app;
5860
};
@@ -167,3 +169,8 @@ const routesMembership = (app: Application) => {
167169
asyncHandler(routeMembershipDelete)
168170
);
169171
};
172+
173+
const routesAdmin = (app: Application) => {
174+
app.get("/users", authHandler, asyncHandler(routeAdminUsers));
175+
app.get("/organizations", authHandler, asyncHandler(routeAdminOrganizations));
176+
};

0 commit comments

Comments
 (0)