- Add brand_name_form partial to personalization settings page
- Use brand_name or PRODUCT_NAME in title partial instead of hardcoded WaboSign
- Add missing EncryptedConfig::GOOGLE_SSO_KEY constant
- Replace deleted Docuseal module references with Wabosign in powered_by and email_attribution
Account admins can now replace "WaboSign" in the UI, emails, audit-trail
PDFs, and authenticator-app issuer with their own product name. The
brand override is stored as an AccountConfig row (brand_name key),
managed from /settings/personalization above the logo upload.
Resolution flows through Wabosign.branded_product_name(account = nil):
1. account&.brand_name if a record is passed
2. else the deployment's oldest non-archived account's brand_name
(so anonymous surfaces like the landing page, PWA manifest, and
og:title get the operator's brand on single-tenant installs)
3. else Wabosign::PRODUCT_NAME ("WaboSign")
AGPL §7(b) DocuSeal attribution stays untouched:
- _powered_by.html.erb second line keeps Wabosign::UPSTREAM_NAME
- _email_attribution.html.erb second paragraph keeps it
- completed.vue keeps its hardcoded DocuSeal link
The Wabosign::UPSTREAM_NAME and UPSTREAM_URL constants stay constants —
they are never overridable.
Swapped 41 direct Wabosign.product_name callers to pass the most-local
account in scope (current_account, @template.account,
@submitter.submission.account, submission.account, or nil for chrome
without account context). Mailers' default `from:` is now a lambda that
reads @current_account per message. SIGN_REASON constant in
generate_result_attachments became sign_reason_template(account) so
PDF signature reasons reflect the brand.
The two i18n keys actually rendered with literal "WaboSign"
(welcome_to_wabosign in templates_dashboard, connect_to_wabosign_mcp
in mcp_settings) are parameterized to %{product_name} across the 7
locales that defined them. The other ~9 WaboSign-branded i18n keys
are unreferenced dead code from the Pro paywall and stay as-is.
Specs:
spec/models/account_spec.rb (new) — Account#brand_name
spec/lib/wabosign_spec.rb (new) — branded_product_name precedence
spec/requests/personalization_settings_spec.rb (new) — end-to-end
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
erblint's autocorrect on the prior commit stripped the opening
<% tag from the variable-assignment block in
app/views/shared/_account_logo.html.erb, leaving plain Ruby code as
literal HTML and a NameError on every render. The "Failure/Error:
<% if acc&.logo&.attached? %>" cascade in CI was 40+ specs hitting
this partial via the navbar / start_form / submit_form / share-link
QR / submission show paths. Restoring the proper <% ... %> tag.
Also drop the now-redundant `# rubocop:disable Rails/Exit` comments
in spec/rails_helper.rb (CI's rubocop-rails doesn't flag those
lines) and add the same path to .rubocop.yml's Rails/Exit Exclude
so the project's local rubocop agrees.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously CI had never run on the wabolabs/wabosign fork (Actions
gated until owner consent). Now that the gate is lifted, run rubocop /
erblint / brakeman / rspec against current master uncovered backlog:
- rubocop: 97 auto-corrected across the WaboSign-fork files (account
logo, SMS, SSO, ability specs, role auth specs, omniauth callbacks).
Remaining 8 fixed by hand:
* lib/wabosign.rb chained map collapsed to filter_map; `hd` param
renamed to `hosted_domain` (Naming/MethodParameterName)
* app/models/user.rb default_sso_account split for line length +
SafeNavigation
* spec/rails_helper.rb abort calls marked `# rubocop:disable
Rails/Exit` (upstream pattern, intentional)
* spec/requests/users/omniauth_callbacks_spec.rb let! used for
side-effect-only setup -> moved into before blocks
- erblint: 21 auto-corrected (mostly Style/StringLiterals from a
sed substitution that picked double quotes) + a missing
autocomplete attribute added to the SMS test-message input.
- brakeman: clean. Removed one obsolete ignore entry (was for the
deleted enquiries controller) and added one new ignore for the
MCP-settings token preview (HighlightCode returns escaped HTML).
- rspec: dashboard "shows the list of templates" was flaky because
other_template's Faker::Book.title could randomly collide with one
of the 5 in-account templates. Pin the name to a unique suffix.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sweep of stale upstream cruft and missing release-process plumbing:
- SECURITY.md routes vuln reports to wabosign@wabo.cc
- package.json renamed wabosign + license/repository fields
- Drop the docuseal.com fallback href in signature_step.vue
- Delete docs/api/ (10 upstream language stubs) and rewrite stale
docuseal.com URLs in docs/openapi.json + docs/embedding/* +
docs/webhooks/* to sign.wabo.cc
- Remove console_redirect + enquiries controllers and routes
(/upgrade, /manage, /console_redirect were DocuSeal-SaaS-only).
Strip the navbar Console icon, the embed_scripts upgrade-to-Pro
fallback, the sessions_controller CONSOLE_URL redirect, and the
CONSOLE_URL/CDN_URL/CLOUD_URL/ENQUIRIES_URL constants. The four
"Learn more" links in templates/_embedding.html.erb now point at
sign.wabo.cc/docs/embedding; the two CDN script-src refs use the
local embed_script_url helper.
- Dockerfile gains OCI image labels via ARG VERSION/REVISION
- docker.yml passes labels + build-args from metadata-action@v5 so
the published image has the right manifest-level metadata
- Add CHANGELOG.md (Keep-a-Changelog) and a Releases section in README
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the disabled "logo upload not bundled in OSS" placeholder
with a real upload flow. Logos attach to the Account via ActiveStorage
(`has_one_attached :logo`) and replace the default WaboSign mark at
every render site that previously rendered `shared/_logo`.
Accepted formats: PNG, JPEG, and SVG. SVGs go through
`AccountLogo.sanitize_upload` before storage:
- `<script>` and `<foreignObject>` elements removed
- every `on*` attribute stripped (onclick, onload, onerror, …)
- `href` / `xlink:href` dropped unless the value starts with `#`
(in-doc fragment) or `data:` (inert in <img> context)
Raster uploads pass through unchanged. 2 MB upload cap on all formats.
Dispatch is a new `shared/_account_logo.html.erb` partial — takes an
optional `account:` local and emits either `<img>` (logo attached) or
falls back to the existing inline `shared/_logo.html.erb` SVG. All
swapped render sites pass the right account expression:
- shared/_title.html.erb → current_account
- start_form/_brand_logo.html.erb → @template.account
- submit_form/_brand_logo.html.erb → @submitter.submission.account
- templates_uploads/show.html.erb → current_account
- submissions/_logo.html.erb → @submission || @submitter accounts
- templates_share_link_qr/_logo.html.erb → @template.account
The landing page stays on the default mark (no account context).
Static favicon/PWA manifest/preview.png stay on the default brand.
Audit-trail PDF (`lib/submissions/generate_audit_trail.rb#add_logo`)
now calls `PdfIcons.account_logo_io(submission.account)`. SVG logos
are rasterized to PNG via ActiveStorage variants (libvips + librsvg,
both present in the production image via the `vips` Alpine pkg). On
any failure path the helper logs and falls back to `PdfIcons.logo_io`
so audit-trail generation never crashes on a bad logo.
Routes: `resource :account_logo, only: %i[create destroy]` nested
under `/settings`. AccountLogoController authorizes via
`authorize!(:manage, current_account)` and routes the form back to
`/settings/personalization` on success or failure.
Specs (11/11 pass in the Ruby 4.0.1 + Postgres-14 container):
- spec/lib/account_logo_spec.rb — 6 sanitizer unit cases
- spec/requests/account_logo_controller_spec.rb — 5 request cases
Smoke-tested end-to-end in the built image:
- PNG round-trips through attach/download.
- Malicious SVG (`<script>` + onload + alert) saves with all three
payloads scrubbed from the stored bytes.
- SVG → PNG rasterization for the PDF path produces a 18 KB PNG
with valid PNG magic — confirms libvips/librsvg is actually
wired in the production Alpine image.
- After purge, `PdfIcons.account_logo_io` is byte-identical to
`PdfIcons.logo_io` (clean fallback).
- /settings/personalization renders the new form with all expected
fields.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Renames the product to WaboSign across UI, mailers, locales, assets, and
internal Ruby module. Keeps the upstream DocuSeal attribution required by
AGPLv3 §7(b) in the powered-by footer, email attribution, README, and a
new NOTICE file. Migration renames the AATL cert identifier in encrypted
configs from docuseal_aatl to wabosign_aatl.
Removes multitenant-gated Pro upsell UI (Plans/Console/Upgrade links,
SMS/SSO/bulk-send/logo placeholders, reminder-duration restriction, the
"DocuSeal Pro" email-attribution toggle, conditions/formula/payment
pricing links) so every shipped feature is reachable on a self-hosted
deployment. Multitenant routing logic is preserved.
Drops Discord, Twitter, and ChatGPT/AI-assistant chrome. Embedding
modal keeps the upstream <docuseal-form> / @docuseal/* SDK contract so
existing embedded forms continue to work; documented in NOTICE.
REBRANDING.md captures the change inventory for future maintainers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>