import { User, InsertUser, ApiToken, InsertApiToken, LdapConnection, InsertLdapConnection, AdUser, InsertAdUser, AdGroup, InsertAdGroup, AdOrgUnit, InsertAdOrgUnit, AdComputer, InsertAdComputer, AdDomain, InsertAdDomain } from "@shared/schema"; import session from "express-session"; import createMemoryStore from "memorystore"; import crypto from "crypto"; // Memory store for sessions const MemoryStore = createMemoryStore(session); export interface IStorage { // User management getUser(id: number): Promise; getUserByUsername(username: string): Promise; createUser(user: InsertUser): Promise; updateUser(id: number, user: Partial): Promise; deleteUser(id: number): Promise; listUsers(): Promise; // API Token management getApiToken(id: number): Promise; getApiTokenByToken(token: string): Promise; createApiToken(token: InsertApiToken): Promise; deleteApiToken(id: number): Promise; listApiTokensByUserId(userId: number): Promise; // LDAP Connection management getLdapConnection(id: number): Promise; createLdapConnection(connection: InsertLdapConnection): Promise; updateLdapConnection(id: number, connection: Partial): Promise; deleteLdapConnection(id: number): Promise; listLdapConnections(): Promise; // AD Users getAdUser(id: number): Promise; createAdUser(user: InsertAdUser): Promise; updateAdUser(id: number, user: Partial): Promise; deleteAdUser(id: number): Promise; listAdUsers(connectionId: number, query?: any): Promise; // AD Groups getAdGroup(id: number): Promise; createAdGroup(group: InsertAdGroup): Promise; updateAdGroup(id: number, group: Partial): Promise; deleteAdGroup(id: number): Promise; listAdGroups(connectionId: number, query?: any): Promise; // AD Organizational Units getAdOrgUnit(id: number): Promise; createAdOrgUnit(ou: InsertAdOrgUnit): Promise; updateAdOrgUnit(id: number, ou: Partial): Promise; deleteAdOrgUnit(id: number): Promise; listAdOrgUnits(connectionId: number, query?: any): Promise; // AD Computers getAdComputer(id: number): Promise; createAdComputer(computer: InsertAdComputer): Promise; updateAdComputer(id: number, computer: Partial): Promise; deleteAdComputer(id: number): Promise; listAdComputers(connectionId: number, query?: any): Promise; // AD Domains getAdDomain(id: number): Promise; createAdDomain(domain: InsertAdDomain): Promise; updateAdDomain(id: number, domain: Partial): Promise; deleteAdDomain(id: number): Promise; listAdDomains(connectionId: number, query?: any): Promise; // Session store sessionStore: session.SessionStore; } export class MemStorage implements IStorage { private users: Map; private apiTokens: Map; private ldapConnections: Map; private adUsers: Map; private adGroups: Map; private adOrgUnits: Map; private adComputers: Map; private adDomains: Map; sessionStore: session.SessionStore; private userCurrentId: number; private tokenCurrentId: number; private connectionCurrentId: number; private adUserCurrentId: number; private adGroupCurrentId: number; private adOrgUnitCurrentId: number; private adComputerCurrentId: number; private adDomainCurrentId: number; constructor() { this.users = new Map(); this.apiTokens = new Map(); this.ldapConnections = new Map(); this.adUsers = new Map(); this.adGroups = new Map(); this.adOrgUnits = new Map(); this.adComputers = new Map(); this.adDomains = new Map(); this.userCurrentId = 1; this.tokenCurrentId = 1; this.connectionCurrentId = 1; this.adUserCurrentId = 1; this.adGroupCurrentId = 1; this.adOrgUnitCurrentId = 1; this.adComputerCurrentId = 1; this.adDomainCurrentId = 1; this.sessionStore = new MemoryStore({ checkPeriod: 86400000 // 24h }); } // User management async getUser(id: number): Promise { return this.users.get(id); } async getUserByUsername(username: string): Promise { return Array.from(this.users.values()).find( (user) => user.username.toLowerCase() === username.toLowerCase(), ); } async createUser(insertUser: InsertUser): Promise { const id = this.userCurrentId++; const now = new Date(); const user: User = { ...insertUser, id, createdAt: now, role: insertUser.role || "user" }; this.users.set(id, user); return user; } async updateUser(id: number, userData: Partial): Promise { const user = await this.getUser(id); if (!user) return undefined; const updatedUser = { ...user, ...userData }; this.users.set(id, updatedUser); return updatedUser; } async deleteUser(id: number): Promise { return this.users.delete(id); } async listUsers(): Promise { return Array.from(this.users.values()); } // API Token management async getApiToken(id: number): Promise { return this.apiTokens.get(id); } async getApiTokenByToken(token: string): Promise { return Array.from(this.apiTokens.values()).find( (apiToken) => apiToken.token === token, ); } async createApiToken(insertToken: InsertApiToken): Promise { const id = this.tokenCurrentId++; const now = new Date(); const token: ApiToken = { ...insertToken, id, createdAt: now }; this.apiTokens.set(id, token); return token; } async deleteApiToken(id: number): Promise { return this.apiTokens.delete(id); } async listApiTokensByUserId(userId: number): Promise { return Array.from(this.apiTokens.values()).filter( (token) => token.userId === userId, ); } // LDAP Connection management async getLdapConnection(id: number): Promise { return this.ldapConnections.get(id); } async createLdapConnection(insertConnection: InsertLdapConnection): Promise { const id = this.connectionCurrentId++; const now = new Date(); const connection: LdapConnection = { ...insertConnection, id, createdAt: now, lastConnected: null, status: "disconnected" }; this.ldapConnections.set(id, connection); return connection; } async updateLdapConnection(id: number, connectionData: Partial): Promise { const connection = await this.getLdapConnection(id); if (!connection) return undefined; const updatedConnection = { ...connection, ...connectionData }; this.ldapConnections.set(id, updatedConnection); return updatedConnection; } async deleteLdapConnection(id: number): Promise { return this.ldapConnections.delete(id); } async listLdapConnections(): Promise { return Array.from(this.ldapConnections.values()); } // AD Users async getAdUser(id: number): Promise { return this.adUsers.get(id); } async createAdUser(user: InsertAdUser): Promise { const id = this.adUserCurrentId++; const adUser: AdUser = { ...user, id }; this.adUsers.set(id, adUser); return adUser; } async updateAdUser(id: number, userData: Partial): Promise { const user = await this.getAdUser(id); if (!user) return undefined; const updatedUser = { ...user, ...userData }; this.adUsers.set(id, updatedUser); return updatedUser; } async deleteAdUser(id: number): Promise { return this.adUsers.delete(id); } async listAdUsers(connectionId: number, query?: any): Promise { let users = Array.from(this.adUsers.values()).filter( (user) => user.connectionId === connectionId, ); // Apply filtering logic based on query if (query) { if (query.filter) { // Simple filter implementation - can be expanded const filterParts = query.filter.split(' '); if (filterParts.length === 3) { const [property, operator, value] = filterParts; const unquotedValue = value.replace(/^'|'$/g, ''); if (operator === 'eq') { users = users.filter(user => (user as any)[property] === unquotedValue); } } } // Apply property selection if (query.select) { const properties = query.select.split(','); users = users.map(user => { const result: any = { id: user.id }; properties.forEach(prop => { if ((user as any)[prop] !== undefined) { result[prop] = (user as any)[prop]; } }); return result as AdUser; }); } } return users; } // AD Groups async getAdGroup(id: number): Promise { return this.adGroups.get(id); } async createAdGroup(group: InsertAdGroup): Promise { const id = this.adGroupCurrentId++; const adGroup: AdGroup = { ...group, id }; this.adGroups.set(id, adGroup); return adGroup; } async updateAdGroup(id: number, groupData: Partial): Promise { const group = await this.getAdGroup(id); if (!group) return undefined; const updatedGroup = { ...group, ...groupData }; this.adGroups.set(id, updatedGroup); return updatedGroup; } async deleteAdGroup(id: number): Promise { return this.adGroups.delete(id); } async listAdGroups(connectionId: number, query?: any): Promise { let groups = Array.from(this.adGroups.values()).filter( (group) => group.connectionId === connectionId, ); // Apply filtering logic if (query) { if (query.select) { const properties = query.select.split(','); groups = groups.map(group => { const result: any = { id: group.id }; properties.forEach(prop => { if ((group as any)[prop] !== undefined) { result[prop] = (group as any)[prop]; } }); return result as AdGroup; }); } } return groups; } // AD Organizational Units async getAdOrgUnit(id: number): Promise { return this.adOrgUnits.get(id); } async createAdOrgUnit(ou: InsertAdOrgUnit): Promise { const id = this.adOrgUnitCurrentId++; const adOrgUnit: AdOrgUnit = { ...ou, id }; this.adOrgUnits.set(id, adOrgUnit); return adOrgUnit; } async updateAdOrgUnit(id: number, ouData: Partial): Promise { const ou = await this.getAdOrgUnit(id); if (!ou) return undefined; const updatedOu = { ...ou, ...ouData }; this.adOrgUnits.set(id, updatedOu); return updatedOu; } async deleteAdOrgUnit(id: number): Promise { return this.adOrgUnits.delete(id); } async listAdOrgUnits(connectionId: number, query?: any): Promise { let orgUnits = Array.from(this.adOrgUnits.values()).filter( (ou) => ou.connectionId === connectionId, ); // Apply filtering logic if (query) { if (query.select) { const properties = query.select.split(','); orgUnits = orgUnits.map(ou => { const result: any = { id: ou.id }; properties.forEach(prop => { if ((ou as any)[prop] !== undefined) { result[prop] = (ou as any)[prop]; } }); return result as AdOrgUnit; }); } } return orgUnits; } // AD Computers async getAdComputer(id: number): Promise { return this.adComputers.get(id); } async createAdComputer(computer: InsertAdComputer): Promise { const id = this.adComputerCurrentId++; const adComputer: AdComputer = { ...computer, id }; this.adComputers.set(id, adComputer); return adComputer; } async updateAdComputer(id: number, computerData: Partial): Promise { const computer = await this.getAdComputer(id); if (!computer) return undefined; const updatedComputer = { ...computer, ...computerData }; this.adComputers.set(id, updatedComputer); return updatedComputer; } async deleteAdComputer(id: number): Promise { return this.adComputers.delete(id); } async listAdComputers(connectionId: number, query?: any): Promise { let computers = Array.from(this.adComputers.values()).filter( (computer) => computer.connectionId === connectionId, ); // Apply filtering logic if (query) { if (query.select) { const properties = query.select.split(','); computers = computers.map(computer => { const result: any = { id: computer.id }; properties.forEach(prop => { if ((computer as any)[prop] !== undefined) { result[prop] = (computer as any)[prop]; } }); return result as AdComputer; }); } } return computers; } // AD Domains async getAdDomain(id: number): Promise { return this.adDomains.get(id); } async createAdDomain(domain: InsertAdDomain): Promise { const id = this.adDomainCurrentId++; const adDomain: AdDomain = { ...domain, id }; this.adDomains.set(id, adDomain); return adDomain; } async updateAdDomain(id: number, domainData: Partial): Promise { const domain = await this.getAdDomain(id); if (!domain) return undefined; const updatedDomain = { ...domain, ...domainData }; this.adDomains.set(id, updatedDomain); return updatedDomain; } async deleteAdDomain(id: number): Promise { return this.adDomains.delete(id); } async listAdDomains(connectionId: number, query?: any): Promise { let domains = Array.from(this.adDomains.values()).filter( (domain) => domain.connectionId === connectionId, ); // Apply filtering logic if (query) { if (query.select) { const properties = query.select.split(','); domains = domains.map(domain => { const result: any = { id: domain.id }; properties.forEach(prop => { if ((domain as any)[prop] !== undefined) { result[prop] = (domain as any)[prop]; } }); return result as AdDomain; }); } } return domains; } } export const storage = new MemStorage();