From 0e0f52e9cc0fd387cc94d0df64003a8c49d5560e Mon Sep 17 00:00:00 2001 From: Gijs de Man Date: Mon, 21 Aug 2023 14:35:44 +0200 Subject: [PATCH] Small testing --- src/dovecotAPI.ts | 27 +++++----- src/index.ts | 104 ++++++++++++++++++--------------------- src/localUserDatabase.ts | 61 +++++++++++------------ src/mailcowAPI.ts | 47 ++++-------------- src/mailcowDatabase.ts | 18 +++---- src/types.ts | 9 +--- 6 files changed, 108 insertions(+), 158 deletions(-) diff --git a/src/dovecotAPI.ts b/src/dovecotAPI.ts index ddf225b..f486260 100644 --- a/src/dovecotAPI.ts +++ b/src/dovecotAPI.ts @@ -1,8 +1,7 @@ import axios, { AxiosInstance } from 'axios'; import { - DoveadmExchangeResult, + DovecotData, DovecotRequestData, - DovecotResponseExchange, DovecotPermissions, ActiveDirectoryPermissions, } from './types'; @@ -12,7 +11,6 @@ let dovecotClient: AxiosInstance; export async function initializeDovecotAPI(): Promise { dovecotClient = axios.create({ - // baseURL: `${config.DOVEADM_API_HOST}/doveadm/v1`, baseURL: 'http://172.22.1.250:9000/doveadm/v1', headers: { 'Content-Type': 'text/plain', @@ -25,9 +23,8 @@ export async function initializeDovecotAPI(): Promise { * Get all mailboxes of an email * @param email - email to get all inboxes from */ -async function getMailboxes(email: string): Promise { - // Get all mailboxes - const response = (await dovecotClient.post( +async function getMailboxSubFolders(email: string): Promise { + const mailboxData: DovecotData[] = ((await dovecotClient.post( '', [[ 'mailboxList', @@ -36,16 +33,15 @@ async function getMailboxes(email: string): Promise { }, `mailboxList_${email}`, ]], - )).data as DovecotResponseExchange; + )).data)[0][1]; - // Convert response to array of mailboxes - const mailboxObjects: DoveadmExchangeResult[] = response[0][1]; + let subFolders: string[] = []; + for (let subFolder of mailboxData) { + if (subFolder.mailbox.startsWith('Shared')) continue; + subFolders.push(subFolder.mailbox); + } - return mailboxObjects.filter(function (item) { - return !item.mailbox.startsWith('Shared'); - }).map((item: DoveadmExchangeResult) => { - return item.mailbox; - }); + return subFolders; } /** @@ -74,7 +70,7 @@ export async function setDovecotPermissions(mail: string, users: string[], permi } if (permission == ActiveDirectoryPermissions.mailPermRO || ActiveDirectoryPermissions.mailPermRW) { - mailboxSubFolders = await getMailboxes(mail); + mailboxSubFolders = await getMailboxSubFolders(mail); permissionTag = 'PermRO'; } @@ -103,7 +99,6 @@ export async function setDovecotPermissions(mail: string, users: string[], permi } const dovecotRequest: DovecotRequestData = [ - // Check if users should be removed or added removePermission ? 'aclRemove' : 'aclSet', { 'user': mail, diff --git a/src/index.ts b/src/index.ts index a3f63b8..cfd76be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,10 @@ import { Client } from 'ldapts'; import { - activityUserDB, - addUserDB, + updateLocalUserActivity, + createLocalUser, getLocalUser, - createSOBDB, - getChangedSOBDB, + editLocalUserPermissions, + getUpdateSOBLocalUsers, getUncheckedLocalActiveUsers, initializeLocalUserDatabase, updateLocalUserPermissions, @@ -15,11 +15,10 @@ import { } from 'replace-in-file'; import fs, { PathLike } from 'fs'; import path from 'path'; -import { SearchResult } from 'ldapts/Client'; import { - addUserAPI, + createMailcowUser, getMailcowUser, - editUserAPI, + editMailcowUser, initializeMailcowAPI, } from './mailcowAPI'; import { @@ -40,7 +39,6 @@ import { initializeMailcowDatabase, } from './mailcowDatabase'; -// Set all default variables export const containerConfig: ContainerConfig = { LDAP_URI: '', LDAP_BIND_DN: '', @@ -58,14 +56,13 @@ export const containerConfig: ContainerConfig = { DOVEADM_API_KEY: '', DOVEADM_API_HOST: '', }; -const consoleLogLine = '-'.repeat(process.stdout.columns); +const consoleLogLine: string = '-'.repeat(30); export const sessionTime: number = new Date().getTime(); let activeDirectoryConnector: Client; let activeDirectoryUsers: ActiveDirectoryUser[] = []; export async function getActiveDirectoryDisplayName(mail: string) : Promise { - // TODO can the filter be generalized to top level? const activeDirectoryUser: ActiveDirectoryUser[] = (await activeDirectoryConnector.search(containerConfig.LDAP_BASE_DN, { scope: 'sub', filter: `(&(objectClass=user)(objectCategory=person)(mail=${mail})`, @@ -98,12 +95,12 @@ async function getActiveDirectoryMails(users: string[], skipUser: ActiveDirector * @param permission - type of permission being considered */ async function synchronizeUserACL(activeDirectoryUser: ActiveDirectoryUser, permission: ActiveDirectoryPermissions): Promise { - const activeDirectoryGroup = (await activeDirectoryConnector.search(activeDirectoryUser[permission], { + const activeDirectoryPermissionGroup = (await activeDirectoryConnector.search(activeDirectoryUser[permission], { scope: 'sub', attributes: ['memberFlattened'], })).searchEntries[0] as unknown as ActiveDirectoryUser; - await updateLocalUserPermissions(activeDirectoryUser.mail, activeDirectoryGroup.memberFlattened, permission) + await updateLocalUserPermissions(activeDirectoryUser.mail, activeDirectoryPermissionGroup.memberFlattened, permission) .then(async (changedUsers: ChangedUsers) => { if (changedUsers.newUsers.length != 0) { changedUsers.newUsers = await getActiveDirectoryMails(changedUsers.newUsers, activeDirectoryUser); @@ -122,27 +119,25 @@ async function synchronizeUserACL(activeDirectoryUser: ActiveDirectoryUser, perm ); } -async function synchronizeUserSOB(activeDirectoryUser: ActiveDirectoryUser): Promise { - const activeDirectoryGroup: ActiveDirectoryUser[] = (await activeDirectoryConnector.search(activeDirectoryUser[ActiveDirectoryPermissions.mailPermSOB], { +async function synchronizeUserSOB(activeDirectoryGroup: ActiveDirectoryUser): Promise { + // Should always be one entry + const activeDirectoryPermissionGroup: ActiveDirectoryUser = ((await activeDirectoryConnector.search(activeDirectoryGroup[ActiveDirectoryPermissions.mailPermSOB], { scope: 'sub', attributes: ['memberFlattened'], - })).searchEntries as unknown as ActiveDirectoryUser[]; + })).searchEntries)[0] as unknown as ActiveDirectoryUser; - // Construct list in database with DN of all committees they are in - // Get existing list of committees, add new DN as string - // TODO check, I think this can be the same as syncACL where you just pick first entry instead of looping - for (const members of activeDirectoryGroup) { - // Singular entries are possible, so turn them into an array - if (!Array.isArray(members.memberFlattened)) - members.memberFlattened = [members.memberFlattened]; - - for (const member of members.memberFlattened) { - const memberResults: ActiveDirectoryUser[] = (await activeDirectoryConnector.search(member, { - scope: 'sub', - attributes: ['mail'], - })).searchEntries as unknown as ActiveDirectoryUser[]; - await createSOBDB(memberResults[0].mail, activeDirectoryUser.mail); - } + // Singular entries are possible, so turn them into an array + if (!Array.isArray(activeDirectoryPermissionGroup.memberFlattened)) + activeDirectoryPermissionGroup.memberFlattened = [activeDirectoryPermissionGroup.memberFlattened]; + + // All users are given as DN, so we have to get their mail first + for (const activeDirectoryUserDN of activeDirectoryPermissionGroup.memberFlattened) { + const activeDirectoryUserMail: ActiveDirectoryUser = ((await activeDirectoryConnector.search(activeDirectoryUserDN, { + scope: 'sub', + attributes: ['mail'], + })).searchEntries)[0] as unknown as ActiveDirectoryUser; + // Own group has to be skipped to prevent clashing permissions + await editLocalUserPermissions(activeDirectoryUserMail.mail, activeDirectoryGroup.mail); } } @@ -299,7 +294,7 @@ async function getUserDataFromActiveDirectory(): Promise { })).searchEntries as unknown as ActiveDirectoryUser[]; } if (retryCount === maxRetryCount) throw new Error('Ran into an issue when getting users from Active Directory.'); - console.log('Successfully got all users from Active Directory'); + console.log('Successfully got all users from Active Directory. \n\n'); } @@ -320,14 +315,14 @@ async function synchronizeUsersWithActiveDirectory(): Promise { if (!localUser.exists) { console.log(`Adding local user ${mail} (active: ${isActive})`); - await addUserDB(mail, displayName, isActive); + await createLocalUser(mail, displayName, isActive); localUser.exists = true; localUser.isActive = isActive; } if (!mailcowUser.exists) { console.log(`Adding Mailcow user ${mail} (active: ${isActive})`); - await addUserAPI(mail, displayName, isActive, 256); + await createMailcowUser(mail, displayName, isActive, 256); mailcowUser.exists = true; mailcowUser.isActive = isActive; mailcowUser.displayName = displayName; @@ -335,23 +330,24 @@ async function synchronizeUsersWithActiveDirectory(): Promise { if (localUser.isActive !== isActive) { console.log(`Set ${mail} to active state ${isActive} in local user database`); - await activityUserDB(mail, isActive, 0); + await updateLocalUserActivity(mail, isActive, 0); } if (mailcowUser.isActive !== isActive) { console.log(`Set ${mail} to active state ${isActive} in Mailcow`); - await editUserAPI(mail, { active: isActive }); + await editMailcowUser(mail, { active: isActive }); } if (mailcowUser.displayName !== displayName) { console.log(`Changed displayname for ${mail} to ${displayName} in Mailcow`); - await editUserAPI(mail, { name: displayName }); + await editMailcowUser(mail, { name: displayName }); } } catch (error) { - console.error(`Ran into an issue when syncing user ${activeDirectoryUser.mail}: ${error}`); + console.error(`Ran into an issue when syncing user ${activeDirectoryUser.mail}. \n\n ${error}`); } } + // Users that were not checked might have to be removed from mailcow for (const user of await getUncheckedLocalActiveUsers()) { try { const mailcowUserData: MailcowUserData = await getMailcowUser(user.email); @@ -363,28 +359,29 @@ async function synchronizeUsersWithActiveDirectory(): Promise { if (inactiveCount > maxInactiveCount) { console.log(`Deactivated user ${user.email} in local user database, not found in LDAP`); - await activityUserDB(user.email, 0, 255); + await updateLocalUserActivity(user.email, 0, 255); } else { console.log(`Increased inactive count to ${inactiveCount + 1} for ${user.email}`); - await activityUserDB(user.email, 2, inactiveCount + 1); + await updateLocalUserActivity(user.email, 2, inactiveCount + 1); } - // Check if user is still active, if so, deactivate user if (mailcowUserData.isActive && localUserData.isActive === 0) { - console.log(`Deactivated user ${user.email} in Mailcow, not found in LDAP`); - await editUserAPI(user.email, { active: 0 }); + console.log(`Deactivated user ${user.email} in Mailcow, not found in Active Directory`); + await editMailcowUser(user.email, { active: 0 }); } } catch (error) { - console.log(`Exception throw during handling of ${user}: ${error}`); + console.log(`Ran into an issue when checking inactivity of ${user.email}. \n\n ${error}`); } } - console.log('Successfully synced all users with Active Directory'); + console.log('Successfully synced all users with Active Directory. \n\n'); } async function synchronizePermissionsWithActiveDirectory(): Promise { for (const activeDirectoryUser of activeDirectoryUsers) { try { // Check if current user has corresponding permissions + // Sometimes, the mail considered is a personal account, but it can also be a shared mailbox + // (in principle this does not matter though, personal mails _could_ in principle also be shared if wanted) if (activeDirectoryUser[ActiveDirectoryPermissions.mailPermROInbox].length != 0) await synchronizeUserACL(activeDirectoryUser, ActiveDirectoryPermissions.mailPermROInbox); if (activeDirectoryUser[ActiveDirectoryPermissions.mailPermROSent].length != 0) @@ -396,22 +393,22 @@ async function synchronizePermissionsWithActiveDirectory(): Promise { if (activeDirectoryUser[ActiveDirectoryPermissions.mailPermSOB].length != 0) await synchronizeUserSOB(activeDirectoryUser); } catch (error) { - console.log(`Ran into an issue when syncing permissions of ${activeDirectoryUser.mail}: ${error}`); + console.log(`Ran into an issue when syncing permissions of ${activeDirectoryUser.mail}. \n\n ${error}`); } } - for (const activeDirectoryUser of await getChangedSOBDB()) { + for (const activeDirectoryUser of await getUpdateSOBLocalUsers()) { try { console.log(`Changing SOB of ${activeDirectoryUser.email}`); const SOBs: string[] = activeDirectoryUser.mailPermSOB.split(';'); - await editUserAPI(activeDirectoryUser.email, { sender_acl: SOBs }); + await editMailcowUser(activeDirectoryUser.email, { sender_acl: SOBs }); await editUserSignature(activeDirectoryUser, SOBs); } catch (error) { - console.log(`Exception throw during handling of ${activeDirectoryUser}: ${error}`); + console.log(`Ran into an issue when syncing send on behalf of ${activeDirectoryUser.email}. \n\n ${error}`); } } - console.log('Successfully synced all permissions with Active Directory'); + console.log('Successfully synced all permissions with Active Directory. \n\n'); } /** @@ -449,7 +446,7 @@ async function initializeSync(): Promise { .catch((error) => { throw new Error('Ran into an issue when reading extra.conf. \n\n' + error); }); - console.log('Successfully adjusted all template files.'); + console.log('Successfully adjusted all template files. \n\n'); console.log(consoleLogLine + '\n APPLYING CONFIG FILES \n' + consoleLogLine); const passDBConfigChanged: boolean = applyConfig('./conf/dovecot/ldap/passdb.conf', passDBConfig); @@ -459,7 +456,6 @@ async function initializeSync(): Promise { console.warn('One or more config files have been changed, please restart dovecot-mailcow and sogo-mailcow.'); console.log('Successfully applied all config files \n\n'); - // Start 'connection' with database console.log(consoleLogLine + '\n INITIALIZING DATABASES AND API CLIENTS \n' + consoleLogLine); await initializeLocalUserDatabase(); await initializeMailcowDatabase(); @@ -467,8 +463,7 @@ async function initializeSync(): Promise { await initializeDovecotAPI(); console.log('Successfully initialized all databases and API clients \n\n'); - // Start sync loop every interval milliseconds - console.log(consoleLogLine + '\n GETTING USERS FROM LDAP \n' + consoleLogLine); + console.log(consoleLogLine + '\nGETTING USERS FROM ACTIVE DIRECTORY\n' + consoleLogLine); await getUserDataFromActiveDirectory(); console.log(consoleLogLine + '\n SYNCING ALL USERS \n' + consoleLogLine); @@ -476,9 +471,6 @@ async function initializeSync(): Promise { console.log(consoleLogLine + '\n SYNCING ALL PERMISSIONS \n' + consoleLogLine); await synchronizePermissionsWithActiveDirectory(); - - console.log(consoleLogLine + '\n CHECKING INACTIVE USERS \n' + consoleLogLine); - await synchronize(); } /** diff --git a/src/localUserDatabase.ts b/src/localUserDatabase.ts index df25830..8799274 100644 --- a/src/localUserDatabase.ts +++ b/src/localUserDatabase.ts @@ -4,17 +4,8 @@ import fs from 'fs'; import { ActiveDirectoryPermissions, ChangedUsers, ActiveUserSetting, LocalUserData } from './types'; import { sessionTime } from './index'; -// Connection options for the DB -const dataSource = new DataSource({ - type: 'sqlite', - database: './db/ldap-mailcow.sqlite3', - entities: [ - Users, - ], - synchronize: true, -}); - let localUserRepository: Repository; +let dataSource: DataSource; /** * Initialize database connection. Setup database if it does not yet exist @@ -22,6 +13,16 @@ let localUserRepository: Repository; export async function initializeLocalUserDatabase(): Promise { if (!fs.existsSync('./db/ldap-mailcow.sqlite3')) fs.writeFileSync('./db/ldap-mailcow.sqlite3', ''); + + dataSource = new DataSource({ + type: 'sqlite', + database: './db/ldap-mailcow.sqlite3', + entities: [ + Users, + ], + synchronize: true, + }); + dataSource.initialize().catch((error) => console.log(error)); localUserRepository = dataSource.getRepository(Users); } @@ -41,13 +42,13 @@ export async function getUncheckedLocalActiveUsers(): Promise { /** * Add a user to the DB - * @param email - mail entry in the database + * @param mail - mail entry in the database * @param displayName * @param active - whether user is active */ -export async function addUserDB(email: string, displayName: string, active: ActiveUserSetting): Promise { +export async function createLocalUser(mail: string, displayName: string, active: ActiveUserSetting): Promise { const user: Users = Object.assign(new Users(), { - email: email, + email: mail, active: active, displayName: displayName, inactiveCount: 0, @@ -68,9 +69,9 @@ export async function addUserDB(email: string, displayName: string, active: Acti /** * Get a user data from database - * @param email - mail from to be retrieved user + * @param mail - mail from to be retrieved user */ -export async function getLocalUser(email: string): Promise { +export async function getLocalUser(mail: string): Promise { const localUserData: LocalUserData = { exists: false, isActive: 0, @@ -79,7 +80,7 @@ export async function getLocalUser(email: string): Promise { const localUser: Users | null = await localUserRepository.findOne({ where: { - email: email, + email: mail, }, }); @@ -98,18 +99,16 @@ export async function getLocalUser(email: string): Promise { /** * Change user activity status in the DB - * @param email - email of user + * @param mail - email of user * @param active - activity of user * @param inactiveCount - number of times user has been inactive */ -export async function activityUserDB(email: string, active: ActiveUserSetting, inactiveCount: number): Promise { - // Retrieve user with email +export async function updateLocalUserActivity(mail: string, active: ActiveUserSetting, inactiveCount: number): Promise { const user: Users = await localUserRepository.findOneOrFail({ where: { - email: email, + email: mail, }, }); - // Set new activity of user user.active = active; user.inactiveCount = inactiveCount; await localUserRepository.update(user.email, user); @@ -117,19 +116,18 @@ export async function activityUserDB(email: string, active: ActiveUserSetting, i /** * Update user's SOB - * @param email - email of user + * @param mail - email of user * @param SOBEmail - acl to check */ -export async function createSOBDB(email: string, SOBEmail: string): Promise { - // Retrieve user with email +export async function editLocalUserPermissions(mail: string, SOBEmail: string): Promise { const user: Users = await localUserRepository.findOneOrFail({ where: { - email: email, + email: mail, }, }); // Check if permissions for ACL are set - const SOB = !user.newMailPermSOB ? [] : user.newMailPermSOB.split(';'); + const SOB: string[] = !user.newMailPermSOB ? [] : user.newMailPermSOB.split(';'); // Check if sob mail is in list (it should not be, but checking does not hurt) if (SOB.indexOf(SOBEmail) === -1) { @@ -139,14 +137,13 @@ export async function createSOBDB(email: string, SOBEmail: string): Promise { - // First, check all users that actually have changed - const users = await localUserRepository.find(); +export async function getUpdateSOBLocalUsers(): Promise { + const users: Users[] = await localUserRepository.find(); const changedUsers : Users[] = []; for (const user of users) { if (user.newMailPermSOB != user.mailPermSOB) { - console.log(`SOB of ${user.email} changed from ${user.mailPermSOB} to ${user.newMailPermSOB}`); + console.log(`SOB of ${user.email} changed from ${user.mailPermSOB} to ${user.newMailPermSOB}.`); user.mailPermSOB = user.newMailPermSOB; changedUsers.push(user); } @@ -182,8 +179,8 @@ export async function updateLocalUserPermissions(mail: string, newUsers: string[ // Filter for users, also filter empty entries const removedUsers : string[] = !user ? [] : user[permission].split(';'); - changedUsers.newUsers = newUsers.filter(x => !removedUsers.includes(x) && x != ''); - changedUsers.removedUsers = removedUsers.filter(x => !newUsers.includes(x) && x != ''); + changedUsers.newUsers = newUsers.filter((innerUser: string) => !removedUsers.includes(innerUser) && innerUser != ''); + changedUsers.removedUsers = removedUsers.filter((innerUser: string) => !newUsers.includes(innerUser) && innerUser != ''); user[permission] = newUsers.join(';'); await localUserRepository.update(user.email, user); diff --git a/src/mailcowAPI.ts b/src/mailcowAPI.ts index 5fc7ae0..3678323 100644 --- a/src/mailcowAPI.ts +++ b/src/mailcowAPI.ts @@ -1,7 +1,6 @@ import MailCowClient from 'ts-mailcow-api'; import { ACLEditRequest, - MailboxDeleteRequest, MailboxEditRequest, MailboxPostRequest, } from 'ts-mailcow-api/src/types'; @@ -13,8 +12,8 @@ import { } from 'ts-mailcow-api/dist/types'; import { containerConfig } from './index'; +const passwordLength: number = 32; let mailcowClient: MailCowClient; -const passwordLength = 32; /** * Initialize database connection. Setup database if it does not yet exist @@ -36,10 +35,10 @@ export async function initializeMailcowAPI(): Promise { * @param length - length of random password */ function generatePassword(length: number): string { - let result = ''; - const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result: string = ''; + const characters: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength: number = characters.length; - for (let i = 0; i < length; i++) + for (let i: number = 0; i < length; i++) result += characters.charAt(Math.floor(Math.random() * charactersLength)); return result; } @@ -51,11 +50,9 @@ function generatePassword(length: number): string { * @param active - activity of the new user * @param quotum - mailbox size of the new user */ -export async function addUserAPI(email: string, name: string, active: number, quotum: number): Promise { - // Generate password +export async function createMailcowUser(email: string, name: string, active: number, quotum: number): Promise { const password: string = generatePassword(passwordLength); - // Set details of the net mailbox const mailboxData: MailboxPostRequest = { // Active: 0 = no incoming mail/no login, 1 = allow both, 2 = custom state: allow incoming mail/no login 'active': active, @@ -70,33 +67,22 @@ export async function addUserAPI(email: string, name: string, active: number, qu 'tls_enforce_out': false, }; - // Create mailbox await mailcowClient.mailbox.create(mailboxData); - // Set ACL data of new mailbox const aclData: ACLEditRequest = { 'items': email, 'attr': { 'user_acl': [ 'spam_alias', - //"tls_policy", 'spam_score', 'spam_policy', 'delimiter_action', - // "syncjobs", - // "eas_reset", - // "sogo_profile_reset", 'quarantine', - // "quarantine_attachments", 'quarantine_notification', - // "quarantine_category", - // "app_passwds", - // "pushover" ], }, }; - // Adjust ACL data of new mailbox await mailcowClient.mailbox.editUserACL(aclData); } @@ -105,24 +91,13 @@ export async function addUserAPI(email: string, name: string, active: number, qu * @param email - email of user to be edited * @param options - options to be edited */ -// Todo add send from ACLs -export async function editUserAPI(email: string, options: Partial): Promise { +export async function editMailcowUser(email: string, options: Partial): Promise { const mailboxData: MailboxEditRequest = { 'items': [email], 'attr': options, }; - await mailcowClient.mailbox.edit(mailboxData); -} -/** - * Delete user from Mailcow - * @param email - */ -export async function deleteUserAPI(email: string): Promise { - const mailboxData: MailboxDeleteRequest = { - 'mailboxes': [email], - }; - await mailcowClient.mailbox.delete(mailboxData); + await mailcowClient.mailbox.edit(mailboxData); } /** @@ -135,13 +110,9 @@ export async function getMailcowUser(email: string): Promise { isActive: 0, }; - // Get mailbox data from user with email - const mailboxData: Mailbox = (await mailcowClient.mailbox.get(email) - .catch(e => { - throw new Error(e); - }))[0]; + // Should only find one user + const mailboxData: Mailbox = (await mailcowClient.mailbox.get(email))[0]; - // If no data, return immediately, otherwise return response data if (!(Object.keys(mailboxData).length === 0 && mailboxData.constructor === Object)) { userData.exists = true; userData.isActive = mailboxData.active_int; diff --git a/src/mailcowDatabase.ts b/src/mailcowDatabase.ts index 9d2cff9..d3b8cf4 100644 --- a/src/mailcowDatabase.ts +++ b/src/mailcowDatabase.ts @@ -43,24 +43,24 @@ export async function initializeMailcowDatabase(): Promise { export async function editUserSignature(user: Users, SOBs: string[]): Promise { console.log(`Changing signatures for ${user.email}`); - let profile = await SogoUserProfileRepository.findOneOrFail({ + let userProfile: SogoUserProfile = await SogoUserProfileRepository.findOneOrFail({ where: { c_uid: user.email, }, }); - let cDefaults : Defaults = JSON.parse(profile.c_defaults); - let newIdentities : SOGoMailIdentity[] = []; + let defaultSettings: Defaults = JSON.parse(userProfile.c_defaults); + let newIdentities: SOGoMailIdentity[] = []; - for (let identity of cDefaults.SOGoMailIdentities) { + for (let identity of defaultSettings.SOGoMailIdentities) { if (identity.signature.indexOf('class="autogenerated"') === -1) { newIdentities.push(identity); } } for (let identityMail of SOBs) { - const committeeDisplayName = await getActiveDirectoryDisplayName(identityMail); - let signature : string = (await axios.get(`https://signature.gewis.nl/${identityMail}`)).data; + const committeeDisplayName: string = await getActiveDirectoryDisplayName(identityMail); + let signature: string = (await axios.get(`https://signature.gewis.nl/${identityMail}`)).data; signature = signature.replace('{{displayName}}', user.displayName); signature = signature.replaceAll('{{committeeDisplayName}}', committeeDisplayName); signature = signature.replaceAll('{{identityMail}}', identityMail); @@ -76,8 +76,8 @@ export async function editUserSignature(user: Users, SOBs: string[]): Promise