-
Notifications
You must be signed in to change notification settings - Fork 4
feat(imap) module #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(imap) module #143
Changes from 1 commit
c43f8f1
a01331b
631d89a
4f43fdb
620be6f
c0ab5ca
0005f8e
e4c77cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
|
|
||
|
||
| export interface IMapCustomer { | ||
| inboxIntegrationId: string; | ||
| contactsId: string; | ||
| email: string; | ||
| firstName?: string; | ||
| lastName?: string; | ||
| integrationId?: string; | ||
| } | ||
|
|
||
| export interface IMapCustomerDocument extends IMapCustomer, Document {} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| export interface IMapIntegration { | ||
|
||
| inboxId: string; | ||
| host: string; | ||
| smtpHost: string; | ||
| smtpPort: string; | ||
| mainUser: string; | ||
| user: string; | ||
| password: string; | ||
|
Comment on lines
+6
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainStore credentials securely The interface stores sensitive data like password as plain text. This could pose a security risk if database records are exposed. Consider implementing credential encryption at rest. One approach is to use environment-specific encryption keys to encrypt sensitive fields before storage and decrypt when needed. 🏁 Script executed: #!/bin/bash
# Check if other sensitive fields are stored securely in the codebase
echo "Checking for credential storage patterns in the codebase..."
rg -i "password.*string|secret.*string|token.*string" --type tsLength of output: 16805 🏁 Script executed: #!/bin/bash
set -e
echo "Inspecting IMAP integration DB definitions around 'password'..."
rg -A 5 -n "password" backend/plugins/frontline_api/src/modules/integrations/imap/db/definitions/integrations.ts
echo
echo "Searching for any encryption-related code or libraries in the repo..."
rg -i --context 3 "encrypt" .Length of output: 2149 Encrypt IMAP integration credentials at rest The IMAP integration’s • backend/plugins/frontline_api/src/modules/integrations/imap/@types/integrations.ts password: string;• backend/plugins/frontline_api/src/modules/integrations/imap/db/definitions/integrations.ts password: String,Our searches (
🤖 Prompt for AI Agents |
||
| healthStatus?: string; | ||
| error?: string; | ||
| lastFetchDate?: Date; | ||
| } | ||
|
|
||
| export interface IMapIntegrationDocument extends IMapIntegration, Document {} | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Document } from 'mongoose'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface IMapMail { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| address: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface IMapMail { | |
| name: string; | |
| address: string; | |
| } | |
| export interface IMapMail { | |
| name: string; | |
| address: string; | |
| } |
🤖 Prompt for AI Agents
In
backend/plugins/frontline_api/src/modules/integrations/imap/@types/messages.ts
around lines 3 to 6, the IMapMail interface is declared but not exported. To fix
this, add the export keyword before the interface declaration so it can be used
in other files that import it.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add inReplyTo and references fields to match schema
The IMapMessage interface is missing the inReplyTo and references fields that exist in the Mongoose schema. This could cause inconsistency between the TypeScript interface and the database schema.
export interface IMapMessage {
inboxIntegrationId: string;
inboxConversationId: string;
messageId: string;
+ inReplyTo?: string;
+ references?: string[];
subject: string;
body: string;
to: IMapMail[];
cc: IMapMail[];
bcc: IMapMail[];
from: IMapMail[];
attachments?: IMapAttachmentParams[];
createdAt: Date;
+ type: 'SENT' | 'INBOX';
}The type field is also missing, which is defined in the schema with an enum restriction to 'SENT' or 'INBOX'.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export interface IMapMessage { | |
| inboxIntegrationId: string; | |
| inboxConversationId: string; | |
| messageId: string; | |
| subject: string; | |
| body: string; | |
| to: IMapMail[]; | |
| cc: IMapMail[]; | |
| bcc: IMapMail[]; | |
| from: IMapMail[]; | |
| attachments?: IMapAttachmentParams[]; | |
| createdAt: Date; | |
| } | |
| export interface IMapMessage { | |
| inboxIntegrationId: string; | |
| inboxConversationId: string; | |
| messageId: string; | |
| inReplyTo?: string; | |
| references?: string[]; | |
| subject: string; | |
| body: string; | |
| to: IMapMail[]; | |
| cc: IMapMail[]; | |
| bcc: IMapMail[]; | |
| from: IMapMail[]; | |
| attachments?: IMapAttachmentParams[]; | |
| createdAt: Date; | |
| type: 'SENT' | 'INBOX'; | |
| } |
🤖 Prompt for AI Agents
In
backend/plugins/frontline_api/src/modules/integrations/imap/@types/messages.ts
between lines 14 and 26, the IMapMessage interface lacks the inReplyTo and
references fields present in the Mongoose schema, causing inconsistency.
Additionally, the type field with enum values 'SENT' or 'INBOX' is missing. To
fix this, add the inReplyTo and references fields with appropriate types (likely
string or string array) and include the type field as a string enum restricted
to 'SENT' or 'INBOX' to align the interface with the schema.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
|
|
||
| import { Schema } from 'mongoose'; | ||
| export const customerSchema = new Schema({ | ||
| inboxIntegrationId: String, | ||
| contactsId: String, | ||
| email: { type: String, unique: true }, | ||
| firstName: String, | ||
| lastName: String | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { Schema } from 'mongoose'; | ||
| export const integrationSchema = new Schema({ | ||
| inboxId: String, | ||
| host: String, | ||
| smtpHost: String, | ||
| smtpPort: String, | ||
| mainUser: String, | ||
| user: String, | ||
| password: String, | ||
| healthStatus: String, | ||
| error: String, | ||
| lastFetchDate: Date | ||
| }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security concern: password stored as plain text The integration schema stores the password as plain text, which is a security risk. Consider:
export const integrationSchema = new Schema({
- inboxId: String,
+ inboxId: { type: String, required: true },
- host: String,
+ host: { type: String, required: true },
- smtpHost: String,
+ smtpHost: { type: String, required: true },
- smtpPort: String,
+ smtpPort: {
+ type: String,
+ required: true,
+ validate: {
+ validator: (v: string) => /^\d+$/.test(v) && parseInt(v) > 0 && parseInt(v) <= 65535,
+ message: 'smtpPort must be a valid port number'
+ }
+ },
mainUser: String,
- user: String,
+ user: { type: String, required: true },
- password: String,
+ password: { type: String, required: true },
healthStatus: String,
error: String,
lastFetchDate: Date
+}, {
+ timestamps: true
});Additionally, consider implementing password encryption either through:
🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,36 @@ | ||||||
| import { Schema } from 'mongoose'; | ||||||
| export const attachmentSchema = new Schema( | ||||||
| { | ||||||
| filename: String, | ||||||
| mimeType: String, | ||||||
| type: String, | ||||||
| size: Number, | ||||||
| attachmentId: String | ||||||
| }, | ||||||
| { _id: false } | ||||||
| ); | ||||||
|
|
||||||
| const emailSchema = new Schema( | ||||||
| { | ||||||
| name: String, | ||||||
| address: String | ||||||
| }, | ||||||
| { _id: false } | ||||||
| ); | ||||||
|
|
||||||
| export const messageSchema = new Schema({ | ||||||
| inboxIntegrationId: String, | ||||||
| inboxConversationId: String, | ||||||
| subject: String, | ||||||
| messageId: { type: String, unique: true }, | ||||||
| inReplyTo: String, | ||||||
| references: [String], | ||||||
| body: String, | ||||||
| to: [emailSchema], | ||||||
| cc: [emailSchema], | ||||||
| bcc: [emailSchema], | ||||||
| from: [emailSchema], | ||||||
| attachments: [attachmentSchema], | ||||||
| createdAt: { type: Date, index: true, default: new Date() }, | ||||||
|
||||||
| createdAt: { type: Date, index: true, default: new Date() }, | |
| createdAt: { type: Date, index: true, default: Date.now }, |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick (bug_risk): Use Date.now instead of new Date() for default
default: new Date() sets the same timestamp for all documents. Use default: Date.now to assign the creation time when each document is created.
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { Model } from 'mongoose'; | ||
| import {IMapCustomerDocument} from '@/integrations/imap/@types/customers'; | ||
| import { customerSchema } from '@/integrations/imap/db/definitions/customers' | ||
| export type IMapCustomerModel = Model<IMapCustomerDocument>; | ||
|
|
||
|
|
||
| export const loadImapCustomerClass = (models) => { | ||
| class Customer {} | ||
|
|
||
| customerSchema.loadClass(Customer); | ||
|
|
||
| return customerSchema; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { Model } from 'mongoose'; | ||
| import { IMapIntegrationDocument} from '@/integrations/imap/@types/integrations'; | ||
| import { integrationSchema } from '@/integrations/imap/db/definitions/integrations' | ||
| export type IMapIntegrationModel = Model<IMapIntegrationDocument>; | ||
|
|
||
| export const loadImapIntegrationClass = (models) => { | ||
| class Integration {} | ||
|
|
||
| integrationSchema.loadClass(Integration); | ||
|
|
||
| return integrationSchema; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: The interface names for the
imapmodels (e.g.IMapCustomerModel) useMapinstead ofImap. For consistency with the filename paths and loader functions (loadImapCustomerClass), consider renaming these toIImapCustomerModel,IImapIntegrationModel, andIImapMessageModel.