Skip to content

(proxy) create email service [DA-392]#319

Merged
Mr-Quin merged 5 commits intomasterfrom
DA-392_Create-email-service
Mar 16, 2026
Merged

(proxy) create email service [DA-392]#319
Mr-Quin merged 5 commits intomasterfrom
DA-392_Create-email-service

Conversation

@Mr-Quin
Copy link
Owner

@Mr-Quin Mr-Quin commented Feb 25, 2026

No description provided.

@Mr-Quin Mr-Quin self-assigned this Feb 25, 2026
Copilot AI review requested due to automatic review settings February 25, 2026 04:36
@Mr-Quin
Copy link
Owner Author

Mr-Quin commented Feb 25, 2026

Task linked: DA-392 Create email service

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 25, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
danmaku-anywhere-web 030188e Commit Preview URL

Branch Preview URL
Mar 16 2026, 01:10 AM

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Mr-Quin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new email service to the backend proxy, leveraging Resend for transactional email capabilities. This enhancement enables critical authentication features such as password reset and email verification. Concurrently, a new documentation enforcement rule has been added, alongside comprehensive README.md and AGENTS.md files across several applications and packages, significantly improving the project's overall documentation and maintainability.

Highlights

  • Email Service Implementation: A new email service has been implemented in the backend/proxy using Resend, providing a robust and abstracted way to send transactional emails.
  • Authentication Email Integration: The authentication flow now integrates the new email service for critical features such as password reset and email verification, enhancing user security and experience.
  • Documentation Enforcement Rule: A new Cursor rule (update-docs-after-changes.mdc) has been added to remind developers to keep README.md and AGENTS.md files updated after significant code changes across apps and packages.
  • Comprehensive Documentation Added: Detailed README.md and AGENTS.md files have been introduced for various applications and packages, significantly improving the project's documentation and clarity for contributors.
Changelog
  • .cursor/rules/README.md
    • Added documentation for the new update-docs-after-changes.mdc rule.
  • .cursor/rules/update-docs-after-changes.mdc
    • Added a new Cursor rule to ensure README.md and AGENTS.md are updated after significant changes to app/package/backend code.
  • app/web/AGENTS.md
    • Added agent context documentation for the Angular web application.
  • app/web/README.md
    • Added a README file detailing the Angular web application's purpose, tech stack, scripts, and dependencies.
  • backend/proxy/.dev.vars.example
    • Added EMAIL_FROM environment variable example.
  • backend/proxy/AGENTS.md
    • Added agent context documentation for the Cloudflare Workers backend proxy.
  • backend/proxy/README.md
    • Added a README file detailing the Cloudflare Workers backend proxy's purpose, tech stack, and scripts.
  • backend/proxy/package.json
    • Added resend package dependency.
  • backend/proxy/scripts/setup-secrets-store.ts
    • Added a script to set up local secrets, including the RESEND_API_KEY_STG.
  • backend/proxy/src/auth/config.ts
    • Integrated email service for password reset and email verification.
    • Updated createAuth and getOrCreateAuth to handle waitUntil.
  • backend/proxy/src/email/index.ts
    • Added an email service factory to create and manage email service instances.
  • backend/proxy/src/email/resend.ts
    • Added an implementation of the EmailService using the Resend API.
  • backend/proxy/src/email/types.ts
    • Defined interfaces for EmailService and SendEmailParams for abstraction.
  • backend/proxy/src/middleware/authContext.ts
    • Modified the authentication context middleware to pass waitUntil to getOrCreateAuth.
  • backend/proxy/src/routes/api/auth/router.ts
    • Updated authentication router calls to getOrCreateAuth to include waitUntil.
  • backend/proxy/worker-configuration.d.ts
    • Updated generated Cloudflare Worker types to reflect new environment variables and secrets.
  • backend/proxy/wrangler.json
    • Configured EMAIL_FROM and RESEND_API_KEY in Wrangler settings for different environments.
  • packages/bangumi-api/AGENTS.md
    • Added agent context documentation for the bangumi-api package.
  • packages/bangumi-api/README.md
    • Added a README file for the bangumi-api package, detailing its purpose, exports, and scripts.
  • packages/danmaku-anywhere/AGENTS.md
    • Added agent context documentation for the danmaku-anywhere package.
  • packages/danmaku-anywhere/README.md
    • Added a README file for the danmaku-anywhere package, detailing its purpose, tech stack, and scripts.
  • packages/danmaku-converter/AGENTS.md
    • Added agent context documentation for the danmaku-converter package.
  • packages/danmaku-converter/README.md
    • Added a README file for the danmaku-converter package, detailing its purpose and usage.
  • packages/danmaku-engine/AGENTS.md
    • Added agent context documentation for the danmaku-engine package.
  • packages/danmaku-engine/README.md
    • Added a README file for the danmaku-engine package, detailing its purpose and usage.
  • packages/danmaku-provider/AGENTS.md
    • Added agent context documentation for the danmaku-provider package.
  • packages/danmaku-provider/README.md
    • Added a README file for the danmaku-provider package, detailing its purpose and exports.
  • packages/integration-policy/AGENTS.md
    • Added agent context documentation for the integration-policy package.
  • packages/result/AGENTS.md
    • Added agent context documentation for the result package.
  • packages/web-scraper/AGENTS.md
    • Added agent context documentation for the web-scraper package.
  • packages/web-scraper/README.md
    • Added a README file for the web-scraper package, detailing its purpose and usage.
  • pnpm-lock.yaml
    • Updated lockfile to reflect new resend dependency and its sub-dependencies.
Activity
  • No specific activity (comments, reviews, progress) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new email service using Resend to handle transactional emails for password resets and email verifications. The implementation includes a service abstraction, which is good practice. The changes correctly use Cloudflare Workers' waitUntil to ensure background tasks like sending emails are completed. My feedback focuses on improving the robustness and security of the new email service by adding validation for required environment variables and preventing potential XSS vulnerabilities. A large portion of this PR also includes adding documentation files across the repository, which is a great addition for maintainability.

Comment on lines +14 to +16
const from = env.EMAIL_FROM.trim()

emailService = new ResendEmailService(apiKey, from)
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The EMAIL_FROM environment variable is trimmed but not checked for being empty. If the variable is not set or contains only whitespace, from will be an empty string, which will cause the email sending to fail at runtime. It's better to fail fast with a clear error message if this crucial configuration is missing.

  const from = env.EMAIL_FROM.trim()

  if (!from) {
    throw new Error('EMAIL_FROM environment variable is not configured.')
  }

  emailService = new ResendEmailService(apiKey, from)

Comment on lines +19 to +23
const html =
params.html ??
(params.text
? `<p>${params.text.replaceAll('\n', '<br>')}</p>`
: '<p></p>')
Copy link
Contributor

Choose a reason for hiding this comment

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

high

When converting a plain text body to HTML, the text content is not escaped. This could lead to a Cross-Site Scripting (XSS) vulnerability if the params.text contains malicious HTML, for example from user-controlled data in the future. While the current usage in better-auth seems safe, it's best practice to always escape content that is injected into HTML.

Suggested change
const html =
params.html ??
(params.text
? `<p>${params.text.replaceAll('\n', '<br>')}</p>`
: '<p></p>')
const escapeHtml = (unsafe: string) =>
unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
const html =
params.html ??
(params.text
? `<p>${escapeHtml(params.text).replaceAll('\n', '<br>')}</p>`
: '<p></p>')

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements email service functionality for the Danmaku Anywhere backend proxy using Resend as the email provider. The changes enable password reset and email verification features through Better Auth integration. Additionally, this PR includes comprehensive documentation updates (README.md and AGENTS.md files) for multiple packages and apps across the monorepo, following the newly added documentation standards rule.

Changes:

  • Integrated Resend email service with abstraction layer for transactional emails
  • Configured Better Auth to send password reset and email verification emails
  • Added comprehensive README.md and AGENTS.md documentation for all packages and apps
  • Updated Cloudflare Workers configuration with email-related environment variables and secrets

Reviewed changes

Copilot reviewed 30 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pnpm-lock.yaml Added resend@6.9.2 and its dependencies (postal-mime, svix, standardwebhooks, uuid@10.0.0)
backend/proxy/package.json Added resend dependency to backend proxy
backend/proxy/wrangler.json Added EMAIL_FROM env var and RESEND_API_KEY secret binding across all environments; also added preview_bucket_name for R2
backend/proxy/worker-configuration.d.ts Regenerated TypeScript types to include new EMAIL_FROM and RESEND_API_KEY bindings
backend/proxy/src/email/types.ts Defined EmailService interface and SendEmailParams for email abstraction
backend/proxy/src/email/resend.ts Implemented ResendEmailService using Resend SDK
backend/proxy/src/email/index.ts Created getOrCreateEmailService factory with singleton pattern
backend/proxy/src/auth/config.ts Integrated email service for password reset and email verification callbacks; updated getOrCreateAuth signature to accept waitUntil
backend/proxy/src/routes/api/auth/router.ts Updated auth router to pass waitUntil to getOrCreateAuth
backend/proxy/src/middleware/authContext.ts Updated middleware to pass waitUntil to getOrCreateAuth
backend/proxy/scripts/setup-secrets-store.ts Added RESEND_API_KEY_STG to local secrets setup script
backend/proxy/.dev.vars.example Added EMAIL_FROM environment variable example
backend/proxy/README.md Added comprehensive documentation for the backend proxy package
backend/proxy/AGENTS.md Added agent context documentation for the backend proxy
packages/*/README.md Added README documentation for all workspace packages
packages/*/AGENTS.md Added agent context documentation for all workspace packages
app/web/README.md Added README documentation for the web app
app/web/AGENTS.md Added agent context documentation for the web app
.cursor/rules/update-docs-after-changes.mdc Added new documentation maintenance rule
.cursor/rules/README.md Updated rules index to include new documentation rule
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (14)

packages/danmaku-converter/README.md:13

  • Typo in the command description: 'tsgo' should likely be 'tsc' (TypeScript compiler) or another valid build tool name.
| `pnpm build` | Compile with tsgo |

packages/web-scraper/README.md:1

  • This PR includes documentation updates (README.md and AGENTS.md) for multiple packages and the web app that are unrelated to the email service implementation. While these documentation updates appear to follow the conventions described in .cursor/rules/update-docs-after-changes.mdc, they should ideally be in a separate PR focused on documentation to keep changes focused and easier to review.

The email service changes are in backend/proxy/src/email/, backend/proxy/src/auth/config.ts, and configuration files, but the documentation changes span across many unrelated packages.
backend/proxy/src/email/resend.ts:42

  • The new email service functionality lacks test coverage. The codebase has test infrastructure (vitest with workers pool) and existing test files (e.g., src/utils/computeEtag.test.ts), indicating that testing is a practice in this project.

Consider adding tests for:

  1. ResendEmailService.send() - test email formatting, error handling, and API interaction
  2. getOrCreateEmailService() - test singleton behavior and configuration validation
  3. Integration with auth callbacks - verify email sending is triggered correctly for password reset and email verification
import { Resend } from 'resend'
import type { EmailService, SendEmailParams } from './types'

/**
 * Resend implementation of the email service abstraction.
 * Only this file should import from 'resend' so the rest of the app stays provider-agnostic.
 */
export class ResendEmailService implements EmailService {
  private readonly resend: Resend
  private readonly from: string

  constructor(apiKey: string, from: string) {
    this.resend = new Resend(apiKey)
    this.from = from
  }

  async send(params: SendEmailParams): Promise<void> {
    const to = Array.isArray(params.to) ? params.to : [params.to]
    const html =
      params.html ??
      (params.text
        ? `<p>${params.text.replaceAll('\n', '<br>')}</p>`
        : '<p></p>')
    const text = params.text

    const payload: Parameters<Resend['emails']['send']>[0] = {
      from: this.from,
      to,
      subject: params.subject,
      html,
    }
    if (text) payload.text = text

    console.log('Sending email to', to)
    const { error, data } = await this.resend.emails.send(payload)

    console.log('Email sent successfully', data)
    if (error) {
      throw new Error(`Resend send failed: ${JSON.stringify(error)}`)
    }
  }
}

backend/proxy/src/auth/config.ts:54

  • Email sending operations are wrapped with waitUntil, but errors thrown from emailService.send() will not be caught or logged. If an email fails to send (e.g., due to API key issues or network problems), the user won't receive any feedback, and the error might be silently lost.

Consider adding error handling around the email send promise before passing it to waitUntil, or ensure that email send failures are properly logged and monitored.

      sendResetPassword: async ({ user, url }) => {
        const emailService = await getOrCreateEmailService(env)
        const promise = emailService.send({
          to: user.email,
          subject: 'Reset your password',
          text: `Click the link to reset your password: ${url}`,
        })
        waitUntil(promise)
      },

packages/web-scraper/README.md:13

  • Typo in the command description: 'tsgo' should likely be 'tsc' (TypeScript compiler) or another valid build tool name. The same typo appears in multiple README files.
    packages/bangumi-api/README.md:16
  • Typo in the command description: 'tsgo' should likely be 'tsc' (TypeScript compiler) or another valid build tool name.
| `pnpm build` | tsgo + copy schemas |

backend/proxy/src/email/resend.ts:37

  • The console.log statement on line 37 executes before checking if there was an error. This means "Email sent successfully" will be logged even when the email send operation fails. The log should only execute when there is no error, or should be moved after the error check.
    console.log('Email sent successfully', data)

backend/proxy/src/email/resend.ts:34

  • Sensitive information (email addresses) is being logged with console.log. While this might be acceptable for debugging, it could expose user PII in production logs. Consider using a more structured logging approach or redacting sensitive data, especially since the codebase appears to use Sentry for error tracking and observability.
    console.log('Sending email to', to)

backend/proxy/src/email/index.ts:14

  • The EMAIL_FROM environment variable is only trimmed but not validated. If this value is empty or malformed after trimming, the email service will fail at runtime. Consider adding validation to ensure EMAIL_FROM is a non-empty string with a valid email format, similar to how other critical configuration values are validated.
  const from = env.EMAIL_FROM.trim()

backend/proxy/src/auth/config.ts:66

  • Email sending operations are wrapped with waitUntil, but errors thrown from emailService.send() will not be caught or logged. If an email fails to send (e.g., due to API key issues or network problems), the user won't receive any feedback, and the error might be silently lost.

Consider adding error handling around the email send promise before passing it to waitUntil, or ensure that email send failures are properly logged and monitored.

      sendVerificationEmail: async ({ user, url }) => {
        const emailService = await getOrCreateEmailService(env)
        const promise = emailService.send({
          to: user.email,
          subject: 'Verify your email address',
          text: `Click the link to verify your email: ${url}`,
        })
        waitUntil(promise)
      },

backend/proxy/src/email/resend.ts:23

  • The html parameter includes a fallback to <p></p> when both params.html and params.text are undefined. However, the SendEmailParams interface in types.ts marks both as optional but doesn't indicate that at least one must be provided. This could lead to sending emails with empty content.

Consider either: (1) requiring at least one of text or html in the type definition, or (2) adding runtime validation to throw an error if both are missing.

    const html =
      params.html ??
      (params.text
        ? `<p>${params.text.replaceAll('\n', '<br>')}</p>`
        : '<p></p>')

packages/danmaku-engine/README.md:13

  • Typo in the command description: 'tsgo' should likely be 'tsc' (TypeScript compiler) or another valid build tool name.
| `pnpm build` | Compile with tsgo |

packages/danmaku-provider/README.md:15

  • Typo in the command description: 'tsgo' should likely be 'tsc' (TypeScript compiler) or another valid build tool name.
| `pnpm build` | Compile protobuf + tsgo |

backend/proxy/wrangler.json:136

  • The addition of preview_bucket_name for the R2 bucket configuration is unrelated to the email service functionality described in the PR title. This change should ideally be in a separate PR or the PR description should mention this infrastructure change.
          "bucket_name": "danmaku-anywhere-file-staging",
          "preview_bucket_name": "danmaku-anywhere-file-staging-preview"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Mr-Quin Mr-Quin force-pushed the DA-392_Create-email-service branch from bee9ce1 to 53c69c6 Compare March 16, 2026 00:36
@vercel
Copy link

vercel bot commented Mar 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
danmaku-anywhere-web-dvay Ready Ready Preview, Comment Mar 16, 2026 1:10am

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 16, 2026

Deploying danmaku-anywhere-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 23d9eb0
Status: ✅  Deploy successful!
Preview URL: https://db7d94b7.danmaku-anywhere.pages.dev
Branch Preview URL: https://da-392-create-email-service.danmaku-anywhere.pages.dev

View logs

@Mr-Quin Mr-Quin force-pushed the DA-392_Create-email-service branch from 23d9eb0 to 030188e Compare March 16, 2026 01:08
@Mr-Quin Mr-Quin merged commit 6953925 into master Mar 16, 2026
12 checks passed
@Mr-Quin Mr-Quin deleted the DA-392_Create-email-service branch March 16, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants