Skip to content

Add Hub early access and CE routing in billing#147

Merged
tobihagemann merged 7 commits intodevelopfrom
feature/hub-managed-early-access
Mar 6, 2026
Merged

Add Hub early access and CE routing in billing#147
tobihagemann merged 7 commits intodevelopfrom
feature/hub-managed-early-access

Conversation

@SailReal
Copy link
Member

@SailReal SailReal commented Mar 5, 2026

Summary

  • Add optional early access checkbox to Hub Managed signup form with BETA pill and link to docs
  • Parse optional oldLicense (JWT) and returnUrl from URL fragment in Hub billing page, with fallback to query params for backward compatibility
  • Show Community Edition column (free, up to 5 seats) when oldLicense is present and the instance is confirmed as self-hosted (custom billing returns 404 or managed: false)
  • Merge hubToken and verificationToken into a single oldLicense variable — both are Hub License JWTs, so oldLicense now also serves as the token for license refresh
  • Refactor checkbox partial to support HTML labels and fix multiline text alignment

Details

Hub 1.5.0+ clients pass oldLicense (JWT) and returnUrl in the URL fragment when directing users to /hub/billing. The code falls back to query params (hub_id, return_url) for backward compatibility with older clients.

The JWT's payload is decoded to extract the hubId. When oldLicense is present and the instance is confirmed as self-hosted (custom billing API returns 404 or managed: false), a "Community" column appears as the first option in the checkout view, linking to /hub/register for a free license with up to 5 seats.

The checkbox partial (layouts/partials/checkbox.html) now wraps the input inside the label and uses safeHTML to render HTML content. Multiline labels align correctly using CSS padding-left + negative text-indent.

@SailReal SailReal requested a review from tobihagemann March 5, 2026 16:55
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 158e560c-f3c5-429b-a0f5-c5b2666f3b72

📥 Commits

Reviewing files that changed from the base of the PR and between dedf735 and cca0546.

📒 Files selected for processing (1)
  • assets/js/hubsubscription.js

Walkthrough

Adds new i18n keys in English and German (accept_hub_managed_early_access_optional and six hub_billing_checkout_community_*). Adds submitData.earlyaccess and an optional Early Access checkbox to layouts/hub-managed/single.html. Updates assets/js/hubsubscription.js to read hubId, oldLicense (from URL fragment or query), and returnUrl from the URL fragment with query fallbacks and to use oldLicense across token flows. Adds subscriptionData.oldLicense and a conditional Community panel plus responsive layout adjustments to layouts/hub-billing/single.html. Refactors layouts/partials/checkbox.html to nest the input inside its label and render label HTML safely.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • overheadhunter
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add Hub early access and CE routing in billing' accurately summarizes the main changes: adding early access functionality and Community Edition routing in the billing section.
Description check ✅ Passed The description is clearly related to the changeset, detailing the early access checkbox, oldLicense parsing, Community Edition routing, and checkbox partial refactoring that align with file changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/hub-managed-early-access

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@i18n/de.yaml`:
- Around line 37-38: The German locale entry with key
accept_hub_managed_early_access_optional contains English text ("Early access");
update the translation in i18n/de.yaml for
accept_hub_managed_early_access_optional to the proper German label (e.g.,
"Früher Zugriff" or "Vorabzugang") so the UI is fully localized for German
users.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 06df7510-9bed-4777-b864-8520d6fac84f

📥 Commits

Reviewing files that changed from the base of the PR and between cb240a5 and 59387a5.

📒 Files selected for processing (3)
  • i18n/de.yaml
  • i18n/en.yaml
  • layouts/hub-managed/single.html

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/hubsubscription.js`:
- Around line 17-20: The JWT parsing in HubSubscription uses
this._subscriptionData.hubToken and directly accesses split('.')[1], atob and
JSON.parse which can throw for malformed tokens; wrap the decoding into a
try-catch around the block that computes base64 and sets
this._subscriptionData.hubId, first check that
this._subscriptionData.hubToken.split('.') yields at least 2 parts, add proper
base64 padding/replace as needed, and on any error set
this._subscriptionData.hubId = null (or delete this._subscriptionData.hubToken)
and emit a console.warn or logger message describing the malformed token so the
constructor doesn't throw.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27add001-abb3-480f-986e-8f38d32a3402

📥 Commits

Reviewing files that changed from the base of the PR and between 59387a5 and 5cd88d4.

📒 Files selected for processing (4)
  • assets/js/hubsubscription.js
  • i18n/de.yaml
  • i18n/en.yaml
  • layouts/hub-billing/single.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • i18n/de.yaml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
layouts/partials/checkbox.html (1)

4-4: Keep the HTML trust boundary at the call site.

checkbox.html is a shared partial, and {{ .label | safeHTML }} now marks every label as trusted HTML. That changes the helper’s contract and makes future call sites easier to misuse. Safer pattern is to render {{ .label }} here and let only the few rich-label callers opt into | safeHTML explicitly.

♻️ Proposed refactor
-  <input class="mr-2 rounded-sm text-primary focus:ring-0 focus:ring-offset-0 focus:border-secondary" type="checkbox" id="{{ $unique_id }}" x-model="{{ .alpineVariable }}" />{{ .label | safeHTML }}
+  <input class="mr-2 rounded-sm text-primary focus:ring-0 focus:ring-offset-0 focus:border-secondary" type="checkbox" id="{{ $unique_id }}" x-model="{{ .alpineVariable }}" />{{ .label }}

The HTML-bearing checkbox labels, such as the early-access copy in layouts/hub-managed/single.html:177-186, can then opt in with | safeHTML at the call site instead of making that decision globally in the partial.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@layouts/partials/checkbox.html` at line 4, The partial
layouts/partials/checkbox.html currently trusts every label by using "{{ .label
| safeHTML }}", which widens the HTML trust boundary; change the partial to
render the label untrusted as "{{ .label }}" (leave the rest of the input
element and attributes like id "{{ $unique_id }}" and x-model "{{
.alpineVariable }}" unchanged) and update only the specific call sites that
require rich HTML (e.g., the hub-managed single.html label) to pass in "{{
.label | safeHTML }}" at the point they invoke the checkbox partial so that HTML
is explicitly opted-in per caller.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@i18n/de.yaml`:
- Line 38: The translation string for the key "translation" contains an external
anchor with target="_blank" but lacks rel="noopener"; update that anchor in the
translation value (the <a class="text-link"
href="https://docs.cryptomator.org/hub/early-access/" target="_blank">...</a>
portion) to include rel="noopener" so the link becomes hardened against opener
attacks while preserving existing attributes and text.

---

Nitpick comments:
In `@layouts/partials/checkbox.html`:
- Line 4: The partial layouts/partials/checkbox.html currently trusts every
label by using "{{ .label | safeHTML }}", which widens the HTML trust boundary;
change the partial to render the label untrusted as "{{ .label }}" (leave the
rest of the input element and attributes like id "{{ $unique_id }}" and x-model
"{{ .alpineVariable }}" unchanged) and update only the specific call sites that
require rich HTML (e.g., the hub-managed single.html label) to pass in "{{
.label | safeHTML }}" at the point they invoke the checkbox partial so that HTML
is explicitly opted-in per caller.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7516c23e-66b5-49af-b624-f8c0a775ac2d

📥 Commits

Reviewing files that changed from the base of the PR and between 5cd88d4 and fabb181.

📒 Files selected for processing (3)
  • i18n/de.yaml
  • i18n/en.yaml
  • layouts/partials/checkbox.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • i18n/en.yaml

@tobihagemann tobihagemann changed the title Add Hub Early Access Handling Add Hub early access and CE routing in billing Mar 6, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/hubsubscription.js`:
- Around line 27-29: The code is double-decoding the returnUrl: variable
encodedReturnUrl is obtained via fragmentParams.get(...) or
searchParams.get(...), both of which already return decoded values, but then the
code calls decodeURIComponent again when assigning to
this._subscriptionData.returnUrl. Fix by removing the extra decodeURIComponent
call and assign the retrieved value directly (i.e., set
this._subscriptionData.returnUrl = encodedReturnUrl), in the same block where
encodedReturnUrl is defined so fragmentParams.get / searchParams.get are used
as-is.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9310a41-164e-46ca-8e51-3e03b4966264

📥 Commits

Reviewing files that changed from the base of the PR and between 4c53ee0 and dedf735.

📒 Files selected for processing (2)
  • assets/js/hubsubscription.js
  • layouts/hub-billing/single.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • layouts/hub-billing/single.html

@tobihagemann tobihagemann merged commit 53391bf into develop Mar 6, 2026
5 checks passed
@tobihagemann tobihagemann deleted the feature/hub-managed-early-access branch March 6, 2026 13:04
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