Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Mail Builder Laravel Package

dophp/laravel-mail-builder

dophp/laravel-mail-builder provides a fluent, code-driven way to compose rich HTML emails in Laravel, helping you build and send templated messages without hand-writing markup. A lightweight helper for cleaner mailables.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • getodden/mail remains a Laravel-first package: Composer install, vendor:publish for frontend assets, and an optional Filament field (php artisan filament:assets). No separate service, queue, or migration. v2.5.3 adds no infrastructure.
  • The editor is still a custom element (<odden-mail-editor>) driven by a JSON schema export (v3 as of v2.4.0). v2.5.3 does not touch the schema or the editor bundle.
  • The risk profile has shifted surface. v2.4.0 was a UI release that explicitly left persistence and rendering untouched. v2.5.3 changes server-side email compilation — specifically CID image embedding in MailBuilder::embedCidImages() and CidImageEmbedder::embed(). Compiled output is no longer in the "unchanged" category for base-path callers.
  • This is a security hardening release. The described defect is a path-traversal / arbitrary local file read: a relative src such as ../secret in HTML could attach a file from outside the base directory to an outgoing email. That is a confidentiality issue, not just a correctness one.

Integration feasibility

  • Upgrade path is unchanged: composer update getodden/mail. No asset republish required for v2.5.3 (no new bundles, no new module imports), though republishing is harmless if the pipeline always does it.
  • Behavior change is conditional and knowable. Only code that passes a base path is affected; calls without one (data URIs only) behave as before. So the blast radius is enumerable by grepping for embedCidImages( and CidImageEmbedder usage and checking for a base-path argument.
  • Four new acceptance criteria now gate embedding: (1) path resolves inside the base path, (2) regular readable file, (3) ≤ 5 MB, (4) image MIME type. URLs, stream wrappers (php://, file://), and protocol-relative addresses are never treated as local paths. Each criterion is a potential silent drop.
  • No new dependencies, no schema change, no data migration. Licensing and supply-chain exposure unchanged.
  • Version gap to close: we are moving from an assessment of v2.4.0 to v2.5.3 — we have no release notes for v2.4.1 through v2.5.2 in hand. We should not assume those are all inert.

Technical risk

  • Moderate, and elevated versus v2.4.0 — not because the change is large, but because the failure mode is silent and reaches the customer. Previously a broken deploy produced a visibly broken editor in an admin panel. Now a filtered image produces an email that sends successfully with a missing image.
  • Silent image omission is the highest-likelihood failure: images whose src resolved outside the base path, exceeded 5 MB, had a non-image MIME type, or used a wrapper/URL form now fail to embed. Some of these are legitimate images that a permissive check previously accepted (e.g. large hero images over the 5 MB threshold).
  • Possible prior exposure. If any of our code passes a base path together with HTML we do not fully control (user-authored templates, imported HTML, tenant content, pasted markup), earlier versions may have attached unintended local files to outbound mail. That warrants an exposure review, not just a version bump.
  • Secondary risk: MIME-type gating may reject content we consider valid images — SVG (image/svg+xml), HEIC, or images served with generic application/octet-stream type. Needs a concrete test.
  • Editor-side risks from v2.4.0 (missing icons.js, stale bundles, --force overwriting customized assets, changed keyboard navigation) remain valid and unaddressed by this release.

Key questions

  • Do any of our call sites pass a base path to embedCidImages() / CidImageEmbedder::embed()? This is the single question that determines impact. Everything else is conditional on it.
  • If yes: is the HTML ever influenced by end users, tenants, imports, or third parties? If so, run an exposure review for outbound mail sent on prior versions.
  • Do any of our templates reference images outside the intended base path, use ../ segments, stream wrappers, or protocol-relative // sources — deliberately or by accident?
  • Do any of our legitimately embedded images exceed 5 MB or carry a non-image MIME type (SVG, HEIC, octet-stream)? What is our largest typical embedded asset?
  • How does the embedder behave on rejection — silent skip, logged warning, or thrown exception? Can we detect a dropped image before send?
  • What changed in v2.4.1 – v2.5.2? Do we have those notes, and is there a linked advisory/CVE for this hardening?
  • Unchanged from prior assessment: editor via Filament or self-hosted? Are published assets in VCS or built in CI? Who republishes on bump? Is the schema export a documented contract? Any locally modified published assets or CSP/asset-origin restrictions? Which Filament majors are supported?

Integration Approach

Stack fit

  • Native fit unchanged: Laravel + Filament, no new infrastructure, no runtime service, no queue or storage change.
  • The editor still works browser-side against the JSON document, and the new palette/tabs/search from v2.4.0 are unaffected.
  • The changed component is the server-side CID embedding path used when compiling outbound mail. That sits inside our existing send/preview pipeline — no new integration, but it is now a code path we must reason about rather than treat as opaque.

Migration path

  1. Audit before upgrading. Grep for embedCidImages( and CidImageEmbedder and classify each call site: passes a base path / does not. Record them.
  2. For base-path call sites, characterize the HTML source: fully controlled by us, or influenced by users/imports. Escalate any user-influenced case to a security/exposure review.
  3. Confirm composer update getodden/mail lands v2.5.3, and review notes for v2.4.1–v2.5.2 before merging.
  4. Exercise a representative sample of real templates through the embedder in staging, with instrumentation to detect dropped images. Include: a normal image, an image over 5 MB, an SVG, a remote URL, and (in a throwaway test) a ../ path.
  5. Decide whether any rejected-but-intended images need remediation — re-encode to an accepted format, downscale under the limit, or move to a data URI / remote URL.
  6. Deploy through the normal release path. No asset cache-bust required for this release, though the v2.4.0 cache-bust obligation still stands for anyone not yet on 2.4.0.
  7. Re-run the standard editor smoke test (icons.js present, palette/search/tabs render) if assets were republished in the same window.

Compatibility

  • Stored documents: unchanged.
  • Schema export consumers: unchanged by this release (v3 additive contract from 2.4.0 still applies).
  • Editor assets: unchanged by this release; the v2.4.0 icons.js non-backward-tolerance still applies to partial asset deploys.
  • Compiled email: changed for base-path callers. This is the compatibility break to document. Calls without a base path are explicitly unaffected.
  • Semver note: shipping a behavior change under a patch version is common for security fixes, but it means "patch bump ⇒ safe" reasoning no longer holds for this package.

Sequencing

  • Treat as a security-priority change, not a routine minor. Sequence: call-site audit → exposure review (if user-influenced HTML) → dependency bump → staged template sampling with drop detection → production.
  • Do the audit first; it may reveal the change is a no-op for us (all calls data-URI-only) and collapse the risk to trivial.
  • Keep this independent of any in-flight editor/palette work so a missing-image regression is attributable.
  • Schedule the exposure review in parallel, not after — if it finds something, notification obligations may have their own clock.

Operational Impact

Maintenance

  • New recurring obligation: track security advisories and release notes for this package, not just version numbers. We learned about a path-traversal fix from a patch release; that channel needs an owner.
  • Standing v2.4.0 obligation still applies: published editor assets must be re-published on bumps, and the step is easy to miss because Composer succeeds without it. Codify in the upgrade runbook with a post-deploy presence check for icons.js.
  • Track the schema export version (v3) explicitly if we maintain a custom palette.
  • No new dependency to patch; inlined icons mean no added npm/Composer supply-chain surface.

Support

  • Expect a different ticket shape than v2.4.0. Instead of "the block list looks different," expect "the image is missing from the email we sent" — reported by recipients or downstream teams, often well after send, and hard to trace back to a deployment.
  • Give support a triage line: if a missing image is reported, check asset size (≤ 5 MB), MIME type, and whether the source was a URL vs. local path.
  • Editor-facing guidance from v2.4.0 still stands: short labels ("Quote", "Logo wall", "Sidebar split") mean tooltips and accessible names carry the full name; help-center articles should reference group headings and search rather than "scroll the block list." Four icon-only changes (three_column, order_receipt, dynamic_feed, labeled_divider) remain worth a changelog line.
  • If the exposure review finds prior leakage, support/comms may need a scripted response — coordinate with legal/security rather than improvising.

Scaling

  • No impact on throughput, database, or editor performance. The change is a validation gate in an existing code path.
  • Minor: the 5 MB cap bounds per-image memory during embedding — mildly protective for large-template workloads. Confirm the check reads metadata rather than loading whole files.
  • Asset delivery: unchanged by this release; the one extra module (icons.js) from v2.4.0 remains the only added fetch.

Failure modes

  • Silent image omission on send (out-of-base-path, > 5 MB, non-image MIME, wrapper/protocol-relative URL): email delivers successfully with a broken or absent image. Highest-probability and highest-visibility failure. Mitigate with a drop-detection check in staging and, ideally, a pre-send assertion.
  • Legitimate large or unusual images rejected: hero images over 5 MB, SVG/HEIC sources. Mitigate by inventorying embedded assets against the four criteria.
  • Templates that relied on ../ traversal: intentionally or accidentally dependent on the old permissive behavior. These will now fail — verify none of ours do, and treat any that do as a bug on our side.
  • Undetected prior data exposure: files attached to outbound mail on earlier versions. Not a deployment failure but a live incident risk; addressed only by the exposure review.
  • Unreviewed intermediate versions: jumping 2.4.0 → 2.5.3 without notes for 2.4.1–2.5.2 leaves unknown changes unassessed.
  • Inherited v2.4.0 modes (still live): missing icons.js breaks the editor; stale cached bundles cause JS/CSS mismatch; --force silently discards patched published assets; custom palettes reading v3 keys without fallbacks break on older schemas; keyboard QA scripts may false-negative on the new tabs pattern.

Ramp-up

  • Low for engineers mechanically (one Composer command, no asset work). The real cost is the audit and exposure review, which is judgment work, not installation work.
  • Budget roughly one day of engineering: half a day for call-site audit and template sampling with drop detection, plus review of the missing intervening release notes. Add security/legal time if any base-path call site consumes user-influenced HTML.
  • Content editors need no retraining for v2.5.3; the v2.4.0 walkthrough (tile palette, search, Blocks/Structure tabs) still stands if not yet delivered.
  • No vendor onboarding or architecture review required.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource