Inbox Management
Relevant source files
The following files were used as context for generating this wiki page:
Inbox Management is a core feature of the Email Platform, enabling users to create, manage, and receive emails in disposable or permanent inboxes associated with their domains. This system is designed to be flexible, supporting both manual creation by authenticated users and automatic creation on-the-fly as emails are received, a key aspect of its "temp mail" functionality.
Inboxes are tied to domains and have a clear ownership model that governs access and permissions. Users can create inboxes with a specific Time-to-Live (TTL), after which they may be automatically deleted, or create permanent ones. The user interface provides comprehensive tools for listing, creating, deleting, and extending the life of these inboxes.
Data Model
The inboxes table is central to this system, linking a specific email address (localPart) to a domain and an owner. It also supports temporary inboxes through the expiresAt field.
Sources: blueprint.md:149-151, services/api/src/test/inbox_ownership.test.ts:71-77
ER Diagram
This diagram shows the relationship between Users, Domains, Inboxes, and Messages.
inboxes Table Schema
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the inbox. |
domain_id | string | Foreign key linking to the domains table. |
ownerId | string | Foreign key linking to the users table. Defines who can manage the inbox. |
localPart | string | The part of the email address before the '@'. |
expiresAt | datetime | Optional. If set, the inbox is temporary and may be cleaned up after this time. |
deletedAt | datetime | Optional. Supports soft-deleting inboxes. |
claimedAt | datetime | Timestamp for when the inbox was claimed by a user. |
Sources: blueprint.md:149-151, services/api/src/test/inbox_ownership.test.ts:71-77, services/api/prisma/migrations/0002_abuse_controls/migration.sql:6
Inbox Creation
Inboxes can be created in several ways, providing flexibility for different use cases.
1. Manual Creation (Authenticated)
Authenticated users can create inboxes for domains they own or for public/shared domains. The UI provides a form to specify the localPart and an optional TTL.
The creation process is initiated from the Sidebar.tsx component, which calls the createInbox function in Dashboard.tsx. This function then makes a POST request to the /inboxes API endpoint.
Sources: services/web/src/components/Sidebar.tsx:300-318, services/web/src/pages/Dashboard.tsx:266-284
UI for Manual Creation
The sidebar contains a form for creating a new inbox with a name and an optional TTL.
// services/web/src/components/Sidebar.tsx:300-318
<div className="flex items-center gap-1 mb-2">
<input
autoFocus
className="text-sm flex-1 min-w-0"
placeholder="tên-hộp-thư"
value={newInboxName}
onChange={e => setNewInboxName(e.target.value)}
/>
<span className="text-muted text-xs">@{activeDomain?.name}</span>
</div>
<select
className="text-xs mb-2"
value={newInboxTTL}
onChange={e => setNewInboxTTL(e.target.value)}
>
<option value="">Vĩnh viễn (Không xóa)</option>
<option value={3600000}>1 Giờ</option>
<option value={86400000}>1 Ngày</option>
<option value={604800000}>1 Tuần</option>
</select>
Random Inbox Creation
The UI also includes a button to generate a random 8-character inbox name, providing a quick way to create a disposable address.
Sources: services/web/src/components/Sidebar.tsx:43-50, services/web/src/components/Sidebar.tsx:285-292
2. Automatic Creation (On-the-fly)
A key feature is the automatic creation of an inbox when an email is received for an address that does not yet exist. The ensureDomainAndInbox function in the email processing worker handles this logic.
If an email arrives for new-inbox@example.com and it doesn't exist, the worker will:
- Find the
example.comdomain. - Create a new inbox record with
localPart: 'new-inbox'. - If the inbox was previously soft-deleted (
deletedAtis set), it will be restored by settingdeletedAtandexpiresAttonull.
This ensures that any email sent to a valid domain is captured, which is essential for temporary email services.
Sources: services/api/src/worker.ts:29-57
Auto-Creation Flow
The following diagram illustrates the logic within the email worker.
Sources: services/api/src/worker.ts:46-53
3. Public Creation
The system supports a public endpoint for creating inboxes, likely intended for unauthenticated use cases and potentially protected by a CAPTCHA.
Sources: README.md:52
Ownership and Permissions
Inbox ownership is a critical security mechanism. When a user creates an inbox, their userId is stored as the ownerId on the inbox record.
Sources: services/api/src/test/inbox_ownership.test.ts:65-84
- Creation: Only the domain owner or an admin can create an inbox on a private domain. Any authenticated user can create an inbox on a
publicdomain. - Listing: Regular users can only list inboxes they own (
ownerIdmatches theiruserId). Admins can list all inboxes across the system. - Deletion: A user can only delete an inbox they own. An admin can delete any inbox.
This is enforced at the API level, as demonstrated by the ownership tests.
Sources: services/api/src/test/inbox_ownership.test.ts:89-145
Inbox Deletion Access Control Flow
Inbox Lifecycle and Management
Listing and Viewing
Inboxes are listed in the sidebar of the dashboard. The loadInboxes function fetches inboxes for the currently selected domain.
Sources: services/web/src/pages/Dashboard.tsx:112-131, services/web/src/components/Sidebar.tsx:265-397
Temporary Inboxes (TTL)
Inboxes can be created with an expiration time (expiresAt). The UI provides options for 1 hour, 1 day, or 1 week. A CountdownTimer component in the sidebar displays the remaining time for temporary inboxes.
Sources: services/web/src/components/Sidebar.tsx:309-315, services/web/src/components/Sidebar.tsx:364-366
Extending Inbox Lifetime
For temporary inboxes, the UI provides an "extend" button. This action (handleExtendInbox) sends a PATCH request to the /inboxes/:id endpoint, updating the expiresAt field to 10 minutes from its current expiration time.
Sources: services/web/src/pages/Dashboard.tsx:432-455, services/web/src/components/Sidebar.tsx:378-390
Deletion
Users can delete their own inboxes via the UI. This triggers a call to deleteInbox in Dashboard.tsx, which sends a DELETE request to /inboxes/:id. The backend performs a soft delete by setting the deletedAt timestamp.
Sources: services/web/src/pages/Dashboard.tsx:286-306, services/api/prisma/migrations/0002_abuse_controls/migration.sql:6
API Endpoints
The following API endpoints are used for inbox management. All endpoints require authentication.
| Method | Endpoint | Description |
|---|---|---|
GET | /inboxes | Lists inboxes. Filters by ownerId for regular users; returns all for admins. Supports pagination and filtering by domain name. |
POST | /inboxes | Creates a new inbox. The ownerId is set to the authenticated user's ID. |
GET | /inboxes/:id | Retrieves a single inbox by its ID, checking for ownership. |
PATCH | /inboxes/:id | Updates an inbox. Used for extending the expiresAt time. |
DELETE | /inboxes/:id | Soft-deletes an inbox. Only the owner or an admin can perform this action. |
POST | /public/inboxes | Creates an inbox via a public-facing endpoint. |
Sources: services/api/src/test/inbox_ownership.test.ts, services/web/src/pages/Dashboard.tsx, README.md:52
Summary
The Inbox Management system is a robust and flexible feature that forms the backbone of the platform's email-receiving capabilities. It successfully balances ease of use for temporary/disposable email addresses with a secure ownership model for private use. The combination of manual, random, and automatic on-the-fly inbox creation covers a wide range of use cases, while the API and UI provide full control over the inbox lifecycle.