Address code review: fix imports, salt hashing, conditional delivery message

- Move asyncio import to module level in gmail_service.py
- Move datetime import to module level in providers.py
- Use hashlib.sha256 for per-user salt generation (no truncation risk)
- Make delivery method message conditional in AddMailAccountModal

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/pop_puller_to_gmail/sessions/de3ef930-a980-4958-8a9d-a2c802918e81
This commit is contained in:
copilot-swe-agent[bot]
2026-03-22 19:05:41 +00:00
parent b05d489563
commit 681e0582f6
4 changed files with 10 additions and 15 deletions
+1 -2
View File
@@ -1,4 +1,5 @@
"""Provider presets and Gmail credential management endpoints"""
from datetime import datetime
from typing import List
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
@@ -197,14 +198,12 @@ async def save_gmail_credential(
existing.encrypted_access_token = encrypted_access
existing.encrypted_refresh_token = encrypted_refresh
existing.is_valid = True
from datetime import datetime
existing.last_verified_at = datetime.utcnow()
await db.commit()
await db.refresh(existing)
return existing
else:
# Create new
from datetime import datetime
credential = GmailCredential(
user_id=current_user.id,
gmail_email=credential_in.gmail_email,
+3 -3
View File
@@ -1,6 +1,7 @@
"""
Security utilities for encryption, hashing, and token generation.
"""
import hashlib
import secrets
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
@@ -81,10 +82,9 @@ class CredentialEncryption:
if key is None:
key = settings.ENCRYPTION_KEY
# Generate salt - in production, this should be unique per user
# Generate salt - unique per user for enhanced security
if user_id is not None:
# Per-user salt for production
salt = f'pop3fwd_usr_{user_id}'.encode('utf-8')[:16].ljust(16, b'\x00')
salt = hashlib.sha256(f'pop3fwd_usr_{user_id}'.encode()).digest()[:16]
else:
# Default salt for system-wide operations (use with caution)
salt = b'pop3_forwarder_0'
+1 -6
View File
@@ -5,6 +5,7 @@ Uses the Gmail API's users.messages.insert() method to inject emails
into a user's Gmail account, preserving original headers and metadata.
This is preferred over SMTP forwarding as it doesn't modify the email.
"""
import asyncio
import base64
import logging
from typing import Optional, Dict, Any
@@ -94,8 +95,6 @@ class GmailService:
Raises:
GmailInjectionError: If injection fails
"""
import asyncio
if label_ids is None:
label_ids = ["INBOX"]
@@ -145,8 +144,6 @@ class GmailService:
Returns:
True if credentials are valid and can access Gmail
"""
import asyncio
loop = asyncio.get_event_loop()
try:
@@ -170,8 +167,6 @@ class GmailService:
Returns:
Email address string or None if unavailable
"""
import asyncio
loop = asyncio.get_event_loop()
try:
@@ -312,10 +312,11 @@ export function AddMailAccountModal({ account, onClose }: AddMailAccountModalPro
</div>
</div>
<div className="bg-green-50 border border-green-200 rounded-md p-3">
<p className="text-sm text-green-800">
<strong>Gmail API Injection:</strong> Emails will be injected directly into your Gmail
account via the Gmail API. Make sure you have configured your Gmail credentials in Settings.
<div className="bg-blue-50 border border-blue-200 rounded-md p-3">
<p className="text-sm text-blue-800">
<strong>Delivery:</strong> Emails will be delivered to your Gmail account.
Configure your Gmail API credentials in Settings for direct injection (recommended),
or they will be forwarded via SMTP.
</p>
</div>