Skip to content

Commit

Permalink
Fix newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
Gijsdeman committed Dec 1, 2023
1 parent 86a9766 commit 6439af5
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 221 deletions.
135 changes: 1 addition & 134 deletions src/dovecotAPI.ts
Original file line number Diff line number Diff line change
@@ -1,134 +1 @@
import axios, { AxiosInstance } from 'axios';
import {
DovecotData,
DovecotRequestData,
DovecotPermissions,
ActiveDirectoryPermissions,
} from './types';
import { containerConfig } from './index';

let dovecotClient: AxiosInstance;

/**
* Initialize the Dovecot API
*/
export async function initializeDovecotAPI(): Promise<void> {
dovecotClient = axios.create({
baseURL: 'http://172.22.1.250:9000/doveadm/v1',
headers: {
'Content-Type': 'text/plain',
'Authorization': `X-Dovecot-API ${Buffer.from(containerConfig.DOVEADM_API_KEY).toString('base64')}`,
},
});
}

/**
* Get all mailbox subfolders of a mail
* @param mail - email to get all subfolders from
*/
async function getMailboxSubFolders(mail: string): Promise<string[]> {
const mailboxData: DovecotData[] = ((await dovecotClient.post(
'',
[[
'mailboxList',
{
'user': mail,
},
`mailboxList_${mail}`,
]],
)).data)[0][1];

let subFolders: string[] = [];
for (let subFolder of mailboxData) {
if (subFolder.mailbox.startsWith('Shared')) continue;
subFolders.push(subFolder.mailbox);
}

return subFolders;
}

/**
* Set read and write permissions in dovecot
* @param mail - mail for which permissions should be set
* @param users - users that will be getting permissions to the above mail
* @param permission - permissions that will be set
* @param removePermission - whether permissions should be removed or added
*/
export async function setDovecotPermissions(mail: string, users: string[], permission: ActiveDirectoryPermissions, removePermission: boolean) {
let mailboxSubFolders: string[] = [];
let permissionTag;

if (permission == ActiveDirectoryPermissions.mailPermROInbox) {
mailboxSubFolders = mailboxSubFolders.concat(['INBOX', 'Inbox']);
permissionTag = 'PermROInbox';
}

if (permission == ActiveDirectoryPermissions.mailPermROSent) {
if (permissionTag === null) {
permissionTag = 'PermROSent';
} else {
permissionTag = 'PermROInboxSent';
}
mailboxSubFolders.push('Sent');
}

if (permission == ActiveDirectoryPermissions.mailPermRO || ActiveDirectoryPermissions.mailPermRW) {
mailboxSubFolders = await getMailboxSubFolders(mail);
permissionTag = 'PermRO';
}

// Dovecot API requests are very unclear and badly documented
// The idea; you can create an array of requests and send it as one big request
const dovecotRequests : DovecotRequestData[] = [];
for (const subFolder of mailboxSubFolders) {
for (const user of users) {

let rights = [
DovecotPermissions.lookup,
DovecotPermissions.read,
DovecotPermissions.write,
DovecotPermissions.write_seen,
];

if (permission === ActiveDirectoryPermissions.mailPermRW) {
rights = rights.concat([
DovecotPermissions.write_deleted,
DovecotPermissions.insert,
DovecotPermissions.post,
DovecotPermissions.expunge,
DovecotPermissions.create,
DovecotPermissions.delete,
]);
}

const dovecotRequest: DovecotRequestData = [
removePermission ? 'aclRemove' : 'aclSet',
{
'user': mail,
'id': `user=${user}`,
'mailbox': subFolder,
'right': rights,
},
permission === ActiveDirectoryPermissions.mailPermRW ? `PermRW_${mail}_${user}` : `${permissionTag}_${mail}_${user}`,
];

dovecotRequests.push(dovecotRequest);
}
}

// There is a max size of the requests
// Break them up in smaller pieces if necessary
// NOTE from Dovecot docs: It is not guaranteed that requests are processed in order or that the doveadm server does not crash
const dovecotMaxRequestSize: number = 20;
if (dovecotRequests.length > dovecotMaxRequestSize) {
for (let requestsDone: number = 0; requestsDone < dovecotRequests.length; requestsDone += dovecotMaxRequestSize) {
await dovecotClient.post(
'', dovecotRequests.slice(requestsDone, requestsDone + dovecotMaxRequestSize),
);
}
} else {
await dovecotClient.post(
'', dovecotRequests,
);
}
}
import axios, { AxiosInstance } from 'axios';import { DovecotData, DovecotRequestData, DovecotPermissions, ActiveDirectoryPermissions,} from './types';import { containerConfig } from './index';let dovecotClient: AxiosInstance;/** * Initialize the Dovecot API */export async function initializeDovecotAPI(): Promise<void> { dovecotClient = axios.create({ baseURL: 'http://172.22.1.250:9000/doveadm/v1', headers: { 'Content-Type': 'text/plain', 'Authorization': `X-Dovecot-API ${Buffer.from(containerConfig.DOVEADM_API_KEY).toString('base64')}`, }, });}/** * Get all mailbox subfolders of a mail * @param mail - email to get all subfolders from */async function getMailboxSubFolders(mail: string): Promise<string[]> { const mailboxData: DovecotData[] = ((await dovecotClient.post( '', [[ 'mailboxList', { 'user': mail, }, `mailboxList_${mail}`, ]], )).data)[0][1]; let subFolders: string[] = []; for (let subFolder of mailboxData) { if (subFolder.mailbox.startsWith('Shared')) continue; subFolders.push(subFolder.mailbox); } return subFolders;}/** * Set read and write permissions in dovecot * @param mail - mail for which permissions should be set * @param users - users that will be getting permissions to the above mail * @param permission - permissions that will be set * @param removePermission - whether permissions should be removed or added */export async function setDovecotPermissions(mail: string, users: string[], permission: ActiveDirectoryPermissions, removePermission: boolean) { let mailboxSubFolders: string[] = []; let permissionTag; if (permission == ActiveDirectoryPermissions.mailPermROInbox) { mailboxSubFolders = mailboxSubFolders.concat(['INBOX', 'Inbox']); permissionTag = 'PermROInbox'; } if (permission == ActiveDirectoryPermissions.mailPermROSent) { if (permissionTag === null) { permissionTag = 'PermROSent'; } else { permissionTag = 'PermROInboxSent'; } mailboxSubFolders.push('Sent'); } if (permission == ActiveDirectoryPermissions.mailPermRO || ActiveDirectoryPermissions.mailPermRW) { mailboxSubFolders = await getMailboxSubFolders(mail); permissionTag = 'PermRO'; } // Dovecot API requests are very unclear and badly documented // The idea; you can create an array of requests and send it as one big request const dovecotRequests : DovecotRequestData[] = []; for (const subFolder of mailboxSubFolders) { for (const user of users) { let rights = [ DovecotPermissions.lookup, DovecotPermissions.read, DovecotPermissions.write, DovecotPermissions.write_seen, ]; if (permission === ActiveDirectoryPermissions.mailPermRW) { rights = rights.concat([ DovecotPermissions.write_deleted, DovecotPermissions.insert, DovecotPermissions.post, DovecotPermissions.expunge, DovecotPermissions.create, DovecotPermissions.delete, ]); } const dovecotRequest: DovecotRequestData = [ removePermission ? 'aclRemove' : 'aclSet', { 'user': mail, 'id': `user=${user}`, 'mailbox': subFolder, 'right': rights, }, permission === ActiveDirectoryPermissions.mailPermRW ? `PermRW_${mail}_${user}` : `${permissionTag}_${mail}_${user}`, ]; dovecotRequests.push(dovecotRequest); } } // There is a max size of the requests // Break them up in smaller pieces if necessary // NOTE from Dovecot docs: It is not guaranteed that requests are processed in order or that the doveadm server does not crash const dovecotMaxRequestSize: number = 20; if (dovecotRequests.length > dovecotMaxRequestSize) { for (let requestsDone: number = 0; requestsDone < dovecotRequests.length; requestsDone += dovecotMaxRequestSize) { await dovecotClient.post( '', dovecotRequests.slice(requestsDone, requestsDone + dovecotMaxRequestSize), ); } } else { await dovecotClient.post( '', dovecotRequests, ); }}
Expand Down
174 changes: 87 additions & 87 deletions src/mailcowDatabase.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,88 @@
import {
DataSource,
Repository,
} from 'typeorm';
import {
Defaults,
SOGoMailIdentity,
} from './types';
import { SogoUserProfile } from './entities/SogoUserProfile';
import { Users } from './entities/User';
import { getActiveDirectoryDisplayName } from './index';
import axios from 'axios';
import { containerConfig } from './index';

// Connection options for the DB
let dataSource : DataSource;
let SogoUserProfileRepository: Repository<SogoUserProfile>;

/**
* Initialize database connection. Setup database if it does not yet exist
*/
export async function initializeMailcowDatabase(): Promise<void> {
dataSource = new DataSource({
type: 'mariadb',
host: '172.22.1.251',
port: 3306,
username: 'mailcow',
password: containerConfig.DB_PASSWORD,
database: 'mailcow',
entities: [
SogoUserProfile,
],
});

await dataSource.initialize()
.catch((error) => {
console.log(error);
});

SogoUserProfileRepository = dataSource.getRepository(SogoUserProfile);
}

/**
* Edit the signatures of a user
* @param user - user to edit the signatures of
* @param SOBs - all SOB for which the user should get signatures
*/
export async function editUserSignatures(user: Users, SOBs: string[]): Promise<void> {
console.log(`Changing signatures for ${user.email}`);

let userProfile: SogoUserProfile = await SogoUserProfileRepository.findOneOrFail({
where: {
c_uid: user.email,
},
});

let defaultSettings: Defaults = JSON.parse(userProfile.c_defaults);
let newIdentities: SOGoMailIdentity[] = [];

for (let identity of defaultSettings.SOGoMailIdentities) {
if (identity.signature.indexOf('class="autogenerated"') === -1) {
newIdentities.push(identity);
}
}

for (let identityMail of SOBs) {
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);

signature.replaceAll('', '');

let newIdentity : SOGoMailIdentity = {
email: identityMail,
fullName: `${user.displayName} | ${committeeDisplayName}`,
replyTo: user.email,
signature: `${signature}`,
};
newIdentities.push(newIdentity);
}

defaultSettings.SOGoMailIdentities = newIdentities;
userProfile.c_defaults = JSON.stringify(defaultSettings);

await SogoUserProfileRepository.update(user.email, userProfile);
import {
DataSource,
Repository,
} from 'typeorm';
import {
Defaults,
SOGoMailIdentity,
} from './types';
import { SogoUserProfile } from './entities/SogoUserProfile';
import { Users } from './entities/User';
import { getActiveDirectoryDisplayName } from './index';
import axios from 'axios';
import { containerConfig } from './index';

// Connection options for the DB
let dataSource : DataSource;
let SogoUserProfileRepository: Repository<SogoUserProfile>;

/**
* Initialize database connection. Setup database if it does not yet exist
*/
export async function initializeMailcowDatabase(): Promise<void> {
dataSource = new DataSource({
type: 'mariadb',
host: '172.22.1.251',
port: 3306,
username: 'mailcow',
password: containerConfig.DB_PASSWORD,
database: 'mailcow',
entities: [
SogoUserProfile,
],
});

await dataSource.initialize()
.catch((error) => {
console.log(error);
});

SogoUserProfileRepository = dataSource.getRepository(SogoUserProfile);
}

/**
* Edit the signatures of a user
* @param user - user to edit the signatures of
* @param SOBs - all SOB for which the user should get signatures
*/
export async function editUserSignatures(user: Users, SOBs: string[]): Promise<void> {
console.log(`Changing signatures for ${user.email}`);

let userProfile: SogoUserProfile = await SogoUserProfileRepository.findOneOrFail({
where: {
c_uid: user.email,
},
});

let defaultSettings: Defaults = JSON.parse(userProfile.c_defaults);
let newIdentities: SOGoMailIdentity[] = [];

for (let identity of defaultSettings.SOGoMailIdentities) {
if (identity.signature.indexOf('class="autogenerated"') === -1) {
newIdentities.push(identity);
}
}

for (let identityMail of SOBs) {
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);

signature.replaceAll('', '');

let newIdentity : SOGoMailIdentity = {
email: identityMail,
fullName: `${user.displayName} | ${committeeDisplayName}`,
replyTo: user.email,
signature: `${signature}`,
};
newIdentities.push(newIdentity);
}

defaultSettings.SOGoMailIdentities = newIdentities;
userProfile.c_defaults = JSON.stringify(defaultSettings);

await SogoUserProfileRepository.update(user.email, userProfile);
}

0 comments on commit 6439af5

Please sign in to comment.