mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-07-26 11:38:13 +00:00
Refactor database schema and storage to support customer management and improved security.
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/71d83b03-af3d-433a-a517-e76255668e93.jpg
This commit is contained in:
+949
-167
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,5 +1,5 @@
|
||||
import express, { type Request, Response, NextFunction } from "express";
|
||||
import { registerRoutes } from "./routes";
|
||||
import { registerRoutes } from "./routes.simplified";
|
||||
import { setupVite, serveStatic, log } from "./vite";
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { Express } from "express";
|
||||
import { createServer, type Server } from "http";
|
||||
import { getCurrentIpAddress, getCurrentIpv6Address } from "./utils/ip-utils";
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Create HTTP server
|
||||
const httpServer = createServer(app);
|
||||
|
||||
// Add public IP endpoint for the frontend
|
||||
app.get('/api/public-ip', async (req, res) => {
|
||||
try {
|
||||
console.log('Fetching public IP addresses');
|
||||
// Get IPv4 address using our utility function
|
||||
const ipv4 = await getCurrentIpAddress();
|
||||
console.log(`Resolved IPv4: ${ipv4}`);
|
||||
|
||||
// Try to get IPv6 as well
|
||||
const ipv6 = await getCurrentIpv6Address();
|
||||
console.log(`Resolved IPv6: ${ipv6}`);
|
||||
|
||||
res.json({ ipv4, ipv6 });
|
||||
} catch (error) {
|
||||
console.error('Error getting public IP:', error);
|
||||
res.status(500).json({ error: 'Failed to get public IP address' });
|
||||
}
|
||||
});
|
||||
|
||||
return httpServer;
|
||||
}
|
||||
+12
-7
@@ -11,14 +11,17 @@ import {
|
||||
insertDnsRecordSchema,
|
||||
insertProviderSchema,
|
||||
insertApiTokenSchema,
|
||||
insertOrganizationSchema,
|
||||
insertCustomerSchema,
|
||||
insertWebhookSchema,
|
||||
insertDnsMetricSchema,
|
||||
insertCustomRoleSchema,
|
||||
insertCustomerUserAssignmentSchema,
|
||||
insertDomainCredentialsSchema,
|
||||
insertApiTokenCustomerAccessSchema,
|
||||
recordTypes,
|
||||
providerTypes,
|
||||
customRoles,
|
||||
memberTypes
|
||||
systemRoles
|
||||
} from "@shared/schema";
|
||||
import { randomBytes } from "crypto";
|
||||
import { getProviderForDomain } from './providers';
|
||||
@@ -119,8 +122,8 @@ async function triggerDnsWebhooks(
|
||||
const domain = await storage.getDomain(domainId);
|
||||
if (!domain) return;
|
||||
|
||||
// Get webhooks for this organization
|
||||
const webhooks = await storage.getWebhooksByOrganization(domain.organizationId);
|
||||
// Get webhooks for this customer
|
||||
const webhooks = await storage.getWebhooksByCustomer(domain.customerId);
|
||||
|
||||
// Filter webhooks that have subscribed to DNS events
|
||||
const dnsWebhooks = webhooks.filter(webhook =>
|
||||
@@ -153,9 +156,9 @@ async function triggerDnsWebhooks(
|
||||
}
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Setup authentication routes
|
||||
setupAuth(app);
|
||||
|
||||
// Create HTTP server
|
||||
const httpServer = createServer(app);
|
||||
|
||||
// Add public IP endpoint for the frontend
|
||||
app.get('/api/public-ip', async (req, res) => {
|
||||
try {
|
||||
@@ -174,6 +177,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
res.status(500).json({ error: 'Failed to get public IP address' });
|
||||
}
|
||||
});
|
||||
|
||||
return httpServer;
|
||||
|
||||
// DNS Records routes
|
||||
app.get("/api/dns-records", requireRole(["admin", "manager", "user", "readonly"]), async (req, res) => {
|
||||
|
||||
+34
-14
@@ -1,19 +1,22 @@
|
||||
import {
|
||||
type User, type InsertUser,
|
||||
type Organization, type InsertOrganization,
|
||||
type Customer, type InsertCustomer,
|
||||
type CustomerUserAssignment, type InsertCustomerUserAssignment,
|
||||
type Domain, type InsertDomain,
|
||||
type DomainCredentials, type InsertDomainCredentials,
|
||||
type DnsRecord, type InsertDnsRecord,
|
||||
type Provider, type InsertProvider,
|
||||
type ApiToken, type InsertApiToken,
|
||||
type ApiTokenCustomerAccess, type InsertApiTokenCustomerAccess,
|
||||
type DnsHistory,
|
||||
type Webhook, type InsertWebhook,
|
||||
type WebhookDeliveryLog, type InsertWebhookDeliveryLog,
|
||||
type DnsMetric, type InsertDnsMetric,
|
||||
type CustomRole, type InsertCustomRole,
|
||||
type MemberType
|
||||
type CustomRole, type InsertCustomRole
|
||||
} from "@shared/schema";
|
||||
import session from "express-session";
|
||||
import { DatabaseStorage } from "./database-storage";
|
||||
import { ImprovedDatabaseStorage } from "./improved-database-storage";
|
||||
|
||||
export interface IStorage {
|
||||
// User management
|
||||
@@ -24,23 +27,33 @@ export interface IStorage {
|
||||
updateUser(id: string, user: Partial<InsertUser>): Promise<User | undefined>;
|
||||
deleteUser(id: string): Promise<boolean>;
|
||||
|
||||
// Organization management
|
||||
getOrganization(id: string): Promise<Organization | undefined>;
|
||||
getOrganizations(): Promise<Organization[]>;
|
||||
createOrganization(org: InsertOrganization): Promise<Organization>;
|
||||
updateOrganization(id: string, org: Partial<InsertOrganization>): Promise<Organization | undefined>;
|
||||
deleteOrganization(id: string): Promise<boolean>;
|
||||
// Customer management
|
||||
getCustomer(id: string): Promise<Customer | undefined>;
|
||||
getCustomers(): Promise<Customer[]>;
|
||||
createCustomer(customer: InsertCustomer): Promise<Customer>;
|
||||
updateCustomer(id: string, customer: Partial<InsertCustomer>): Promise<Customer | undefined>;
|
||||
deleteCustomer(id: string): Promise<boolean>;
|
||||
|
||||
// Group management has been removed
|
||||
// Customer-User assignments
|
||||
getCustomerUsers(customerId: string): Promise<User[]>;
|
||||
getUserCustomers(userId: string): Promise<Customer[]>;
|
||||
assignUserToCustomer(assignment: InsertCustomerUserAssignment): Promise<CustomerUserAssignment>;
|
||||
updateUserCustomerRole(customerId: string, userId: string, role: string): Promise<CustomerUserAssignment | undefined>;
|
||||
removeUserFromCustomer(customerId: string, userId: string): Promise<boolean>;
|
||||
|
||||
// Domain management
|
||||
getDomain(id: string): Promise<Domain | undefined>;
|
||||
getDomainsByOrganization(organizationId: string): Promise<Domain[]>;
|
||||
getDomainsByCustomer(customerId: string): Promise<Domain[]>;
|
||||
getAllDomains(): Promise<Domain[]>;
|
||||
createDomain(domain: InsertDomain): Promise<Domain>;
|
||||
updateDomain(id: string, domain: Partial<InsertDomain>): Promise<Domain | undefined>;
|
||||
deleteDomain(id: string): Promise<boolean>;
|
||||
|
||||
// Domain credentials management
|
||||
getDomainCredentials(domainId: string): Promise<DomainCredentials | undefined>;
|
||||
createDomainCredentials(credentials: InsertDomainCredentials): Promise<DomainCredentials>;
|
||||
updateDomainCredentials(domainId: string, credentials: Partial<InsertDomainCredentials>): Promise<DomainCredentials | undefined>;
|
||||
|
||||
// DNS Record management
|
||||
getDnsRecord(id: string): Promise<DnsRecord | undefined>;
|
||||
getDnsRecordsByDomain(domainId: string): Promise<DnsRecord[]>;
|
||||
@@ -58,11 +71,17 @@ export interface IStorage {
|
||||
// API Token management
|
||||
getApiToken(id: string): Promise<ApiToken | undefined>;
|
||||
getApiTokenByToken(token: string): Promise<ApiToken | undefined>;
|
||||
getApiTokensByOrganization(organizationId: string): Promise<ApiToken[]>;
|
||||
getApiTokensByCustomer(customerId: string): Promise<ApiToken[]>;
|
||||
getApiTokens(): Promise<ApiToken[]>;
|
||||
createApiToken(token: InsertApiToken): Promise<ApiToken>;
|
||||
updateApiToken(id: string, token: Partial<InsertApiToken>): Promise<ApiToken | undefined>;
|
||||
deleteApiToken(id: string): Promise<boolean>;
|
||||
|
||||
// API Token Customer Access
|
||||
getApiTokenCustomerAccess(tokenId: string): Promise<ApiTokenCustomerAccess[]>;
|
||||
addApiTokenCustomerAccess(access: InsertApiTokenCustomerAccess): Promise<ApiTokenCustomerAccess>;
|
||||
removeApiTokenCustomerAccess(tokenId: string, customerId: string): Promise<boolean>;
|
||||
|
||||
// DNS History
|
||||
addDnsHistory(recordId: string, action: string, previousValue?: string, newValue?: string, userId?: string): Promise<DnsHistory>;
|
||||
getDnsHistoryByRecord(recordId: string): Promise<DnsHistory[]>;
|
||||
@@ -70,7 +89,7 @@ export interface IStorage {
|
||||
|
||||
// Webhook management
|
||||
getWebhook(id: string): Promise<Webhook | undefined>;
|
||||
getWebhooksByOrganization(organizationId: string): Promise<Webhook[]>;
|
||||
getWebhooksByCustomer(customerId: string): Promise<Webhook[]>;
|
||||
createWebhook(webhook: InsertWebhook): Promise<Webhook>;
|
||||
updateWebhook(id: string, webhook: Partial<InsertWebhook>): Promise<Webhook | undefined>;
|
||||
deleteWebhook(id: string): Promise<boolean>;
|
||||
@@ -927,4 +946,5 @@ export class MemStorage implements IStorage {
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = new MemStorage();
|
||||
// Use the improved storage implementation
|
||||
export const storage = new ImprovedDatabaseStorage();
|
||||
|
||||
Reference in New Issue
Block a user