list roles, make sidebar component, responsive mobile settings menu selector

This commit is contained in:
Milo Schwartz
2024-11-09 00:08:17 -05:00
parent 9c2e481d2b
commit bb17d30c9e
25 changed files with 733 additions and 207 deletions

View File

@@ -7,7 +7,7 @@ import HttpCode from "@server/types/HttpCode";
export enum ActionsEnum {
createOrg = "createOrg",
deleteOrg = "deleteOrg",
// deleteOrg = "deleteOrg",
getOrg = "getOrg",
updateOrg = "updateOrg",
createSite = "createSite",
@@ -39,16 +39,16 @@ export enum ActionsEnum {
addRoleResource = "addRoleResource",
removeRoleResource = "removeRoleResource",
removeRoleSite = "removeRoleSite",
addRoleAction = "addRoleAction",
removeRoleAction = "removeRoleAction",
// addRoleAction = "addRoleAction",
// removeRoleAction = "removeRoleAction",
listRoleSites = "listRoleSites",
listRoleResources = "listRoleResources",
listRoleActions = "listRoleActions",
addUserRole = "addUserRole",
addUserResource = "addUserResource",
addUserSite = "addUserSite",
addUserAction = "addUserAction",
removeUserAction = "removeUserAction",
// addUserAction = "addUserAction",
// removeUserAction = "removeUserAction",
removeUserResource = "removeUserResource",
removeUserSite = "removeUserSite",
}

View File

@@ -56,14 +56,13 @@ export async function ensureActions() {
}
export async function createAdminRole(orgId: string) {
// Create the Default role if it doesn't exist
const [insertedRole] = await db
.insert(roles)
.values({
orgId,
isAdmin: true,
name: "Admin",
description: "Admin role most permissions",
description: "Admin role with the most permissions",
})
.returning({ roleId: roles.roleId })
.execute();

View File

@@ -53,12 +53,12 @@ authenticated.post(
verifyUserHasAction(ActionsEnum.updateOrg),
org.updateOrg
);
// authenticated.delete(
// "/org/:orgId",
// verifyOrgAccess,
// verifyUserIsOrgOwner,
// org.deleteOrg
// );
authenticated.delete(
"/org/:orgId",
verifyOrgAccess,
verifyUserIsOrgOwner,
org.deleteOrg
);
authenticated.put(
"/org/:orgId/site",
@@ -192,13 +192,13 @@ authenticated.delete(
target.deleteTarget
);
// authenticated.put(
// "/org/:orgId/role",
// verifyOrgAccess,
// verifyAdmin,
// verifyUserHasAction(ActionsEnum.createRole),
// role.createRole
// );
authenticated.put(
"/org/:orgId/role",
verifyOrgAccess,
verifyAdmin,
verifyUserHasAction(ActionsEnum.createRole),
role.createRole
);
authenticated.get(
"/org/:orgId/roles",
verifyOrgAccess,

View File

@@ -45,13 +45,6 @@ export async function createOrg(
);
}
// TODO: we cant do this when they create an org because they are not in an org yet... maybe we need to make the org id optional on the userActions table
// Check if the user has permission
// const hasPermission = await checkUserActionPermission(ActionsEnum.createOrg, req);
// if (!hasPermission) {
// return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to perform this action'));
// }
const { orgId, name } = parsedBody.data;
// make sure the orgId is unique
@@ -113,10 +106,7 @@ export async function createOrg(
} catch (error) {
logger.error(error);
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
}
}

View File

@@ -3,6 +3,7 @@ import { z } from "zod";
import { db } from "@server/db";
import {
orgs,
Resource,
resources,
roleResources,
roles,
@@ -29,6 +30,8 @@ const createResourceSchema = z.object({
subdomain: z.string().min(1).max(255).optional(),
});
export type CreateResourceResponse = Resource;
export async function createResource(
req: Request,
res: Response,
@@ -82,10 +85,8 @@ export async function createResource(
);
}
// Generate a unique resourceId
const fullDomain = `${subdomain}.${org[0].domain}`;
// Create new resource in the database
const newResource = await db
.insert(resources)
.values({
@@ -122,7 +123,7 @@ export async function createResource(
});
}
response(res, {
response<CreateResourceResponse>(res, {
data: newResource[0],
success: true,
error: false,
@@ -130,12 +131,8 @@ export async function createResource(
status: HttpCode.CREATED,
});
} catch (error) {
throw error;
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
}
}

View File

@@ -1,12 +1,14 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { roles } from "@server/db/schema";
import { orgs, Role, roleActions, roles } from "@server/db/schema";
import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { ActionsEnum } from "@server/auth/actions";
import { eq, and } from "drizzle-orm";
const createRoleParamsSchema = z.object({
orgId: z.string(),
@@ -17,6 +19,8 @@ const createRoleSchema = z.object({
description: z.string().optional(),
});
export type CreateRoleResponse = Role;
export async function createRole(
req: Request,
res: Response,
@@ -47,6 +51,25 @@ export async function createRole(
const { orgId } = parsedParams.data;
const allRoles = await db
.select({
roleId: roles.roleId,
name: roles.name,
})
.from(roles)
.leftJoin(orgs, eq(roles.orgId, orgs.orgId))
.where(and(eq(roles.name, roleData.name), eq(roles.orgId, orgId)));
// make sure name is unique
if (allRoles.length > 0) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Role with that name already exists"
)
);
}
const newRole = await db
.insert(roles)
.values({
@@ -55,7 +78,25 @@ export async function createRole(
})
.returning();
return response(res, {
// default allowed actions for a non admin role
const allowedActions: ActionsEnum[] = [
ActionsEnum.getOrg,
ActionsEnum.getResource,
ActionsEnum.listResources,
];
await db
.insert(roleActions)
.values(
allowedActions.map((action) => ({
roleId: newRole[0].roleId,
actionId: action,
orgId,
}))
)
.execute();
return response<Role>(res, {
data: newRole[0],
success: true,
error: false,

View File

@@ -79,6 +79,7 @@ export async function createSite(
subnet,
})
.returning();
const adminRole = await db
.select()
.from(roles)
@@ -104,7 +105,7 @@ export async function createSite(
});
}
// Add the peer to the exit node
// add the peer to the exit node
await addPeer(exitNodeId, {
publicKey: pubKey,
allowedIps: [],