Skip to content

Commit

Permalink
refactor: moves EmailInbox to custom model methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardogarim committed May 25, 2024
1 parent 6551356 commit 7df2f55
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 27 deletions.
15 changes: 6 additions & 9 deletions apps/meteor/app/api/server/lib/emailInbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ export const findEmailInboxes = async ({
};
};

export const findOneEmailInbox = async ({ _id }: { _id: string }): Promise<IEmailInbox | null> => {
return EmailInbox.findOneById(_id);
};
export const insertOneEmailInbox = async (
userId: string,
emailInboxParams: Pick<IEmailInbox, 'active' | 'name' | 'email' | 'description' | 'senderInfo' | 'department' | 'smtp' | 'imap'>,
Expand All @@ -50,7 +47,7 @@ export const insertOneEmailInbox = async (
_createdBy: await Users.findOneById(userId, { projection: { username: 1 } }),
};

const response = await EmailInbox.insertOne(obj);
const response = await EmailInbox.create(obj);

if (response.insertedId) {
void notifyOnEmailInboxChanged({ _id: response.insertedId, ...obj }, 'inserted');
Expand Down Expand Up @@ -79,24 +76,24 @@ export const updateEmailInbox = async (
...(department === 'All' && { $unset: { department: 1 as const } }),
};

const updateResponse = await EmailInbox.findOneAndUpdate({ _id }, updateEmailInbox, { returnDocument: 'after', projection: { _id: 1 } });
const updatedResponse = await EmailInbox.updateById(_id, updateEmailInbox);

if (updateResponse.value) {
if (updatedResponse.value) {
void notifyOnEmailInboxChanged(
{
...updateResponse.value,
...updatedResponse.value,
...(department === 'All' && { department: undefined }),
},
'updated',
);
}

// Maintained to preserve the same behavior as the previous version
if (!updateResponse.value) {
if (!updatedResponse.value) {
throw new Error('error-invalid-email-inbox');
}

return updateResponse.value;
return updatedResponse.value;
};

export const removeEmailInbox = async (emailInboxId: IEmailInbox['_id']): Promise<DeleteResult> => {
Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/app/api/server/v1/email-inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { check, Match } from 'meteor/check';
import { sendTestEmailToInbox } from '../../../../server/features/EmailInbox/EmailInbox_Outgoing';
import { API } from '../api';
import { getPaginationItems } from '../helpers/getPaginationItems';
import { insertOneEmailInbox, findEmailInboxes, findOneEmailInbox, updateEmailInbox, removeEmailInbox } from '../lib/emailInbox';
import { insertOneEmailInbox, findEmailInboxes, updateEmailInbox, removeEmailInbox } from '../lib/emailInbox';

API.v1.addRoute(
'email-inbox.list',
Expand Down Expand Up @@ -90,7 +90,7 @@ API.v1.addRoute(
if (!_id) {
throw new Error('error-invalid-param');
}
const emailInbox = await findOneEmailInbox({ _id });
const emailInbox = await EmailInbox.findById(_id);

if (!emailInbox) {
return API.v1.notFound();
Expand Down Expand Up @@ -132,7 +132,7 @@ API.v1.addRoute(

// TODO: Chapter day backend - check if user has permission to view this email inbox instead of null values
// TODO: Chapter day: Remove this endpoint and move search to GET /email-inbox
const emailInbox = await EmailInbox.findOne({ email });
const emailInbox = await EmailInbox.findByEmail(email);

return API.v1.success({ emailInbox });
},
Expand All @@ -152,7 +152,7 @@ API.v1.addRoute(
if (!_id) {
throw new Error('error-invalid-param');
}
const emailInbox = await findOneEmailInbox({ _id });
const emailInbox = await EmailInbox.findById(_id);

if (!emailInbox) {
return API.v1.notFound();
Expand Down
13 changes: 5 additions & 8 deletions apps/meteor/server/email/IMAPInterceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,13 @@ export class IMAPInterceptor extends EventEmitter {

async selfDisable(): Promise<void> {
logger.info(`Disabling inbox ${this.inboxId}`);

// Again, if there's 2 inboxes with the same email, this will prevent looping over the already disabled one
// Active filter is just in case :)
const { value: emailInbox } = await EmailInbox.findOneAndUpdate(
{ _id: this.inboxId, active: true },
{ $set: { active: false } },
{ returnDocument: 'after' },
);

if (emailInbox) {
void notifyOnEmailInboxChanged(emailInbox, 'updated');
const { value } = await EmailInbox.setDisabledById(this.inboxId);

if (value) {
void notifyOnEmailInboxChanged(value, 'updated');
}

logger.info(`IMAP inbox ${this.inboxId} automatically disabled`);
Expand Down
4 changes: 1 addition & 3 deletions apps/meteor/server/features/EmailInbox/EmailInbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ export type Inbox = {
export const inboxes = new Map<string, Inbox>();

export async function configureEmailInboxes(): Promise<void> {
const emailInboxesCursor = EmailInbox.find({
active: true,
});
const emailInboxesCursor = EmailInbox.findActiveEmailInboxes();

logger.info('Clearing old email inbox registrations');
for (const { imap } of inboxes.values()) {
Expand Down
30 changes: 29 additions & 1 deletion apps/meteor/server/models/raw/EmailInbox.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IEmailInbox, RocketChatRecordDeleted } from '@rocket.chat/core-typings';
import type { IEmailInboxModel } from '@rocket.chat/model-typings';
import type { Collection, Db, IndexDescription } from 'mongodb';
import type { Collection, Db, DeleteResult, FindCursor, IndexDescription, InsertOneResult, ModifyResult, UpdateFilter } from 'mongodb';

import { BaseRaw } from './BaseRaw';

Expand All @@ -12,4 +12,32 @@ export class EmailInboxRaw extends BaseRaw<IEmailInbox> implements IEmailInboxMo
protected modelIndexes(): IndexDescription[] {
return [{ key: { email: 1 }, unique: true }];
}

async setDisabledById(id: IEmailInbox['_id']): Promise<ModifyResult<IEmailInbox>> {
return this.findOneAndUpdate({ _id: id, active: true }, { $set: { active: false } }, { returnDocument: 'after' });
}

async removeById(id: IEmailInbox['_id']): Promise<DeleteResult> {
return this.deleteOne({ _id: id });
}

async create(emailInbox: IEmailInbox): Promise<InsertOneResult<IEmailInbox>> {
return this.insertOne(emailInbox);
}

async updateById(id: IEmailInbox['_id'], data: UpdateFilter<IEmailInbox>): Promise<ModifyResult<IEmailInbox>> {
return this.findOneAndUpdate({ _id: id }, data, { returnDocument: 'after', projection: { _id: 1 } });
}

findActiveEmailInboxes(): FindCursor<IEmailInbox> {
return this.find({ active: true });
}

async findByEmail(email: IEmailInbox['email']): Promise<IEmailInbox | null> {
return this.findOne({ email });
}

async findById(id: IEmailInbox['_id']): Promise<IEmailInbox | null> {
return this.findOne({ _id: id });
}
}
10 changes: 8 additions & 2 deletions packages/model-typings/src/models/IEmailInboxModel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type { IEmailInbox } from '@rocket.chat/core-typings';
import type { DeleteResult, FindCursor, InsertOneResult, ModifyResult, UpdateFilter } from 'mongodb';

import type { IBaseModel } from './IBaseModel';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IEmailInboxModel extends IBaseModel<IEmailInbox> {
//
setDisabledById(id: IEmailInbox['_id']): Promise<ModifyResult<IEmailInbox>>;
removeById(id: IEmailInbox['_id']): Promise<DeleteResult>;
create(emailInbox: Omit<IEmailInbox, '_id'>): Promise<InsertOneResult<IEmailInbox>>;
updateById(id: IEmailInbox['_id'], data: UpdateFilter<IEmailInbox>): Promise<ModifyResult<IEmailInbox>>;
findActiveEmailInboxes(): FindCursor<IEmailInbox>;
findByEmail(email: IEmailInbox['email']): Promise<IEmailInbox | null>;
findById(id: IEmailInbox['_id']): Promise<IEmailInbox | null>;
}

0 comments on commit 7df2f55

Please sign in to comment.