mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-08-30 12:09:54 +00:00
Add group management functionality. Includes creating, reading, updating, and deleting groups and their members.
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/3fe56e9d-2ec4-4180-9f3d-a256a9f15f1d.jpg
This commit is contained in:
+142
-1
@@ -14,9 +14,12 @@ import {
|
|||||||
insertWebhookSchema,
|
insertWebhookSchema,
|
||||||
insertDnsMetricSchema,
|
insertDnsMetricSchema,
|
||||||
insertCustomRoleSchema,
|
insertCustomRoleSchema,
|
||||||
|
insertGroupSchema,
|
||||||
|
insertGroupMemberSchema,
|
||||||
recordTypes,
|
recordTypes,
|
||||||
providerTypes,
|
providerTypes,
|
||||||
customRoles
|
customRoles,
|
||||||
|
memberTypes
|
||||||
} from "@shared/schema";
|
} from "@shared/schema";
|
||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
|
|
||||||
@@ -569,6 +572,144 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Groups
|
||||||
|
app.get("/api/groups", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const groups = await storage.getGroups();
|
||||||
|
res.json(groups);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching groups:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/groups/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id;
|
||||||
|
const group = await storage.getGroup(id);
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
return res.status(404).json({ message: "Group not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(group);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching group:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/groups/:id/members", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id;
|
||||||
|
const members = await storage.getGroupMembers(id);
|
||||||
|
res.json(members);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching group members:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/groups", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const validatedData = insertGroupSchema.parse({
|
||||||
|
...req.body,
|
||||||
|
createdBy: req.user?.id
|
||||||
|
});
|
||||||
|
const group = await storage.createGroup(validatedData);
|
||||||
|
res.status(201).json(group);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
res.status(400).json({ message: "Validation error", errors: error.errors });
|
||||||
|
} else {
|
||||||
|
console.error("Error creating group:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put("/api/groups/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id;
|
||||||
|
const validatedData = insertGroupSchema.partial().parse(req.body);
|
||||||
|
|
||||||
|
const updatedGroup = await storage.updateGroup(id, validatedData);
|
||||||
|
|
||||||
|
if (!updatedGroup) {
|
||||||
|
return res.status(404).json({ message: "Group not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(updatedGroup);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
res.status(400).json({ message: "Validation error", errors: error.errors });
|
||||||
|
} else {
|
||||||
|
console.error("Error updating group:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/api/groups/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id;
|
||||||
|
const deleted = await storage.deleteGroup(id);
|
||||||
|
|
||||||
|
if (!deleted) {
|
||||||
|
return res.status(404).json({ message: "Group not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(204).end();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting group:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Group Members
|
||||||
|
app.post("/api/group-members", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
// Validate member type
|
||||||
|
const memberTypeValidator = z.enum(memberTypes);
|
||||||
|
|
||||||
|
// Extend schema with validation
|
||||||
|
const schema = insertGroupMemberSchema.extend({
|
||||||
|
memberType: memberTypeValidator
|
||||||
|
});
|
||||||
|
|
||||||
|
const validatedData = schema.parse({
|
||||||
|
...req.body,
|
||||||
|
addedBy: req.user?.id
|
||||||
|
});
|
||||||
|
|
||||||
|
const member = await storage.addGroupMember(validatedData);
|
||||||
|
res.status(201).json(member);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
res.status(400).json({ message: "Validation error", errors: error.errors });
|
||||||
|
} else {
|
||||||
|
console.error("Error adding group member:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/api/group-members/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id;
|
||||||
|
const deleted = await storage.removeGroupMember(id);
|
||||||
|
|
||||||
|
if (!deleted) {
|
||||||
|
return res.status(404).json({ message: "Group member not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(204).end();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error removing group member:", error);
|
||||||
|
res.status(500).json({ message: "Internal server error" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
app.get("/api/api-tokens", requireRole(["admin", "manager"]), async (req, res) => {
|
app.get("/api/api-tokens", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ export interface IStorage {
|
|||||||
updateOrganization(id: string, org: Partial<InsertOrganization>): Promise<Organization | undefined>;
|
updateOrganization(id: string, org: Partial<InsertOrganization>): Promise<Organization | undefined>;
|
||||||
deleteOrganization(id: string): Promise<boolean>;
|
deleteOrganization(id: string): Promise<boolean>;
|
||||||
|
|
||||||
|
// Group management
|
||||||
|
getGroup(id: string): Promise<Group | undefined>;
|
||||||
|
getGroups(): Promise<Group[]>;
|
||||||
|
getGroupMembers(groupId: string): Promise<GroupMember[]>;
|
||||||
|
createGroup(group: InsertGroup): Promise<Group>;
|
||||||
|
updateGroup(id: string, group: Partial<InsertGroup>): Promise<Group | undefined>;
|
||||||
|
deleteGroup(id: string): Promise<boolean>;
|
||||||
|
addGroupMember(member: InsertGroupMember): Promise<GroupMember>;
|
||||||
|
removeGroupMember(id: string): Promise<boolean>;
|
||||||
|
|
||||||
// Domain management
|
// Domain management
|
||||||
getDomain(id: string): Promise<Domain | undefined>;
|
getDomain(id: string): Promise<Domain | undefined>;
|
||||||
getDomainsByOrganization(organizationId: string): Promise<Domain[]>;
|
getDomainsByOrganization(organizationId: string): Promise<Domain[]>;
|
||||||
|
|||||||
Reference in New Issue
Block a user