mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-07-26 11:38:13 +00:00
Refactor: Improve authorization and access control for webhooks and domains by replacing organization IDs with customer IDs.
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/9d305f1a-cfc0-4985-9af8-152b65c738cb.jpg
This commit is contained in:
+47
-19
@@ -707,10 +707,10 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
app.get("/api/domains", requireRole(["admin", "manager", "user", "readonly"]), async (req, res) => {
|
||||
try {
|
||||
let domains;
|
||||
const orgId = req.query.organizationId ? parseInt(req.query.organizationId as string) : undefined;
|
||||
const customerId = req.query.customerId as string;
|
||||
|
||||
if (orgId) {
|
||||
domains = await storage.getDomainsByOrganization(orgId);
|
||||
if (customerId) {
|
||||
domains = await storage.getDomainsByCustomer(customerId);
|
||||
} else {
|
||||
domains = await storage.getAllDomains();
|
||||
}
|
||||
@@ -744,7 +744,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Create a custom validation schema for the API that makes providerId optional
|
||||
const domainSchema = z.object({
|
||||
name: z.string(),
|
||||
organizationId: z.string().uuid(),
|
||||
customerId: z.string().uuid(),
|
||||
providerId: z.string().uuid().optional(),
|
||||
isActive: z.boolean().optional().default(true)
|
||||
});
|
||||
@@ -770,7 +770,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Create custom validation schema with optional providerId
|
||||
const domainUpdateSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
organizationId: z.string().uuid().optional(),
|
||||
customerId: z.string().uuid().optional(),
|
||||
providerId: z.string().uuid().optional().nullable(),
|
||||
isActive: z.boolean().optional()
|
||||
});
|
||||
@@ -1406,9 +1406,16 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(404).json({ message: "Webhook not found" });
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
if (req.user?.role !== "admin" && webhook.organizationId !== req.user?.organizationId) {
|
||||
return res.status(403).json({ message: "Not authorized to access this webhook" });
|
||||
// Check authorization for non-admin users
|
||||
if (req.user?.role !== "admin") {
|
||||
// Get user's customers
|
||||
const userCustomers = await storage.getUserCustomers(req.user?.id as string);
|
||||
const userCustomerIds = userCustomers.map(c => c.id);
|
||||
|
||||
// Check if the user has access to the webhook's customer
|
||||
if (!userCustomerIds.includes(webhook.customerId)) {
|
||||
return res.status(403).json({ message: "Not authorized to access this webhook" });
|
||||
}
|
||||
}
|
||||
|
||||
res.json(webhook);
|
||||
@@ -1430,8 +1437,15 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
const validatedData = insertWebhookSchema.parse(requestData);
|
||||
|
||||
// Check authorization for non-admin users
|
||||
if (req.user?.role !== "admin" && validatedData.organizationId !== req.user?.organizationId) {
|
||||
return res.status(403).json({ message: "Not authorized to create webhooks for this organization" });
|
||||
if (req.user?.role !== "admin") {
|
||||
// Get user's customers
|
||||
const userCustomers = await storage.getUserCustomers(req.user?.id as string);
|
||||
const userCustomerIds = userCustomers.map(c => c.id);
|
||||
|
||||
// Check if the user has access to the customer
|
||||
if (!userCustomerIds.includes(validatedData.customerId)) {
|
||||
return res.status(403).json({ message: "Not authorized to create webhooks for this customer" });
|
||||
}
|
||||
}
|
||||
|
||||
const webhook = await storage.createWebhook(validatedData);
|
||||
@@ -1455,16 +1469,23 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(404).json({ message: "Webhook not found" });
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
if (req.user?.role !== "admin" && webhook.organizationId !== req.user?.organizationId) {
|
||||
return res.status(403).json({ message: "Not authorized to modify this webhook" });
|
||||
// Check authorization for non-admin users
|
||||
if (req.user?.role !== "admin") {
|
||||
// Get user's customers
|
||||
const userCustomers = await storage.getUserCustomers(req.user?.id as string);
|
||||
const userCustomerIds = userCustomers.map(c => c.id);
|
||||
|
||||
// Check if the user has access to the webhook's customer
|
||||
if (!userCustomerIds.includes(webhook.customerId)) {
|
||||
return res.status(403).json({ message: "Not authorized to modify this webhook" });
|
||||
}
|
||||
}
|
||||
|
||||
const validatedData = insertWebhookSchema.partial().parse(req.body);
|
||||
|
||||
// Prevent changing organization for security reasons
|
||||
if (validatedData.organizationId && validatedData.organizationId !== webhook.organizationId) {
|
||||
return res.status(400).json({ message: "Cannot change webhook organization" });
|
||||
// Prevent changing customer for security reasons
|
||||
if (validatedData.customerId && validatedData.customerId !== webhook.customerId) {
|
||||
return res.status(400).json({ message: "Cannot change webhook customer" });
|
||||
}
|
||||
|
||||
const updatedWebhook = await storage.updateWebhook(req.params.id, validatedData);
|
||||
@@ -1487,9 +1508,16 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(404).json({ message: "Webhook not found" });
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
if (req.user?.role !== "admin" && webhook.organizationId !== req.user?.organizationId) {
|
||||
return res.status(403).json({ message: "Not authorized to delete this webhook" });
|
||||
// Check authorization for non-admin users
|
||||
if (req.user?.role !== "admin") {
|
||||
// Get user's customers
|
||||
const userCustomers = await storage.getUserCustomers(req.user?.id as string);
|
||||
const userCustomerIds = userCustomers.map(c => c.id);
|
||||
|
||||
// Check if the user has access to the webhook's customer
|
||||
if (!userCustomerIds.includes(webhook.customerId)) {
|
||||
return res.status(403).json({ message: "Not authorized to delete this webhook" });
|
||||
}
|
||||
}
|
||||
|
||||
const deleted = await storage.deleteWebhook(req.params.id);
|
||||
|
||||
Reference in New Issue
Block a user