Visitar URL original
fix: keep deletes working when the certificate email is unset by HarshMN2345 · Pull Request #14195 · appwrite/appwrite · GitHub
Skip to content

fix: keep deletes working when the certificate email is unset - #14195

Draft
HarshMN2345 wants to merge 4 commits into
mainfrom
cursor/deletes-missing-certificate-email-d21d
Draft

HarshMN2345 wants to merge 4 commits into
mainfrom
cursor/deletes-missing-certificate-email-d21d

Conversation

@HarshMN2345

@HarshMN2345 HarshMN2345 commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

What does this PR do?

Fixes the deletes worker crashing on every job when _APP_EMAIL_CERTIFICATES and _APP_SYSTEM_SECURITY_EMAIL_ADDRESS are empty.

The worker injects the certificates resource for every job. That resource threw while it was created, before the action ran, so bucket file cleanup, project deletion, and domain cleanup all failed and landed in utopia-queue.failed.v1-deletes.

The Let's Encrypt client is now created even when the address is missing. Local certificate files are still removed, because removal does not use the account email. Issuance still throws the same error. That failure is recorded on the rule (status unverified) through the existing issuance-failure path, and the certificate's attempt count is set to the maintenance cap so it is not rescheduled. A generation job whose rule is not issuing is still skipped. No failure email is queued when there is no address.

When that failure happens before the first save, the rule still stores the new certificate. The failure path keeps the document returned by the upsert, which is the row that has the id.

Fixes #14174

Test Plan

  • tests/unit/Certificates/LetsEncryptTest.php: issuing without an email throws the existing error, including when both environment variables are unset. A certificates address, or the security-address fallback, gets past that check. File removal still deletes the local certificate directory when the client has no email.
  • tests/e2e/Services/Proxy/CertificatesCustomServerTest.php: a generation job with an empty email, run against the platform database, marks the rule unverified, stores the maintenance attempt cap, links the new certificate, and queues no mail. The rule API then shows that failure and a renew time. A rule that is not issuing is left untouched. The pre-existing DNS checks stay in tests/unit/Workers/CertificatesDomainValidationTest.php.

Ran phpunit tests/unit/Certificates/LetsEncryptTest.php tests/unit/Workers/CertificatesDomainValidationTest.php (8 tests, 16 assertions). The proxy e2e case runs with the Proxy suite.

Related PRs and Issues

Checklist

  • Have you read the Contributing Guidelines on issues?
  • If the PR includes a change to an API's metadata (desc, label, params, etc.), does it also include updated API specs and example docs?
Open in Web Open in Cursor 

The certificates client was created for every deletes job and threw
when no email was configured, so bucket and domain cleanup never ran.
Issuance still requires the address. Local certificate removal does not.

Fixes #14174
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Security rules

No new WARNING or ERROR findings from security rules.

32 existing findings tracked in .semgrep/baseline.json
  • php.appwrite.guest-write-without-abuse-limit (17)
  • php.appwrite.permissive-write-permission (8)
  • php.appwrite.secret-compare-timing (5)
  • php.appwrite.weak-secret-env-default (2)

Posted by Checks / Rules. Re-runs update this comment in place. Rule details and baseline: .semgrep/README.md.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → cursor/deletes-missing-certificate-email-d21d (after).

Metric Before After Change
🚀 Requests/sec 204.53 202.27 ⚪ -1.1%
⏱️ Latency P50 82.67 ms 85.93 ms ⚪ +3.9%
⏱️ Latency P95 210.51 ms 199.62 ms 🟢 -5.2%
Per-scenario breakdown & investigation details

Metrics below reflect the current branch (after). Δ P95 compares against the base.

Scenario P50 (ms) P95 (ms) Requests RPS Δ P95 (ms)
API total 85.93 199.62 12,540 202.27 -10.89
Account 167.92 308.11 660 11.14 -24.38
TablesDB 83.39 162.47 6,820 111.5 +14.52
Storage 77.27 167.13 3,300 56.36 -9.25
Functions 125.06 238.88 1,760 30.74 -23.07

Top API waits (after)

API request Max wait (ms)
account.name.update 552.14
account.prefs.update 459.99
functions.create 420.89
storage.buckets.create 393.94
functions.delete 369.76

Throwing before the rule lookup failed jobs that should be skipped and
left a generating rule to be retried. The existing failure path marks the
rule unverified, and no mail is queued when there is no address.
A failed issuance stores a low attempt count and a due renew date.
Maintenance keeps enqueueing that certificate, and the follow-up job
skips it once the rule is unverified, so the count never reaches the cap.

Copy link
Copy Markdown
Member Author

@hansi-codes review

@hansi-codes

hansi-codes Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

🟢 Tier S · Ready to merge

Both previously reported issues are fixed, and the reviewed changes have no remaining concrete defects.

Moves the certificate-email requirement from worker resource creation to certificate issuance, allowing deletion cleanup to run without an email configured. Missing-email issuance failures are recorded on the rule, capped against maintenance retries, and do not enqueue notification mail. Adds library and proxy e2e regression coverage.

Verdict New comments Fixed Still open
✅ Approved 0 2 0
📂 Walkthrough · 5
File Change
app/worker.php Creates the certificate provider without requiring an email at resource resolution.
src/Appwrite/Certificates/LetsEncrypt.php Adds environment-based construction and checks the email when issuing.
src/Appwrite/Platform/Workers/Certificates.php Records missing-email failures, retains the persisted certificate ID, and skips mail without a recipient.
tests/e2e/Services/Proxy/CertificatesCustomServerTest.php Covers failure persistence, API-visible state, mail suppression, and skipped generation.
tests/unit/Certificates/LetsEncryptTest.php Covers email requirements, environment fallback, and email-independent file removal.
✅ Fixed since the last review · 2
  • Retain the newly created certificate on the early failure path · src/Appwrite/Platform/Workers/Certificates.php:317
  • Cover worker behavior through the required e2e surface · tests/unit/Workers/CertificatesDomainValidationTest.php:79

Reviewed 71affe2 · Details · Comment @hansi-codes review to re-run, or mention @hansi-codes with a question.

@hansi-codes hansi-codes Bot left a comment

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.

🟡 Tier B · 1 blocking finding to address. Summary

Comment thread src/Appwrite/Platform/Workers/Certificates.php
Comment thread tests/unit/Workers/CertificatesDomainValidationTest.php Outdated
A missing email throws before the in-try upsert, and the failure path
was reading the id from the unsaved document. Keep the upsert result so
the rule stores that certificate.

The worker regressions now run in the proxy e2e suite against the
platform database. The Let's Encrypt client stays in the unit suite.
@cursor

cursor Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The missing-email failure now keeps the certificate returned by the upsert, so a rule that did not have one yet stores that certificateId.

The two worker regressions moved to tests/e2e/Services/Proxy/CertificatesCustomServerTest.php and run against the platform database, then the rule API. tests/unit/Certificates/LetsEncryptTest.php still covers the client. The older DNS checks in CertificatesDomainValidationTest are unchanged.

Copy link
Copy Markdown
Member Author

@hansi-codes review

@hansi-codes hansi-codes Bot left a comment

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.

🟢 Tier S · Looks good to merge. Summary

This branch has not been deployed

No deployments
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.

🐛 Bug Report: Deletes worker fails without a certificate email

1 participant