Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Email API:
Email Sandbox (Testing):

- Project management CRUD – [`projects_api.rb`](examples/projects_api.rb)
- Inboxes CRUD - [`inboxes_api.rb`](examples/inboxes_api.rb)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

minor. inconsistent with the previous line


Contact management:

Expand Down
33 changes: 33 additions & 0 deletions examples/inboxes_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'mailtrap'

account_id = 3229
client = Mailtrap::Client.new(api_key: 'your-api-key')
inboxes = Mailtrap::InboxesAPI.new(account_id, client)

# Create new Inbox
list = inboxes.create(name: 'Test Inbox', project_id: 123_456)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

rename the variable

# => #<struct Mailtrap::Inbox id=1, name="Test Inbox">

# Get all Inboxes
inboxes.list
# => [#<struct Mailtrap::Inbox id=1, name="Test Inbox">]

# Update contact list
inboxes.update(list.id, name: 'Test List Updated')
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">

# Get contact list
inbox = inboxes.get(list.id)
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix incorrect terminology in comments.

The comments reference "contact list" but this is the Inboxes API. These appear to be copy-paste artifacts from another example file.

📝 Suggested fix
-# Update contact list
+# Update Inbox
 inboxes.update(list.id, name: 'Test List Updated')
 # => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">

-# Get contact list
+# Get Inbox by ID
 inbox = inboxes.get(list.id)
 # => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">
📝 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.

Suggested change
# Update contact list
inboxes.update(list.id, name: 'Test List Updated')
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">
# Get contact list
inbox = inboxes.get(list.id)
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">
# Update Inbox
inboxes.update(list.id, name: 'Test List Updated')
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">
# Get Inbox by ID
inbox = inboxes.get(list.id)
# => #<struct Mailtrap::Inbox id=1, name="Test Inbox Updated">
🤖 Prompt for AI Agents
In `@examples/inboxes_api.rb` around lines 15 - 21, The comments incorrectly say
"contact list" in the Inboxes API example; update the comment lines above the
calls to inboxes.update and inboxes.get to refer to "inbox" (e.g., "Update
inbox" and "Get inbox") and ensure any surrounding wording matches the Inboxes
API context (leave the calls inboxes.update, inboxes.get and the id usage like
list.id as-is unless variable name should be inbox.id in this example).


# Delete all messages (emails) from Inbox
inboxes.clean(inbox.id)

# Mark all messages in the inbox as read
inboxes.mark_as_read(inbox.id)

# Reset SMTP credentials of the inbox
inboxes.reset_credentials(inbox.id)

# Delete contact list
inboxes.delete(inbox.id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix incorrect terminology.

The comment says "Delete contact list" but should say "Delete Inbox".

📝 Suggested fix
-# Delete contact list
+# Delete Inbox
 inboxes.delete(inbox.id)
🤖 Prompt for AI Agents
In `@examples/inboxes_api.rb` around lines 32 - 33, The comment above the
inboxes.delete(inbox.id) call uses incorrect terminology ("Delete contact
list"); update that comment to accurately read "Delete Inbox" (or similar
correct wording) so it matches the operation performed by the
inboxes.delete(inbox.id) call.

1 change: 1 addition & 0 deletions lib/mailtrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require_relative 'mailtrap/contact_imports_api'
require_relative 'mailtrap/suppressions_api'
require_relative 'mailtrap/projects_api'
require_relative 'mailtrap/inboxes_api'

module Mailtrap
# @!macro api_errors
Expand Down
98 changes: 98 additions & 0 deletions lib/mailtrap/inboxes_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true

require_relative 'base_api'
require_relative 'inbox'

module Mailtrap
class InboxesAPI
include BaseAPI

self.supported_options = %i[name email_username project_id]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You cannot update project_id.

self.response_class = Inbox

# Lists all Inboxes for the account
# @return [Array<Inbox>] Array of Inboxes
# @!macro api_errors
def list
base_list
end

# Retrieves a specific inbox
# @param inbox_id [Integer] The inbox identifier
# @return [Inbox] Inbox object
# @!macro api_errors
def get(inbox_id)
base_get(inbox_id)
end

# Creates a new inbox
# @param [Hash] options The parameters to create
# @option options [String] :name The inbox name
# @return [Inbox] Created inbox object
# @!macro api_errors
# @raise [ArgumentError] If invalid options are provided
def create(options)
validate_options!(options, supported_options)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

validate_options!(options, supported_options + [:project_id])

response = client.post("/api/accounts/#{account_id}/projects/#{options[:project_id]}/inboxes",
wrap_request(options))
handle_response(response)
end
Comment on lines +28 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing validation for required project_id parameter.

The create method uses options[:project_id] to construct the API path, but there's no validation ensuring it's present. If project_id is nil or missing, the path becomes malformed (e.g., /api/accounts/123/projects//inboxes), which could result in unexpected errors.

Additionally, the @option documentation only mentions :name but project_id is effectively required.

Proposed fix
     # Creates a new inbox
     # `@param` [Hash] options The parameters to create
     # `@option` options [String] :name The inbox name
+    # `@option` options [Integer] :project_id The project identifier (required)
     # `@return` [Inbox] Created inbox object
     # @!macro api_errors
     # `@raise` [ArgumentError] If invalid options are provided
     def create(options)
       validate_options!(options, supported_options + [:project_id])
+      raise ArgumentError, 'project_id is required' unless options[:project_id]
       response = client.post("/api/accounts/#{account_id}/projects/#{options[:project_id]}/inboxes",
                              wrap_request(options))
       handle_response(response)
     end
🧰 Tools
🪛 ast-grep (0.40.5)

[warning] 35-36: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: client.post("/api/accounts/#{account_id}/projects/#{options[:project_id]}/inboxes",
wrap_request(options))
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures [REFERENCES]
https://cwe.mitre.org/data/definitions/522.html

(hardcoded-secret-rsa-passphrase-ruby)

🤖 Prompt for AI Agents
In `@lib/mailtrap/inboxes_api.rb` around lines 28 - 39, The create method uses
options[:project_id] in the path but doesn't ensure it's present, so add an
explicit validation that options[:project_id] is provided (raise ArgumentError
with a clear message if missing or nil) before calling client.post; keep the
existing validate_options! call for supported keys but ensure project_id is
treated as required by either adding a presence check or adjusting
validate_options! usage for required keys; also update the YARD docs above
create to include `@option` options [Integer, String] :project_id (marked
required) so callers know project_id is mandatory.


# Deletes an inbox
# @param inbox_id [Integer] The Inbox identifier
# @return nil
# @!macro api_errors
def delete(inbox_id)
base_delete(inbox_id)
end

# Updates an existing Inbox
# @param inbox_id [Integer] The Inbox identifier
# @param [Hash] options The parameters to update
# @option options [String] :name The inbox name
# @option options [String] :email_username The inbox email username
# @return [Inbox] Updated Inbox object
# @!macro api_errors
# @raise [ArgumentError] If invalid options are provided
def update(inbox_id, options)
base_update(inbox_id, options)
end

# Delete all messages (emails) from Inbox
# @param inbox_id [Integer] The Inbox identifier
# @return [Inbox] Updated Inbox object
# @!macro api_errors
def clean(inbox_id)
response = client.patch("#{base_path}/#{inbox_id}/clean")
handle_response(response)
end

# Mark all messages in the inbox as read
# @param inbox_id [Integer] The Inbox identifier
# @return [Inbox] Updated Inbox object
# @!macro api_errors
def mark_as_read(inbox_id)
response = client.patch("#{base_path}/#{inbox_id}/all_read")
handle_response(response)
end

# Reset SMTP credentials of the inbox
# @param inbox_id [Integer] The Inbox identifier
# @return [Inbox] Updated Inbox object
# @!macro api_errors
def reset_credentials(inbox_id)
response = client.patch("#{base_path}/#{inbox_id}/reset_credentials")
handle_response(response)
end

private

def wrap_request(options)
{ inbox: options }
end

def base_path
"/api/accounts/#{account_id}/inboxes"
end
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading