Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions app/controllers/white_label_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ def render_gate(agreement, error: nil)
be taken to a secure page to add a payment method — no account or login required.</p>
#{err_html}
<h2>Master Services & White-Label / SDK License Agreement (#{agreement.msa_version})</h2>
<pre class="doc">#{ERB::Util.html_escape(msa)}</pre>
<div class="doc">#{markdown_to_html(msa)}</div>
<h2>Acceptable Use & Service Terms (#{agreement.terms_version})</h2>
<pre class="doc">#{ERB::Util.html_escape(terms)}</pre>
<div class="doc">#{markdown_to_html(terms)}</div>
<form method="post" action="/white-label/#{ERB::Util.html_escape(params[:token])}/accept">
<label>Full name<input name="signer_name" required value="#{ERB::Util.html_escape(params[:signer_name].to_s)}"></label>
<label>Title<input name="signer_title" required value="#{ERB::Util.html_escape(params[:signer_title].to_s)}"></label>
Expand Down Expand Up @@ -112,6 +112,46 @@ def doc_body(kind, version)
raw.sub(/\A<!--.*?-->\s*/m, "").strip
end

# Minimal Markdown -> HTML for the legal docs (no gem dependency): headings,
# bold, unordered lists, horizontal rules, paragraphs. All content is escaped.
def markdown_to_html(text)
out = +""
@list_open = false
text.each_line do |raw|
line = raw.rstrip
if line.empty?
out << close_md_list
elsif (m = line.match(/\A(\#+)\s+(.*)\z/))
out << close_md_list
level = [m[1].length, 6].min
out << "<h#{level}>#{inline_md(m[2])}</h#{level}>"
elsif (m = line.match(/\A[-*]\s+(.*)\z/))
unless @list_open
out << "<ul>"
@list_open = true
end
out << "<li>#{inline_md(m[1])}</li>"
elsif line.match?(/\A-{3,}\z/)
out << close_md_list << "<hr>"
else
out << close_md_list << "<p>#{inline_md(line)}</p>"
end
end
out << close_md_list
out
end

def close_md_list
return "" unless @list_open

@list_open = false
"</ul>"
end

def inline_md(str)
ERB::Util.html_escape(str).gsub(/\*\*(.+?)\*\*/) { "<strong>#{Regexp.last_match(1)}</strong>" }
end

def layout(inner)
<<~HTML
<!doctype html><html lang="en"><head><meta charset="utf-8">
Expand All @@ -122,8 +162,12 @@ def layout(inner)
max-width:760px;margin:0 auto;padding:32px 20px;background:#fafafa}
h1{font-size:26px;margin:0 0 8px} h2{font-size:18px;margin:28px 0 8px}
.lead{color:#444} .err{background:#fde8e8;color:#9b1c1c;padding:10px 14px;border-radius:8px}
pre.doc{white-space:pre-wrap;background:#fff;border:1px solid #e2e2e2;border-radius:10px;
padding:18px;max-height:320px;overflow:auto;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}
.doc{background:#fff;border:1px solid #e2e2e2;border-radius:10px;padding:18px 22px;
max-height:360px;overflow:auto}
.doc h1{font-size:20px;margin:0 0 10px} .doc h2{font-size:16px;margin:18px 0 6px}
.doc h3{font-size:14px;margin:14px 0 4px} .doc p{margin:0 0 10px;font-size:14px;color:#333}
.doc ul{margin:0 0 10px 18px;padding:0} .doc li{font-size:14px;color:#333;margin:3px 0}
.doc hr{border:0;border-top:1px solid #eee;margin:14px 0} .doc strong{font-weight:600}
form{background:#fff;border:1px solid #e2e2e2;border-radius:10px;padding:18px;margin-top:24px}
label{display:block;margin:0 0 14px;font-weight:600}
label.check{font-weight:400;display:flex;gap:8px;align-items:flex-start}
Expand Down
18 changes: 9 additions & 9 deletions config/white_label/msa_v1.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<!--
White-Label / SDK Master Services Agreement
version: v1 (the acceptance gate records THIS version string against each signer)
status: DRAFT — must be reviewed by qualified counsel before it is presented to a customer.
Bracketed [LIKE_THIS] tokens are deliberate fill-ins. Do not ship with brackets unresolved.
status: DRAFT — reviewed by qualified counsel still recommended before presenting to a customer.
Entity filled: Thinkfleet AI, LLC (NC) d/b/a Flobyte; governing law North Carolina.
-->

# Master Services & White-Label / SDK License Agreement

**Version v1 — Effective on acceptance**

This Master Services & White-Label / SDK License Agreement (the **"Agreement"**) is entered into between **[LEGAL ENTITY NAME], a [STATE/COUNTRY] [entity type]** ("**Flobyte**", "**we**", "**us**") and the entity that accepts this Agreement ("**Customer**", "**you**"). By clicking "I Accept," signing an order, or accessing the Service, the individual accepting represents that they are authorized to bind Customer, and Customer agrees to this Agreement as of that date (the "**Effective Date**").
This Master Services & White-Label / SDK License Agreement (the **"Agreement"**) is entered into between **Thinkfleet AI, LLC, a North Carolina limited liability company doing business as "Flobyte"** ("**Flobyte**", "**we**", "**us**") and the entity that accepts this Agreement ("**Customer**", "**you**"). By clicking "I Accept," signing an order, or accessing the Service, the individual accepting represents that they are authorized to bind Customer, and Customer agrees to this Agreement as of that date (the "**Effective Date**").

## 1. Definitions

Expand Down Expand Up @@ -46,9 +46,9 @@ Customer will not, and will not permit any End User to: (a) reverse engineer, de

5.2 **Billing & auto-charge.** Fees are billed in advance each billing period through Flobyte's billing processor. By providing a payment method, Customer authorizes Flobyte and its processor to automatically charge that method for all Fees, including renewals and usage charges, until the Agreement is terminated.

5.3 **Auto-renewal.** Subscriptions renew automatically for successive periods equal to the initial term unless either party gives notice of non-renewal at least [30] days before the end of the then-current period.
5.3 **Auto-renewal.** Subscriptions renew automatically for successive periods equal to the initial term unless either party gives notice of non-renewal at least 30 days before the end of the then-current period.

5.4 **Late payment.** Overdue amounts accrue interest at the lesser of 1.5% per month or the maximum permitted by law. Flobyte may suspend the Service for non-payment after [10] days' notice.
5.4 **Late payment.** Overdue amounts accrue interest at the lesser of 1.5% per month or the maximum permitted by law. Flobyte may suspend the Service for non-payment after 10 days' notice.

5.5 **Taxes.** Fees are exclusive of taxes. Customer is responsible for all taxes other than taxes on Flobyte's net income.

Expand All @@ -58,7 +58,7 @@ Customer will not, and will not permit any End User to: (a) reverse engineer, de

6.1 **Term.** This Agreement begins on the Effective Date and continues for the subscription term in the Order, renewing under Section 5.3.

6.2 **Termination for cause.** Either party may terminate for the other's material breach not cured within [30] days of notice (or immediately for breach of Sections 3, 4, 7, or 8).
6.2 **Termination for cause.** Either party may terminate for the other's material breach not cured within 30 days of notice (or immediately for breach of Sections 3, 4, 7, or 8).

6.3 **Effect.** On termination, all licenses and White-Label Rights end, Customer ceases use of the Service and SDK, and any accrued Fees become due. Sections that by their nature survive (including 4, 7–12) survive termination.

Expand All @@ -80,7 +80,7 @@ Each party will protect the other's Confidential Information with at least reaso

9.1 Flobyte will maintain commercially reasonable administrative, technical, and organizational safeguards designed to protect Customer Data.

9.2 To the extent Flobyte processes personal data on Customer's behalf, the parties will comply with the Data Processing Addendum at **[DPA URL]**, which is incorporated by reference.
9.2 To the extent Flobyte processes personal data on Customer's behalf, the parties will comply with Flobyte's Data Processing Addendum, which Flobyte will make available upon request and which is incorporated by reference.

9.3 Customer is responsible for the legality of Customer Data and for obtaining all consents required from its End Users.

Expand Down Expand Up @@ -114,11 +114,11 @@ Customer will comply with all applicable laws, including export controls, sancti

14.2 **Assignment.** Neither party may assign this Agreement without the other's consent, except to a successor in a merger or sale of substantially all assets, with notice.

14.3 **Governing law; venue.** This Agreement is governed by the laws of the State of **[HOME_STATE]**, USA, without regard to conflicts rules. The parties submit to the exclusive jurisdiction of the state and federal courts located in **[HOME_STATE_COUNTY/CITY], [HOME_STATE]**.
14.3 **Governing law; venue.** This Agreement is governed by the laws of the State of **North Carolina**, USA, without regard to conflicts rules. The parties submit to the exclusive jurisdiction of the state and federal courts of competent jurisdiction located in the State of North Carolina.

14.4 **Force majeure.** Neither party is liable for delays caused by events beyond its reasonable control.

14.5 **Notices.** Notices must be in writing to the parties' designated contacts (email permitted for routine notices; legal notices to **[NOTICE ADDRESS]**).
14.5 **Notices.** Notices must be in writing to the parties' designated contacts (email permitted for routine notices; legal notices to Flobyte at its registered business address or the email address Flobyte designates for legal notices).

14.6 **Entire agreement.** This Agreement and the Order are the entire agreement and supersede prior understandings. Any conflicting terms in Customer's purchase documents are rejected. Flobyte may update the Terms and the standard form of this Agreement prospectively for renewals.

Expand Down
2 changes: 1 addition & 1 deletion config/white_label/terms_v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Flobyte may suspend or limit the Service, in whole or part, to protect the Servi

## 7. Changes to These Terms

Flobyte may update these Terms prospectively. Material changes take effect at the next renewal or upon [30] days' notice. Continued use after the effective date constitutes acceptance.
Flobyte may update these Terms prospectively. Material changes take effect at the next renewal or upon 30 days' notice. Continued use after the effective date constitutes acceptance.

---

Expand Down
Loading