Recently Written · git

sbm-sync

Sync server for sbm bookmark files: one small Go program, plain files, AGPL

git clone https://github.com/equwal/sbm-sync

Log | Files | Refs


pages.html (23442 bytes)

1 {{define "head"}}<!doctype html>
2 <html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <title>{{if .Title}}{{.Title}} · {{end}}sbm Sync</title>
7 <meta name="description" content="Sync your sbm bookmarks between the terminal, the browser add-on and Android.">
8 <meta property="og:type" content="website">
9 <meta property="og:site_name" content="sbm Sync">
10 <meta property="og:title" content="{{if .Title}}{{.Title}} · {{end}}sbm Sync">
11 <meta property="og:description" content="Sync your sbm bookmarks between the terminal, the browser add-on and Android.">
12 <meta property="og:image" content="{{.URL}}/og.png">
13 <meta name="twitter:card" content="summary_large_image">
14 <meta name="theme-color" content="#005577">
15 <link rel="search" type="application/opensearchdescription+xml" title="sbm bookmarks" href="/opensearch.xml">
16 <style>
17 body { max-width: 36em; margin: 2em auto; padding: 0 1em; font: 16px/1.5 sans-serif; color: #222; background: #fff; }
18 a { color: #005577; }
19 h1 { font-size: 1.5em; } h2 { font-size: 1.15em; margin-top: 2em; }
20 label { display: block; }
21 input { display: block; width: 100%; box-sizing: border-box; margin: .2em 0 1em; padding: .4em; font: inherit; }
22 button { font: inherit; padding: .4em 1em; margin: .2em .5em .2em 0; }
23 .error { color: #a00; } .note, footer { color: #555; } footer { margin-top: 3em; font-size: .9em; }
24 select { font: inherit; padding: .3em; margin: .2em 0 1em; }
25 textarea { display: block; width: 100%; box-sizing: border-box; height: 60vh; margin: .2em 0 1em; font: 13px/1.4 monospace; }
26 details { margin: 1em 0; } summary { cursor: pointer; }
27 .bookmarks { list-style: none; padding: 0; } .bookmarks li { margin: .8em 0; overflow-wrap: anywhere; } .bookmarks small { color: #555; }
28 .bookmarks form { display: inline; } .bookmarks form button { padding: .1em .5em; margin: 0; font-size: .9em; }
29 .check { display: inline; width: auto; margin: 0 .4em 0 0; } pre { overflow-x: auto; }
30 @media (prefers-color-scheme: dark) {
31   body { background: #111; color: #ddd; } a { color: #4fb3d9; } .note, footer, .bookmarks small { color: #999; } .error { color: #f77; }
32 }
33 </style>
34 </head>
35 <body>
36 <header><a href="/"><b>sbm Sync</b></a></header>
37 {{end}}
38 
39 {{define "foot"}}
40 <footer>
41 <a href="https://github.com/equwal/sbm-sync">Source code</a> ·
42 <a href="/privacy">Privacy</a> ·
43 <a href="/terms">Terms of sale</a> ·
44 <a href="https://ko-fi.com/truex">Support sbm on Ko-fi</a>
45 <nav aria-label="More sites and apps">
46 <p>More sites and apps:
47 <a href="https://subread.space/" title="Read along with an audiobook.">SubRead</a> ·
48 <a href="https://booksimulator.com/" title="A reading room for Aozora Bunko and Project Gutenberg books.">Book Simulator</a> ·
49 <a href="https://honjimaku.com/" title="Subtitles for Japanese audiobooks.">honjimaku.com</a> ·
50 <a href="https://dickt.store/" title="Language-learning tools, flashcards and web toys.">dickt.store</a> ·
51 <a href="https://hentaibun.online/" title="Learn kanbun and kobun.">hentaibun.online</a> ·
52 <a href="https://mowimypopol.online/" title="Archival study materials for Polish.">mowimypopol.online</a> ·
53 <a href="https://alljapanesealltheti.me/" title="All Japanese All The Time.">AJATT mirror</a> ·
54 <a href="https://recentlywritten.com/" title="The blog.">Recently Written</a></p>
55 <p>Apps:
56 <a href="https://github.com/equwal/sbm-android/releases/latest">sbm for Android</a> ·
57 <a href="https://github.com/equwal/sbm-extension/releases/latest">sbm add-on</a> ·
58 <a href="https://github.com/equwal/subread-android/releases/latest">SubRead for Android</a> ·
59 <a href="https://github.com/equwal/subread-overlay/releases/latest">SubRead Overlay</a> ·
60 <a href="https://github.com/equwal/subread-dictionary/releases/latest">SubRead Dictionary</a> ·
61 <a href="https://github.com/equwal/subread-anki">SubRead Anki</a> ·
62 <a href="https://github.com/equwal/subread-extension/releases/latest">SubRead for YouTube</a> ·
63 <a href="https://github.com/equwal/subread.koplugin">SubRead for KOReader</a> ·
64 <a href="https://github.com/equwal/subrep-android/releases/latest">Subrep</a> ·
65 <a href="https://github.com/equwal/rebind/releases">Rebind</a> ·
66 <a href="https://github.com/equwal/ink-recents/releases/latest">Ink Recents</a> ·
67 <a href="https://github.com/equwal/ink-dim/releases/latest">Ink Dim</a> ·
68 <a href="https://github.com/equwal/ink-update/releases/latest">Ink Update</a> ·
69 <a href="https://recentlywritten.com/projects.html">All projects</a></p>
70 </nav>
71 </footer>
72 </body>
73 </html>
74 {{end}}
75 
76 {{define "support"}}{{with .Support}}<p>sbm Sync is free. To pay for the server and the work on sbm,
77 <a href="{{.}}">become a supporter</a>.{{with $.Manage}} Supporters can
78 <a href="{{.}}">manage or cancel</a> their subscription.{{end}}</p>{{end}}{{end}}
79 
80 {{define "home"}}{{template "head" .}}
81 <h1>Your bookmarks, the same everywhere</h1>
82 {{if .Active}}<form id="search" method="get" action="/bookmarks">
83 <input type="search" name="q" placeholder="Search your bookmarks, or type an address" aria-label="Search your bookmarks" autocomplete="off" autofocus>
84 </form>
85 <div id="results" data-empty="clear"></div>
86 <script src="/search.js" defer></script>{{end}}
87 <p><a href="https://github.com/equwal/sbm">sbm</a> keeps your bookmarks in one plain
88 text file. sbm Sync keeps that file the same on each of your devices: bm on
89 your computers, the sbm app for Android, and the sbm add-on for Firefox and
90 Chrome. You can also use your bookmarks on this site, in any browser.</p>
91 {{if .Billing}}<p>Free for {{.TrialDays}} days. Then {{.Year}} or {{.Month}}. Cancel at any time.</p>{{end}}
92 <p>{{if .Email}}{{if .Active}}<a href="/bookmarks">Your bookmarks</a> · <a href="/feed">Your feed</a> · {{end}}<a href="/account">Your account</a>{{else}}<a href="/signup">Create an account</a> or <a href="/login">sign in</a>.{{end}}</p>
93 <p>The <a href="/feed">feed page</a> follows RSS and Atom feeds for you, and can
94 look through your bookmarks for feeds. Read it here, or with the sfeed tools
95 in a terminal.</p>
96 {{with .Teams}}<h2>Teams</h2>
97 <p>Coming: bookmarks for teams. The members of a team share one bookmark
98 file, and sync it on each of their devices. Pre-order the founding plan: <a href="{{.}}">for up to 10 people</a>{{with $.TeamsLarge}},
99 or <a href="{{.}}">for 11 people or more</a>{{end}}.</p>{{end}}
100 {{template "support" .}}
101 <h2 id="privacy">Your bookmarks stay yours</h2>
102 <ul>
103 <li>No ads, no analytics and no trackers. The only cookie keeps you signed in.</li>
104 <li>We do not sell or share your data.</li>
105 <li>Your bookmarks are one plain text file. You can read it, copy it and leave at any time.</li>
106 <li>You can delete your account and all copies on the server at once.</li>
107 <li>The source code is open. Anyone can check what the server does.</li>
108 </ul>
109 <p>The server does not encrypt your bookmark file. The operator of the server
110 can read it. If that is not acceptable, <a href="https://github.com/equwal/sbm-sync">run
111 your own server</a>. See the <a href="/privacy">privacy policy</a>.</p>
112 <p class="note">sbm Sync is free software under the AGPL-3.0.</p>
113 {{template "foot" .}}{{end}}
114 
115 {{define "signup"}}{{template "head" .}}
116 <h1>Create an account</h1>
117 {{with .Error}}<p class="error">{{.}}</p>{{end}}
118 <form method="post" action="/signup">
119 <label>Email <input type="email" name="email" value="{{.Email}}" required autocomplete="email"></label>
120 <label>Password, 8 characters or more <input type="password" name="password" minlength="8" maxlength="72" required autocomplete="new-password"></label>
121 <button>Create account</button>
122 </form>
123 <p class="note">See the <a href="/privacy">privacy policy</a>. You have an account? <a href="/login">Sign in</a>.</p>
124 {{template "foot" .}}{{end}}
125 
126 {{define "login"}}{{template "head" .}}
127 <h1>Sign in</h1>
128 {{with .Error}}<p class="error">{{.}}</p>{{end}}
129 <form method="post" action="/login">
130 <label>Email <input type="email" name="email" value="{{.Email}}" required autocomplete="email"></label>
131 <label>Password <input type="password" name="password" required autocomplete="current-password"></label>
132 <button>Sign in</button>
133 </form>
134 <p class="note">No account yet? <a href="/signup">Create one</a>.</p>
135 {{template "foot" .}}{{end}}
136 
137 {{define "account"}}{{template "head" .}}
138 <h1>Your account</h1>
139 <p>Signed in as {{.Email}}.</p>
140 {{if .Active}}<p><a href="/bookmarks"><b>Open your bookmarks</b></a> · <a href="/feed">Your feed</a></p>{{end}}
141 {{with .Error}}<p class="error">{{.}}</p>{{end}}
142 {{if .Unconfirmed}}<p><b>Confirm your email address.</b> Open the link in the
143 email that this server sent to {{.Email}}. Sync starts after that.</p>
144 <form method="post" action="/account/verify"><button>Send the email again</button></form>{{end}}
145 <p><b>{{.State}}</b></p>
146 {{if .CanSubscribe}}<form method="post" action="/account/checkout">
147 <button name="plan" value="year">Subscribe: {{.Year}}</button>
148 <button name="plan" value="month">Subscribe: {{.Month}}</button>
149 </form>{{end}}
150 {{if .Customer}}<form method="post" action="/account/portal"><button>Manage billing</button></form>{{end}}
151 {{template "support" .}}
152 
153 <h2>Connect your devices</h2>
154 <p>Sign in with this email and password on each device:</p>
155 <ul>
156 <li>bm on a computer: run <code>bm-sync login</code></li>
157 <li>the sbm app for Android: menu, Sign in to sync</li>
158 <li>the sbm add-on for Firefox or Chrome: its options page</li>
159 </ul>
160 <p>Server: <code>{{.URL}}</code></p>
161 <form method="post" action="/logout"><button>Sign out</button></form>
162 
163 <h2>Delete your account</h2>
164 <form method="post" action="/account/delete">
165 <p>This deletes your account and the copy of your bookmarks on this server at
166 once.{{if .Customer}} It also ends your subscription.{{end}} Your devices keep
167 their bookmark files.</p>
168 <label>Password <input type="password" name="password" required autocomplete="current-password"></label>
169 <button>Delete my account</button>
170 </form>
171 {{template "foot" .}}{{end}}
172 
173 {{define "nav"}}<p class="note"><a href="/bookmarks">Bookmarks</a> ·
174 <a href="/bookmarks/file">Edit the file</a> ·
175 <a href="/bookmarks.txt">Download</a> ·
176 <a href="/feed">Feed</a> ·
177 <a href="/account">Account</a></p>{{end}}
178 
179 {{define "feed"}}{{template "head" .}}
180 {{template "nav"}}
181 <h1>Your feed</h1>
182 {{with .Error}}<p class="error">{{.}}</p>{{end}}
183 {{with .Done}}<p><b>{{.}}</b></p>{{end}}
184 {{if not .Feeds}}<p>Follow a feed: type the address of an RSS or Atom feed
185 below, or turn on Explore in the settings, and the server looks through your
186 bookmarks for feeds. The server fetches new items every 30 minutes.</p>{{end}}
187 <details{{if eq .Open "add"}} open{{end}}><summary>Follow a feed</summary>
188 <form method="post" action="/feed/add">
189 <label>Feed URL <input name="url" value="{{.Form.URL}}" placeholder="https://example.org/rss.xml" required></label>
190 <label>Name <input name="name" value="{{.Form.Name}}"></label>
191 <button>Follow</button>
192 </form></details>
193 <details><summary>Settings</summary>
194 <form method="post" action="/feed/settings">
195 <label><input type="checkbox" class="check" name="newtab"{{if .Settings.NewTab}} checked{{end}}>Open links in a new tab</label>
196 {{if .HasMail}}<label><input type="checkbox" class="check" name="mail"{{if not .Settings.NoMail}} checked{{end}}>Send me the new items by email, once a day</label>{{end}}
197 <label><input type="checkbox" class="check" name="explore"{{if .Settings.Explore}} checked{{end}}>Explore: look through my bookmarks for feeds</label>
198 <button>Save</button>
199 </form></details>
200 <details><summary>Read the feed in a terminal</summary>
201 <p class="note">The items come in the <a href="https://codemadness.org/sfeed.html">sfeed</a>
202 format, newest first, with the token of a device (<code>bm-sync login</code>
203 keeps one in <code>~/.config/sbm/sync</code>):</p>
204 <pre>curl -H "Authorization: Bearer $token" {{.URL}}/api/feed | sfeed_plain</pre>
205 <p class="note"><code>{{.URL}}/api/feeds</code> gives the feeds that you follow, one on each line: the URL, a tab and the name.</p>
206 </details>
207 <p class="note">{{.Total}} items{{with .FilterName}} from <b>{{.}}</b>{{end}}.{{if .Filter}} <a href="/feed">All feeds</a>{{end}}</p>
208 <ul class="bookmarks">
209 {{range .Items}}<li>{{if .Link}}<a href="{{.Link}}"{{if $.Settings.NewTab}} target="_blank" rel="noopener"{{end}}>{{.Title}}</a>{{else}}{{.Title}}{{end}}<br>
210 <small><a href="/feed?feed={{.File}}">{{.Feed}}</a>{{if not .Time.IsZero}} · {{.Time.Format "2006-01-02 15:04"}}{{end}}{{with .Author}} · {{.}}{{end}}</small></li>
211 {{end}}</ul>
212 {{if .Next}}<p><a href="/feed?start={{.Next}}{{with .Filter}}&amp;feed={{.}}{{end}}">Older items</a></p>{{end}}
213 {{with .Feeds}}<h2>Feeds you follow</h2>
214 <p class="note"><a href="{{$.ShareAll}}">Share your list</a>: anyone with that link can follow these feeds
215 on sbm Sync, with an account or after they make one. Share opens the same kind of link for one feed.</p>
216 <ul class="bookmarks">
217 {{range .}}<li><a href="/feed?feed={{.File}}">{{.Name}}</a> <small>{{.URL}} · <a href="{{.Share}}">Share</a></small>
218 <form method="post" action="/feed/delete"><input type="hidden" name="url" value="{{.URL}}"><button>Unfollow</button></form></li>
219 {{end}}</ul>{{end}}
220 {{if .Settings.Explore}}<h2>Explore</h2>
221 <p class="note">The server looked at {{.Checked}} of your {{.Bookmarks}} bookmarked pages for feeds, 20 more with each update.{{if not .Suggestions}} No new feed to follow yet.{{end}}</p>
222 {{with .Suggestions}}<ul class="bookmarks">
223 {{range .}}<li>{{.URL}}<br><small>on {{.Page}}</small>
224 <form method="post" action="/feed/add"><input type="hidden" name="url" value="{{.URL}}"><input type="hidden" name="name" value="{{.Name}}"><button>Follow</button></form></li>
225 {{end}}</ul>{{end}}{{end}}
226 {{template "foot" .}}{{end}}
227 
228 {{define "bookmarks"}}{{template "head" .}}
229 {{template "nav"}}
230 <h1>Your bookmarks</h1>
231 {{with .Error}}<p class="error">{{.}}</p>{{end}}
232 {{with .Done}}<p><b>{{.}}</b></p>{{end}}
233 <form id="search" method="get" action="/bookmarks">
234 <input type="search" name="q" value="{{.Query}}" placeholder="Search, or type an address" aria-label="Search" autocomplete="off" autofocus>
235 {{with .Tag}}<input type="hidden" name="tag" value="{{.}}">{{end}}
236 <label>Order <select name="sort">
237 <option value="recent"{{if eq .Sort "recent"}} selected{{end}}>newest first</option>
238 <option value="url"{{if eq .Sort "url"}} selected{{end}}>URL</option>
239 <option value="desc"{{if eq .Sort "desc"}} selected{{end}}>description</option>
240 <option value="tag"{{if eq .Sort "tag"}} selected{{end}}>tag</option>
241 </select></label>
242 <button>Search</button>
243 </form>
244 <details{{if eq .Open "add"}} open{{end}}><summary>Add a bookmark</summary>
245 <form method="post" action="/bookmarks/add">
246 <label>URL <input name="url" value="{{.Form.URL}}" required></label>
247 <label>Description <input name="desc" value="{{.Form.Desc}}"></label>
248 <label>Tags, with spaces between them <input name="tags" value="{{.Form.Tags}}" autocomplete="off"></label>
249 <button>Add</button>
250 </form></details>
251 <details{{if eq .Open "import"}} open{{end}}><summary>Import bookmarks</summary>
252 <form method="post" action="/bookmarks/import" enctype="multipart/form-data">
253 <p class="note">Export the bookmarks of your browser to an HTML file, then
254 import that file here. Folders become tags. A file of sbm bookmark lines
255 works too. URLs that are bookmarks already are skipped.</p>
256 <label>File <input type="file" name="file" required></label>
257 <button>Import</button>
258 </form></details>
259 <details><summary>Search from the address bar</summary>
260 <p class="note">Add a search engine to your browser with this address, and
261 give it the shortcut sbm:</p>
262 <p><code>{{.URL}}/bookmarks?q=%s</code></p>
263 <p class="note">Then type sbm, a space and your words in the address bar.
264 In Chrome and Edge, add it under Settings, Search engine, Manage search
265 engines and site search. Firefox offers to add sbm from the search button of
266 the address bar while this page is open.</p>
267 </details>
268 <div id="results">
269 <p class="note">{{.Found}} of {{.Total}} bookmarks{{with .Tag}} with the tag <b>{{.}}</b>{{end}}.{{if gt .Found (len .Rows)}}
270 This page shows the first {{len .Rows}}.{{end}}{{if or .Query .Tag}} <a href="/bookmarks">Show all</a>{{end}}</p>
271 {{with .Target}}<p>No bookmark matches. Go to <a href="{{.}}" class="open">{{.}}</a></p>{{end}}
272 <ul class="bookmarks">
273 {{range .Rows}}<li>{{if .Link}}<a href="{{.Link}}" class="open">{{.Title}}</a>{{else}}{{.Title}}{{end}}<br>
274 <small>{{.Host}}{{range .Tags}} · <a href="/bookmarks?tag={{.}}">{{.}}</a>{{end}} ·
275 <a href="/bookmarks/edit?v={{$.Version}}&amp;n={{.N}}">edit</a></small></li>
276 {{end}}</ul>
277 </div>
278 {{with .Tags}}<h2>Tags</h2>
279 <p>{{range .}}<a href="/bookmarks?tag={{.Name}}">{{.Name}}</a>&nbsp;({{.N}}) {{end}}</p>{{end}}
280 <script src="/search.js" defer></script>
281 {{template "foot" .}}{{end}}
282 
283 {{define "follow"}}{{template "head" .}}
284 {{if .SignedIn}}{{template "nav"}}{{end}}
285 <h1>{{if .SignedIn}}Follow these feeds?{{else}}Feeds shared with you{{end}}</h1>
286 {{with .Error}}<p class="error">{{.}}</p>{{end}}
287 {{if or .Feeds .Bad}}<ul class="bookmarks">
288 {{range .Feeds}}<li>{{.Name}}<br><small>{{.URL}}{{if .Known}} · you follow this feed already{{end}}</small></li>
289 {{end}}{{range .Bad}}<li>{{.}}<br><small class="error">not a feed address</small></li>
290 {{end}}</ul>{{else}}<p>This link has no feed in it.</p>{{end}}
291 {{if .SignedIn}}{{if .New}}<form method="post" action="/feed/follow">
292 {{range .Feeds}}{{if not .Known}}<input type="hidden" name="url" value="{{.URL}}"><input type="hidden" name="name" value="{{.Name}}">
293 {{end}}{{end}}<button>Follow {{.New}} {{if eq .New 1}}feed{{else}}feeds{{end}}</button> <a href="/feed">Cancel</a>
294 </form>{{else}}<p><a href="/feed">Your feed</a></p>{{end}}
295 {{else}}<p>sbm Sync follows RSS and Atom feeds for you and shows the new items on one page. It is free.
296 <a href="/login">Sign in</a> or <a href="/signup">create an account</a> to follow these feeds. You come back to this page after that.</p>
297 {{end}}
298 {{template "foot" .}}{{end}}
299 
300 {{define "edit"}}{{template "head" .}}
301 {{template "nav"}}
302 <h1>Edit a bookmark</h1>
303 {{with .Error}}<p class="error">{{.}}</p>{{end}}
304 <form method="post" action="/bookmarks/edit">
305 <input type="hidden" name="v" value="{{.Version}}">
306 <input type="hidden" name="n" value="{{.N}}">
307 <label>URL <input name="url" value="{{.Form.URL}}" required></label>
308 <label>Description <input name="desc" value="{{.Form.Desc}}"></label>
309 <label>Tags, with spaces between them <input name="tags" value="{{.Form.Tags}}" autocomplete="off"></label>
310 <button name="do" value="save">Save</button>
311 <button name="do" value="delete" formnovalidate>Delete</button>
312 <a href="/bookmarks">Cancel</a>
313 </form>
314 {{template "foot" .}}{{end}}
315 
316 {{define "file"}}{{template "head" .}}
317 {{template "nav"}}
318 <h1>Edit the file</h1>
319 {{with .Error}}<p class="error">{{.}}</p>{{end}}
320 <p class="note">One bookmark on each line: the URL, a tab, the description, a
321 tab, and the tags with spaces between them. Lines that start with # are
322 comments. A browser does not type a tab in this box: paste one, or use
323 <a href="/bookmarks">Add a bookmark</a>.</p>
324 <p class="note">When you save, the server merges your changes with the
325 changes of your other devices, as a sync does. Lines that you remove go, new
326 lines come at the end, and the other lines keep their order.</p>
327 <form method="post" action="/bookmarks/file">
328 <input type="hidden" name="base" value="{{.Version}}">
329 <textarea name="text" spellcheck="false" aria-label="The bookmark file">
330 {{.Text}}</textarea>
331 <button>Save</button> <a href="/bookmarks">Cancel</a>
332 </form>
333 {{template "foot" .}}{{end}}
334 
335 {{define "confirmed"}}{{template "head" .}}
336 <h1>{{.Title}}</h1>
337 {{with .Error}}<p class="error">{{.}}</p>{{else}}<p>Sync is on for {{.Email}}.</p>{{end}}
338 <p><a href="/account">Your account</a></p>
339 {{template "foot" .}}{{end}}
340 
341 {{define "done"}}{{template "head" .}}
342 <h1>Back to sbm</h1>
343 <p>You can close this tab. The options page of the sbm add-on shows the new
344 state of your account.</p>
345 <p class="note"><a href="/account">Your account</a> on this website</p>
346 {{template "foot" .}}{{end}}
347 
348 {{define "terms"}}{{template "head" .}}
349 <h1>Terms of sale</h1>
350 <p>The operator of this sbm Sync server sells the paid plans on it,
351 not Google, Mozilla or Stripe.{{with .Contact}} Contact: <a href="mailto:{{.}}">{{.}}</a>.{{end}}
352 Stripe takes the payments. This server never sees your card.</p>
353 <h2>What you can buy</h2>
354 <ul>
355 {{if .Billing}}<li>Sync on this server: {{.Year}} or {{.Month}}, after a free trial of {{.TrialDays}} days.</li>{{end}}
356 {{with .Support}}<li>A supporter subscription. It pays for the server and the work on sbm. It adds no features.</li>{{end}}
357 {{with .Teams}}<li>A pre-order of team bookmarks. You pay now for a plan that comes later.</li>{{end}}
358 {{if not (or .Billing .Support .Teams)}}<li>Nothing: sync on this server is free.</li>{{end}}
359 </ul>
360 <h2>Cancel</h2>
361 <p>You can cancel a subscription at any time.{{if .Billing}} For sync, use
362 Manage billing on your account page or in the add-on.{{end}}{{with .Manage}}
363 For a supporter subscription, use <a href="{{.}}">this page</a>.{{end}}{{with .Contact}}
364 To cancel by email, write to <a href="mailto:{{.}}">{{.}}</a>.{{end}} A subscription
365 that you cancel stays active to the end of the period that you paid for.
366 Then the charges stop.</p>
367 <h2>Refunds</h2>
368 <p>For a full refund, write {{with .Contact}}to <a href="mailto:{{.}}">{{.}}</a>
369 {{end}}within 30 days of a charge.{{if .Teams}} A pre-order gets a full
370 refund at any time before the team plan starts.{{end}}</p>
371 {{template "foot" .}}{{end}}
372 
373 {{define "privacy"}}{{template "head" .}}
374 <h1>Privacy</h1>
375 <p>This policy is for this sbm Sync server, the sbm app for Android and the
376 sbm add-on for Firefox and Chrome.</p>
377 <h2>What the server keeps, and why</h2>
378 <ul>
379 <li>Your email address and a bcrypt hash of your password, never the password itself: to sign you in.
380 When this server checks email addresses, it also sends you an email with a link that confirms your address.</li>
381 <li>Your bookmark file, the last 50 versions that your devices sent: to sync your devices.</li>
382 <li>A hash of the sign-in token of each device: to know your devices.</li>
383 <li>When you subscribe: your Stripe customer ID and the state of your subscription: to bill you.</li>
384 <li>When you follow feeds: the addresses of the feeds, the items that the server fetched from them, and
385 the addresses of the feeds that the server found on your bookmarked pages when you asked it to look:
386 to show you the items, and to send you the new ones by email once a day, unless you turn that off on the feed page.</li>
387 </ul>
388 <p>The server does not sell or share this data, and does not use it for ads.
389 There are no analytics and no trackers. The only cookie keeps you signed in.</p>
390 <p>Data goes to and from the server over HTTPS. On the server it is not
391 encrypted: the operator of the server can read it.</p>
392 <h2>Payments</h2>
393 <p>Stripe takes the payments. This server never sees your card. See the
394 <a href="https://stripe.com/privacy">Stripe privacy policy</a>.</p>
395 <h2 id="delete">Delete your data</h2>
396 <p>Delete your account on the <a href="/account">account page</a>. The
397 server deletes the account and all versions of your bookmark file at once.</p>
398 <h2>The app and the add-on</h2>
399 <p>They keep your bookmarks on your device. They send them only to the sync
400 server that you sign in to, and only after you sign in. Without an account,
401 no data leaves your device.</p>
402 {{with .Contact}}<h2>Contact</h2>
403 <p><a href="mailto:{{.}}">{{.}}</a></p>{{end}}
404 {{template "foot" .}}{{end}}