mirror of
https://github.com/freedbygrace/ActiveDirectoryManager.git
synced 2026-08-28 03:27:06 +00:00
Add user authentication and Active Directory management features. Includes a new admin UI and Swagger API documentation.
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/e9f0a10f-e323-455c-82c9-1da4a687f20e.jpg
This commit is contained in:
+371
-99
@@ -1,44 +1,76 @@
|
||||
import { users, apiTokens, ldapConnections, activityLogs } from "@shared/schema";
|
||||
import type {
|
||||
User, InsertUser,
|
||||
ApiToken, InsertApiToken,
|
||||
import {
|
||||
User, InsertUser, ApiToken, InsertApiToken,
|
||||
LdapConnection, InsertLdapConnection,
|
||||
ActivityLog, InsertActivityLog
|
||||
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 {
|
||||
// Users
|
||||
// User management
|
||||
getUser(id: number): Promise<User | undefined>;
|
||||
getUserByUsername(username: string): Promise<User | undefined>;
|
||||
createUser(user: InsertUser): Promise<User>;
|
||||
updateUser(id: number, user: Partial<User>): Promise<User | undefined>;
|
||||
deleteUser(id: number): Promise<boolean>;
|
||||
listUsers(filters?: any): Promise<User[]>;
|
||||
listUsers(): Promise<User[]>;
|
||||
|
||||
// API Tokens
|
||||
// API Token management
|
||||
getApiToken(id: number): Promise<ApiToken | undefined>;
|
||||
getApiTokenByToken(token: string): Promise<ApiToken | undefined>;
|
||||
createApiToken(token: InsertApiToken & { token: string }): Promise<ApiToken>;
|
||||
updateApiToken(id: number, token: Partial<ApiToken>): Promise<ApiToken | undefined>;
|
||||
createApiToken(token: InsertApiToken): Promise<ApiToken>;
|
||||
deleteApiToken(id: number): Promise<boolean>;
|
||||
listApiTokens(userId?: number): Promise<ApiToken[]>;
|
||||
listApiTokensByUserId(userId: number): Promise<ApiToken[]>;
|
||||
|
||||
// LDAP Connections
|
||||
// LDAP Connection management
|
||||
getLdapConnection(id: number): Promise<LdapConnection | undefined>;
|
||||
createLdapConnection(connection: InsertLdapConnection): Promise<LdapConnection>;
|
||||
updateLdapConnection(id: number, connection: Partial<LdapConnection>): Promise<LdapConnection | undefined>;
|
||||
deleteLdapConnection(id: number): Promise<boolean>;
|
||||
listLdapConnections(): Promise<LdapConnection[]>;
|
||||
|
||||
// Activity Logs
|
||||
createActivityLog(log: InsertActivityLog): Promise<ActivityLog>;
|
||||
listActivityLogs(limit?: number): Promise<ActivityLog[]>;
|
||||
// AD Users
|
||||
getAdUser(id: number): Promise<AdUser | undefined>;
|
||||
createAdUser(user: InsertAdUser): Promise<AdUser>;
|
||||
updateAdUser(id: number, user: Partial<AdUser>): Promise<AdUser | undefined>;
|
||||
deleteAdUser(id: number): Promise<boolean>;
|
||||
listAdUsers(connectionId: number, query?: any): Promise<AdUser[]>;
|
||||
|
||||
// Session Store
|
||||
// AD Groups
|
||||
getAdGroup(id: number): Promise<AdGroup | undefined>;
|
||||
createAdGroup(group: InsertAdGroup): Promise<AdGroup>;
|
||||
updateAdGroup(id: number, group: Partial<AdGroup>): Promise<AdGroup | undefined>;
|
||||
deleteAdGroup(id: number): Promise<boolean>;
|
||||
listAdGroups(connectionId: number, query?: any): Promise<AdGroup[]>;
|
||||
|
||||
// AD Organizational Units
|
||||
getAdOrgUnit(id: number): Promise<AdOrgUnit | undefined>;
|
||||
createAdOrgUnit(ou: InsertAdOrgUnit): Promise<AdOrgUnit>;
|
||||
updateAdOrgUnit(id: number, ou: Partial<AdOrgUnit>): Promise<AdOrgUnit | undefined>;
|
||||
deleteAdOrgUnit(id: number): Promise<boolean>;
|
||||
listAdOrgUnits(connectionId: number, query?: any): Promise<AdOrgUnit[]>;
|
||||
|
||||
// AD Computers
|
||||
getAdComputer(id: number): Promise<AdComputer | undefined>;
|
||||
createAdComputer(computer: InsertAdComputer): Promise<AdComputer>;
|
||||
updateAdComputer(id: number, computer: Partial<AdComputer>): Promise<AdComputer | undefined>;
|
||||
deleteAdComputer(id: number): Promise<boolean>;
|
||||
listAdComputers(connectionId: number, query?: any): Promise<AdComputer[]>;
|
||||
|
||||
// AD Domains
|
||||
getAdDomain(id: number): Promise<AdDomain | undefined>;
|
||||
createAdDomain(domain: InsertAdDomain): Promise<AdDomain>;
|
||||
updateAdDomain(id: number, domain: Partial<AdDomain>): Promise<AdDomain | undefined>;
|
||||
deleteAdDomain(id: number): Promise<boolean>;
|
||||
listAdDomains(connectionId: number, query?: any): Promise<AdDomain[]>;
|
||||
|
||||
// Session store
|
||||
sessionStore: session.SessionStore;
|
||||
}
|
||||
|
||||
@@ -46,31 +78,47 @@ export class MemStorage implements IStorage {
|
||||
private users: Map<number, User>;
|
||||
private apiTokens: Map<number, ApiToken>;
|
||||
private ldapConnections: Map<number, LdapConnection>;
|
||||
private activityLogs: ActivityLog[];
|
||||
|
||||
currentUserId: number;
|
||||
currentTokenId: number;
|
||||
currentConnectionId: number;
|
||||
currentLogId: number;
|
||||
private adUsers: Map<number, AdUser>;
|
||||
private adGroups: Map<number, AdGroup>;
|
||||
private adOrgUnits: Map<number, AdOrgUnit>;
|
||||
private adComputers: Map<number, AdComputer>;
|
||||
private adDomains: Map<number, AdDomain>;
|
||||
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.activityLogs = [];
|
||||
|
||||
this.currentUserId = 1;
|
||||
this.currentTokenId = 1;
|
||||
this.currentConnectionId = 1;
|
||||
this.currentLogId = 1;
|
||||
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, // 24 hours
|
||||
checkPeriod: 86400000 // 24h
|
||||
});
|
||||
}
|
||||
|
||||
// Users
|
||||
// User management
|
||||
async getUser(id: number): Promise<User | undefined> {
|
||||
return this.users.get(id);
|
||||
}
|
||||
@@ -82,18 +130,23 @@ export class MemStorage implements IStorage {
|
||||
}
|
||||
|
||||
async createUser(insertUser: InsertUser): Promise<User> {
|
||||
const id = this.currentUserId++;
|
||||
const createdAt = new Date();
|
||||
const user: User = { ...insertUser, id, createdAt };
|
||||
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, updates: Partial<User>): Promise<User | undefined> {
|
||||
const user = this.users.get(id);
|
||||
async updateUser(id: number, userData: Partial<User>): Promise<User | undefined> {
|
||||
const user = await this.getUser(id);
|
||||
if (!user) return undefined;
|
||||
|
||||
const updatedUser = { ...user, ...updates };
|
||||
const updatedUser = { ...user, ...userData };
|
||||
this.users.set(id, updatedUser);
|
||||
return updatedUser;
|
||||
}
|
||||
@@ -102,22 +155,11 @@ export class MemStorage implements IStorage {
|
||||
return this.users.delete(id);
|
||||
}
|
||||
|
||||
async listUsers(filters?: any): Promise<User[]> {
|
||||
const users = Array.from(this.users.values());
|
||||
if (!filters) return users;
|
||||
|
||||
// Apply filters if provided
|
||||
return users.filter(user => {
|
||||
for (const [key, value] of Object.entries(filters)) {
|
||||
if (user[key as keyof User] !== value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
async listUsers(): Promise<User[]> {
|
||||
return Array.from(this.users.values());
|
||||
}
|
||||
|
||||
// API Tokens
|
||||
// API Token management
|
||||
async getApiToken(id: number): Promise<ApiToken | undefined> {
|
||||
return this.apiTokens.get(id);
|
||||
}
|
||||
@@ -128,61 +170,48 @@ export class MemStorage implements IStorage {
|
||||
);
|
||||
}
|
||||
|
||||
async createApiToken(tokenData: InsertApiToken & { token: string }): Promise<ApiToken> {
|
||||
const id = this.currentTokenId++;
|
||||
const createdAt = new Date();
|
||||
const apiToken: ApiToken = {
|
||||
...tokenData,
|
||||
id,
|
||||
createdAt,
|
||||
lastUsedAt: null
|
||||
};
|
||||
this.apiTokens.set(id, apiToken);
|
||||
return apiToken;
|
||||
}
|
||||
|
||||
async updateApiToken(id: number, updates: Partial<ApiToken>): Promise<ApiToken | undefined> {
|
||||
const token = this.apiTokens.get(id);
|
||||
if (!token) return undefined;
|
||||
|
||||
const updatedToken = { ...token, ...updates };
|
||||
this.apiTokens.set(id, updatedToken);
|
||||
return updatedToken;
|
||||
async createApiToken(insertToken: InsertApiToken): Promise<ApiToken> {
|
||||
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<boolean> {
|
||||
return this.apiTokens.delete(id);
|
||||
}
|
||||
|
||||
async listApiTokens(userId?: number): Promise<ApiToken[]> {
|
||||
const tokens = Array.from(this.apiTokens.values());
|
||||
if (userId === undefined) return tokens;
|
||||
|
||||
return tokens.filter(token => token.userId === userId);
|
||||
async listApiTokensByUserId(userId: number): Promise<ApiToken[]> {
|
||||
return Array.from(this.apiTokens.values()).filter(
|
||||
(token) => token.userId === userId,
|
||||
);
|
||||
}
|
||||
|
||||
// LDAP Connections
|
||||
// LDAP Connection management
|
||||
async getLdapConnection(id: number): Promise<LdapConnection | undefined> {
|
||||
return this.ldapConnections.get(id);
|
||||
}
|
||||
|
||||
async createLdapConnection(connectionData: InsertLdapConnection): Promise<LdapConnection> {
|
||||
const id = this.currentConnectionId++;
|
||||
const ldapConnection: LdapConnection = {
|
||||
...connectionData,
|
||||
async createLdapConnection(insertConnection: InsertLdapConnection): Promise<LdapConnection> {
|
||||
const id = this.connectionCurrentId++;
|
||||
const now = new Date();
|
||||
const connection: LdapConnection = {
|
||||
...insertConnection,
|
||||
id,
|
||||
status: "disconnected",
|
||||
lastConnected: null
|
||||
createdAt: now,
|
||||
lastConnected: null,
|
||||
status: "disconnected"
|
||||
};
|
||||
this.ldapConnections.set(id, ldapConnection);
|
||||
return ldapConnection;
|
||||
this.ldapConnections.set(id, connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
async updateLdapConnection(id: number, updates: Partial<LdapConnection>): Promise<LdapConnection | undefined> {
|
||||
const connection = this.ldapConnections.get(id);
|
||||
async updateLdapConnection(id: number, connectionData: Partial<LdapConnection>): Promise<LdapConnection | undefined> {
|
||||
const connection = await this.getLdapConnection(id);
|
||||
if (!connection) return undefined;
|
||||
|
||||
const updatedConnection = { ...connection, ...updates };
|
||||
const updatedConnection = { ...connection, ...connectionData };
|
||||
this.ldapConnections.set(id, updatedConnection);
|
||||
return updatedConnection;
|
||||
}
|
||||
@@ -195,20 +224,263 @@ export class MemStorage implements IStorage {
|
||||
return Array.from(this.ldapConnections.values());
|
||||
}
|
||||
|
||||
// Activity Logs
|
||||
async createActivityLog(logData: InsertActivityLog): Promise<ActivityLog> {
|
||||
const id = this.currentLogId++;
|
||||
const timestamp = new Date();
|
||||
const log: ActivityLog = { ...logData, id, timestamp };
|
||||
this.activityLogs.push(log);
|
||||
return log;
|
||||
// AD Users
|
||||
async getAdUser(id: number): Promise<AdUser | undefined> {
|
||||
return this.adUsers.get(id);
|
||||
}
|
||||
|
||||
async listActivityLogs(limit = 10): Promise<ActivityLog[]> {
|
||||
// Sort by timestamp descending (newest first)
|
||||
return [...this.activityLogs]
|
||||
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
|
||||
.slice(0, limit);
|
||||
async createAdUser(user: InsertAdUser): Promise<AdUser> {
|
||||
const id = this.adUserCurrentId++;
|
||||
const adUser: AdUser = { ...user, id };
|
||||
this.adUsers.set(id, adUser);
|
||||
return adUser;
|
||||
}
|
||||
|
||||
async updateAdUser(id: number, userData: Partial<AdUser>): Promise<AdUser | undefined> {
|
||||
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<boolean> {
|
||||
return this.adUsers.delete(id);
|
||||
}
|
||||
|
||||
async listAdUsers(connectionId: number, query?: any): Promise<AdUser[]> {
|
||||
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<AdGroup | undefined> {
|
||||
return this.adGroups.get(id);
|
||||
}
|
||||
|
||||
async createAdGroup(group: InsertAdGroup): Promise<AdGroup> {
|
||||
const id = this.adGroupCurrentId++;
|
||||
const adGroup: AdGroup = { ...group, id };
|
||||
this.adGroups.set(id, adGroup);
|
||||
return adGroup;
|
||||
}
|
||||
|
||||
async updateAdGroup(id: number, groupData: Partial<AdGroup>): Promise<AdGroup | undefined> {
|
||||
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<boolean> {
|
||||
return this.adGroups.delete(id);
|
||||
}
|
||||
|
||||
async listAdGroups(connectionId: number, query?: any): Promise<AdGroup[]> {
|
||||
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<AdOrgUnit | undefined> {
|
||||
return this.adOrgUnits.get(id);
|
||||
}
|
||||
|
||||
async createAdOrgUnit(ou: InsertAdOrgUnit): Promise<AdOrgUnit> {
|
||||
const id = this.adOrgUnitCurrentId++;
|
||||
const adOrgUnit: AdOrgUnit = { ...ou, id };
|
||||
this.adOrgUnits.set(id, adOrgUnit);
|
||||
return adOrgUnit;
|
||||
}
|
||||
|
||||
async updateAdOrgUnit(id: number, ouData: Partial<AdOrgUnit>): Promise<AdOrgUnit | undefined> {
|
||||
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<boolean> {
|
||||
return this.adOrgUnits.delete(id);
|
||||
}
|
||||
|
||||
async listAdOrgUnits(connectionId: number, query?: any): Promise<AdOrgUnit[]> {
|
||||
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<AdComputer | undefined> {
|
||||
return this.adComputers.get(id);
|
||||
}
|
||||
|
||||
async createAdComputer(computer: InsertAdComputer): Promise<AdComputer> {
|
||||
const id = this.adComputerCurrentId++;
|
||||
const adComputer: AdComputer = { ...computer, id };
|
||||
this.adComputers.set(id, adComputer);
|
||||
return adComputer;
|
||||
}
|
||||
|
||||
async updateAdComputer(id: number, computerData: Partial<AdComputer>): Promise<AdComputer | undefined> {
|
||||
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<boolean> {
|
||||
return this.adComputers.delete(id);
|
||||
}
|
||||
|
||||
async listAdComputers(connectionId: number, query?: any): Promise<AdComputer[]> {
|
||||
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<AdDomain | undefined> {
|
||||
return this.adDomains.get(id);
|
||||
}
|
||||
|
||||
async createAdDomain(domain: InsertAdDomain): Promise<AdDomain> {
|
||||
const id = this.adDomainCurrentId++;
|
||||
const adDomain: AdDomain = { ...domain, id };
|
||||
this.adDomains.set(id, adDomain);
|
||||
return adDomain;
|
||||
}
|
||||
|
||||
async updateAdDomain(id: number, domainData: Partial<AdDomain>): Promise<AdDomain | undefined> {
|
||||
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<boolean> {
|
||||
return this.adDomains.delete(id);
|
||||
}
|
||||
|
||||
async listAdDomains(connectionId: number, query?: any): Promise<AdDomain[]> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user