Skip to content
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

Added Outlook integration toolkit #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions langchain/src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ export {
formatToOpenAIFunction,
formatToOpenAITool,
} from "./convert_to_openai.js";
export { OutlookIntegration } from "./outlookIntegration.js";
94 changes: 94 additions & 0 deletions langchain/src/tools/outlookIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Tool, type ToolParams } from "./base.js";
import fetch from 'node-fetch';

export interface Email {
sender: string;
subject: string;
// Add other properties as needed
}

export class OutlookIntegration extends Tool {
accessToken: string; // Store the OAuth2 access token

constructor(params: ToolParams, accessToken: string) {
super(params);
this.accessToken = accessToken; // Initialize with an OAuth2 access token
}
Comment on lines +11 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category Security severity potentially major

Security Issue: Access Token Storage

Storing the access token directly in the OutlookIntegration class as a property poses a security risk. If the codebase is compromised, an attacker could gain access to the stored access token and misuse it to access user data or perform unauthorized actions.

Actionable Feedback:

  • Avoid storing sensitive information like access tokens directly in the code.
  • Use a secure storage mechanism such as environment variables or a secrets management system to store the access token.
  • Retrieve the access token from the secure storage when needed, rather than storing it in the code.

By following these recommendations, you can enhance the security of your application and protect user data from unauthorized access.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.


async readEmails(): Promise<Email[]> {
try {
const response = await fetch("https://graph.microsoft.com/v1.0/me/mailFolders('Inbox')/messages?$select=sender,subject", {
headers: {
Authorization: `Bearer ${this.accessToken}`,
},
});

if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}

const data = await response.json();
return data.value; // Assuming 'value' contains the array of emails
} catch (error) {
console.error("Failed to read emails:", error);
throw error;
}
Comment on lines +32 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category Error Handling

In the readEmails and sendEmail methods, you are catching errors, logging them to the console, and then re-throwing the errors using throw error. This can lead to unhandled promise rejections if the caller of these methods does not catch and handle the re-thrown errors. Consider removing the throw error statements and instead return an error response or a default value to indicate that an error occurred. This allows the caller to handle the error appropriately based on the returned value.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +32 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category Security

Security Issue: Error Handling and Logging

The error handling in the readEmails and sendEmail methods could potentially leak sensitive information. When an error occurs, the error details are logged using console.error, which may include sensitive information such as the access token or other details about the API request.

Actionable Feedback:

  • Avoid logging the entire error object or sensitive information directly.
  • Log a generic error message that does not include sensitive details.
  • If logging is necessary for debugging purposes, ensure that the logs are properly secured and accessible only to authorized personnel.
  • Consider using a logging framework that allows you to control the level of detail logged based on the environment.

By handling errors carefully and avoiding the logging of sensitive information, you can prevent unauthorized access to sensitive data and maintain the security of your application.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

}

async sendEmail(to: string, subject: string, content: string): Promise<void> {
const message = {
message: {
subject: subject,
body: {
contentType: "Text",
content: content,
},
toRecipients: [
{
emailAddress: {
address: to,
},
},
],
},
};

try {
const response = await fetch("https://graph.microsoft.com/v1.0/me/sendMail", {
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});

if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}

console.log("Email sent successfully");
} catch (error) {
console.error("Failed to send email:", error);
throw error;
}
}

// You can add more methods for other features like managing contacts, calendar, etc.

}


// import fetch from "node-fetch";

// const accessToken = "YOUR_ACCESS_TOKEN";

// const response = await fetch("https://graph.microsoft.com/v1.0/me/messages", {
// headers: {
// Authorization: `Bearer ${accessToken}`,
// },
// });

// const data = await response.json();

// console.log(data);