feat: add email verification based on spf/dkim/dmarc/logo verification#1622
feat: add email verification based on spf/dkim/dmarc/logo verification#1622ahmetskilinc merged 4 commits intoMail-0:stagingfrom
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughA new email verification feature was implemented, including backend logic to validate SPF, DKIM, DMARC, and BIMI, and a frontend badge indicating verification status. This involved adding methods for retrieving raw emails, a verification module, TRPC endpoints, and integrating a verification badge into the mail display UI. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant MailDisplay
participant EmailVerificationBadge
participant TRPC_Client
participant TRPC_Server
participant Agent
participant MailDriver
participant VerificationModule
User->>MailDisplay: View email
MailDisplay->>EmailVerificationBadge: Render with messageId
EmailVerificationBadge->>TRPC_Client: Query verifyEmail({id})
TRPC_Client->>TRPC_Server: verifyEmail({id})
TRPC_Server->>Agent: getRawEmail(id)
Agent->>MailDriver: getRawEmail(id)
MailDriver->>Agent: Return raw email
Agent->>TRPC_Server: Return raw email
TRPC_Server->>VerificationModule: verify(rawEmail)
VerificationModule-->>TRPC_Server: {isVerified, logoUrl?}
TRPC_Server->>TRPC_Client: Return verification result
TRPC_Client->>EmailVerificationBadge: Show badge if verified
Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
PR Summary
Implements comprehensive email authentication with SPF, DKIM, DMARC, and BIMI verification, adding visual trust indicators in the mail interface.
- Added new
apps/server/src/lib/email-verification.tswith modular validation functions for each authentication protocol - Created
EmailVerificationBadgecomponent inapps/mail/components/mail/email-verification-badge.tsxto display verification status - Extended MailManager interface with
getRawEmail()method inapps/server/src/lib/driver/types.tsto support verification checks - Added verification-related TRPC procedures in
apps/server/src/trpc/routes/mail.tsfor raw email access and verification - Integrated verification badge into
mail-display.tsxalongside sender information
7 files reviewed, 5 comments
Edit PR Review Bot Settings | Greptile
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
apps/server/src/lib/email-verification.ts (2)
354-354: Apply static analysis suggestions for optional chaining.The static analysis tool correctly identified opportunities to use optional chaining for cleaner code.
- if (logoUrl && logoUrl.startsWith('https://')) { + if (logoUrl?.startsWith('https://')) { return logoUrl; }- if (logoUrl && logoUrl.startsWith('https://')) { + if (logoUrl?.startsWith('https://')) { return logoUrl; }Also applies to: 370-370
117-165: Enhance DKIM validation completeness.The DKIM implementation has several limitations:
- Algorithm restriction: Only supports
rsa-sha256, ignoring other valid algorithms- Canonicalization: Assumes simple canonicalization, not handling
relaxedorrelaxed/simple- Public key validation: No validation of the extracted public key format
Consider supporting additional algorithms and canonicalization methods for better compatibility.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/mail/components/mail/email-verification-badge.tsx(1 hunks)apps/mail/components/mail/mail-display.tsx(2 hunks)apps/server/src/lib/driver/google.ts(1 hunks)apps/server/src/lib/driver/types.ts(1 hunks)apps/server/src/lib/email-verification.ts(1 hunks)apps/server/src/routes/chat.ts(2 hunks)apps/server/src/trpc/routes/mail.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
apps/server/src/lib/driver/types.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/trpc/routes/mail.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.376Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/server/src/lib/driver/google.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/components/mail/mail-display.tsx (1)
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:12-12
Timestamp: 2025-04-07T20:46:11.697Z
Learning: In the Mail-0/Zero application, sender emails are guaranteed to be non-empty when passed to components that handle them, making additional empty string validation unnecessary.
apps/server/src/routes/chat.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/lib/email-verification.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
🧬 Code Graph Analysis (3)
apps/mail/components/mail/email-verification-badge.tsx (2)
apps/mail/components/ui/tooltip.tsx (3)
Tooltip(72-72)TooltipTrigger(72-72)TooltipContent(72-72)apps/mail/components/icons/icons.tsx (1)
CircleCheck(258-273)
apps/server/src/trpc/routes/mail.ts (3)
apps/server/src/trpc/trpc.ts (1)
activeDriverProcedure(43-77)apps/server/src/lib/server-utils.ts (1)
getZeroAgent(15-20)apps/server/src/lib/email-verification.ts (1)
verify(384-434)
apps/mail/components/mail/mail-display.tsx (1)
apps/mail/components/mail/email-verification-badge.tsx (1)
EmailVerificationBadge(11-41)
🪛 Biome (1.9.4)
apps/server/src/lib/email-verification.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 370-370: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (9)
apps/server/src/lib/driver/types.ts (1)
105-105: LGTM! Clean interface addition.The
getRawEmailmethod signature is well-designed with appropriate parameter and return types. It follows the existing naming conventions and integrates seamlessly with the interface.apps/server/src/lib/driver/google.ts (1)
773-793: Excellent implementation following established patterns.The
getRawEmailmethod is well-implemented with:
- Proper use of
withErrorHandlerfor consistency- Correct Gmail API usage with
format: 'raw'- Appropriate error handling for missing raw data
- Correct base64 decoding for Gmail's response format
The implementation aligns perfectly with the existing codebase patterns and provides the necessary foundation for email verification.
apps/mail/components/mail/mail-display.tsx (2)
51-51: Clean import addition.The
EmailVerificationBadgeimport is properly placed and follows the existing import organization.
1456-1472: Excellent UI integration that preserves existing functionality.The integration of the
EmailVerificationBadgeis well-executed:
- Clean structural change from
<span>to<div>container with flexbox layout- Proper spacing with
gap-2for visual separation- Existing click handler for sender research is preserved
- Badge receives the correct
messageIdprop fromemailData.id- No breaking changes to existing functionality
The implementation seamlessly adds the verification feature while maintaining the existing user experience.
apps/server/src/routes/chat.ts (1)
274-276: LGTM: Clean implementation following established patterns.Both
getRawEmailmethods correctly follow the existing codebase patterns:
AgentRpcDOuses simple delegation like other methodsZeroAgentincludes the proper driver null check with meaningful error messageThe implementation is consistent with the existing method signatures and error handling strategies.
Also applies to: 825-830
apps/server/src/trpc/routes/mail.ts (2)
398-408: LGTM: Simple and correct implementation.The
getRawEmailprocedure follows the established pattern with proper input validation and clean delegation to the agent.
409-429: LGTM: Solid error handling and design.The
verifyEmailprocedure demonstrates good practices:
- Proper error handling with fallback return value
- Dynamic import keeps verification logic modular
- Error logging aids debugging
- Safe default of
{ isVerified: false }on any failureapps/mail/components/mail/email-verification-badge.tsx (1)
11-41: LGTM: Well-structured React component with proper query management.The component demonstrates good practices:
- Proper query configuration with reasonable caching (5 minutes) and retry policies
- Conditional rendering that only shows badge when verified
- Query disabled when
messageIdis undefined to prevent unnecessary requests- Clean UI structure with accessible tooltip
The implementation correctly integrates with the TRPC API and provides a good user experience.
apps/server/src/lib/email-verification.ts (1)
384-434: LGTM: Well-structured main verification function.The main
verifyfunction demonstrates good architecture:
- Parallel execution of validations for performance
- Proper error handling with safe fallbacks
- Clear logic requiring both authentication (SPF/DKIM/DMARC) and BIMI validation
- Appropriate return type structure
The overall verification strategy aligns with email authentication best practices.
|
worked on this topic good addition keep it up. |
|
This PR has merge conflicts and has been open for more than 3 days. It will be automatically closed. Please resolve the conflicts and reopen the PR if you'd like to continue working on it. |
Bug Report
Comments? Email us. |
|
This PR has merge conflicts and has been open for more than 3 days. It will be automatically closed. Please resolve the conflicts and reopen the PR if you'd like to continue working on it. |
Bug Report
Comments? Email us. |
There was a problem hiding this comment.
cubic analysis
2 issues found across 7 files • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| export const EmailVerificationBadge: React.FC<EmailVerificationBadgeProps> = ({ messageId }) => { | ||
| const trpc = useTRPC(); | ||
|
|
||
| const { data: verificationResult, isLoading, error, isError } = useQuery({ |
There was a problem hiding this comment.
Rule violated: Prevent Side Effects or Logic Inside Render Functions or Loops
Do not place API calls or side-effectful hooks (like useQuery) inside render functions. Move useQuery to the top level of the component, outside of any render logic or loops, to prevent repeated side effects and performance issues.
Prompt for AI agents
Address the following comment on apps/mail/components/mail/email-verification-badge.tsx at line 14:
<comment>Do not place API calls or side-effectful hooks (like useQuery) inside render functions. Move useQuery to the top level of the component, outside of any render logic or loops, to prevent repeated side effects and performance issues.</comment>
<file context>
@@ -0,0 +1,41 @@
+import React from 'react';
+import { CircleCheck } from '../icons/icons';
+import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
+import { useTRPC } from '@/providers/query-provider';
+import { useQuery } from '@tanstack/react-query';
+
+interface EmailVerificationBadgeProps {
+ messageId: string | undefined;
+}
</file context>
| </span> | ||
| <div className="flex items-center gap-2"> | ||
| <span | ||
| onClick={(e) => { |
There was a problem hiding this comment.
Rule violated: Detect React performance bottlenecks and rule breaking
Inline anonymous arrow function passed to the span’s onClick prop violates the performance rule ("Avoid defining anonymous functions directly inside JSX props" – Detect React performance bottlenecks). This function is recreated on every render, causing unnecessary re-renders of descendants and preventing potential memoization.
Prompt for AI agents
Address the following comment on apps/mail/components/mail/mail-display.tsx at line 1459:
<comment>Inline anonymous arrow function passed to the span’s onClick prop violates the performance rule ("Avoid defining anonymous functions directly inside JSX props" – Detect React performance bottlenecks). This function is recreated on every render, causing unnecessary re-renders of descendants and preventing potential memoization.</comment>
<file context>
@@ -1453,20 +1454,23 @@ const MailDisplay = ({ emailData, index, totalEmails, demo, threadAttachments }:
<div className="flex w-full flex-col">
<div className="flex w-full items-center justify-between">
<div className="flex items-center gap-1">
- <span
- onClick={(e) => {
- e.stopPropagation();
- e.preventDefault();
- setResearchSender({
- name: emailData?.sender?.name || '',
</file context>
verification.mp4
do not merge man need to add a different type of tick and need to test more and more
Summary by CodeRabbit