Add Hub early access and CE routing in billing#147
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds 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
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
i18n/de.yamli18n/en.yamllayouts/hub-managed/single.html
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
assets/js/hubsubscription.jsi18n/de.yamli18n/en.yamllayouts/hub-billing/single.html
🚧 Files skipped from review as they are similar to previous changes (1)
- i18n/de.yaml
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
layouts/partials/checkbox.html (1)
4-4: Keep the HTML trust boundary at the call site.
checkbox.htmlis 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| safeHTMLexplicitly.♻️ 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| safeHTMLat 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
📒 Files selected for processing (3)
i18n/de.yamli18n/en.yamllayouts/partials/checkbox.html
🚧 Files skipped from review as they are similar to previous changes (1)
- i18n/en.yaml
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
assets/js/hubsubscription.jslayouts/hub-billing/single.html
🚧 Files skipped from review as they are similar to previous changes (1)
- layouts/hub-billing/single.html
Summary
oldLicense(JWT) andreturnUrlfrom URL fragment in Hub billing page, with fallback to query params for backward compatibilityoldLicenseis present and the instance is confirmed as self-hosted (custom billing returns 404 ormanaged: false)hubTokenandverificationTokeninto a singleoldLicensevariable — both are Hub License JWTs, sooldLicensenow also serves as the token for license refreshDetails
Hub 1.5.0+ clients pass
oldLicense(JWT) andreturnUrlin 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. WhenoldLicenseis present and the instance is confirmed as self-hosted (custom billing API returns 404 ormanaged: false), a "Community" column appears as the first option in the checkout view, linking to/hub/registerfor a free license with up to 5 seats.The checkbox partial (
layouts/partials/checkbox.html) now wraps the input inside the label and usessafeHTMLto render HTML content. Multiline labels align correctly using CSSpadding-left+ negativetext-indent.