Bicrypto 6.7.1
Pre-releaseThis version isn’t published on updates.mashdiv.com yet — the notes are available to preview, but it can’t be downloaded until it’s released.
23 August 2026
This release has upgrade notes. Read them before updating — they describe behaviour changes that need your attention.
Core v6.7.1
Release Date: August 23, 2026 Tags: SEARCH, PAGES, NAVIGATION, ADMIN, PROFILE, PRESENCE, LANDING-PAGE, UI
Overview
Five things a visitor or an operator could not do before, and most were already half-built. The platform shipped twenty-six illustrated avatars that nothing pointed at, a menu model that stored an icon per item with no control to set one, and a home page whose mobile band vanished without a store link. This release wires those up and adds two new things.
The first is a search box in the header answering "what can I do with this
token?". Type BTC and it reports the spot and futures markets, native-token
pairs, binary, forex, staking pools, token sales, P2P offers, copy traders, bot
strategies, investment plans, DEX tokens and the wallet — one request, gated on
the features you run. The second is Add a page: write it, give it a URL,
publish it, and have it linked from the header or footer without touching the
menu editor.
A presence dot also says whether a person is here, around or long gone, on blog bylines and every P2P trader avatar. Nothing changes trading, money movement or permissions, and there is no migration. Read Upgrade Notes — one nginx limit goes up, and pages you had already added become reachable.
Update Instructions
pnpm updatorRestart the backend and ship the frontend build. The search endpoint is new on the backend; everything else is client-side.
Upgrade Notes
nginx has to allow a larger request body than it did
client_max_body_size 10m was right while every route shared the 5 MB platform
floor. Routes that carry a file as base64 inside JSON now declare their own
ceiling — P2P dispute evidence allows 36 MB so a screen recording fits — and
whichever of nginx and the backend is smaller is the one that decides. nginx
refuses with an HTML page the frontend cannot parse, so a customer sees an
upload that spins and then fails with no message at all.
client_max_body_size 40m;Then nginx -t && systemctl reload nginx. Set it at server level, or scope it
to location /api/ if you would rather keep the rest of the site tight. The
per-route table is in the nginx guide.
Presence adds a presence:<userId> key per active user in Redis, written at
most once a minute and expiring after four days. It is a cache — flush it and
presence falls back to sign-in time until people browse again.
CMS pages that used to 404 will start serving
Pages held in the CMS table were reachable only where the landing-page type had been switched to the page builder. On a stock install that setting is unset, so every such page answered 404 — including one an owner had just created, which is how the defect was found.
The gate belonged to builder documents and has been moved onto them, so builder pages behave exactly as before. A CMS page whose body is plain HTML is not a builder page and now serves on any install.
- Look at your CMS pages before you update. If your install carries rows nobody has seen in a while because they were unreachable, publishing state is now the only thing standing between them and the public site. Unpublish anything that should not be live.
Added
One search box over every feature a token is offered in
A visitor who has heard of a token had no way to ask the platform about it. The markets page lists spot pairs, staking lists pools, P2P lists offers — each answers for itself, and none of them answers "where else is this?". Someone who wanted to know whether you offer staking on a coin they hold had to visit every section and check.
The header now carries a search button. It opens a panel with the field inside, and typing a symbol returns one grouped answer: Spot, Futures, Native tokens, Binary, Forex & Multi-Asset, Staking, Token sales, P2P, Copy trading, Trading bots, Earn and Swap, each with the matching rows and a link through to the feature, followed by deposit and withdraw for the token itself. Market rows carry a live price and 24-hour change.
BTC, btc/usdt, BTC-USDT and BTCUSDT are all the same question, and a
half-typed symbol still answers, so the panel is useful before you finish typing.
Opened with an empty field it shows quick links to the features you run, the markets you have flagged Trending or Hot in the market editors, and the visitor's own recent searches.
- Added
GET /api/search, a public endpoint that resolves a token and reports every enabled feature offering it. A feature contributes results only when its extension is installed and enabled — the same gate the menu uses — so a group that is missing is missing because you do not run that feature. - Added the header search control to the Classic and Stacked navbar layouts. Centered and Minimal declare no room for it and do not show it; the layout picker says so on the card before you choose.
- Added keyboard operation throughout — arrows walk one list across every group, Enter opens, Escape closes.
Add a page to your site
The Pages screen offered five pages — home, about, privacy, terms and contact — and no way to make a sixth. An owner who wanted a Cookie Policy, a fee schedule or an "About our licence" page had the page builder, which is a different tool for a different job, or nothing.
Default Pages → Add page now creates one. Give it a title, and the URL fills itself in and is checked against everything already on the site while you type, so a collision is a red line under the field rather than a save that fails. Two checkboxes put a link in the site menu and in the footer at the same time.
The page then opens in the same editor as the built-in five: a live preview, an HTML tab, an SEO panel and a publish switch. Your own pages sit in their own group in the sidebar, apart from the built-ins. Deleting one removes the row and tidies away the menu and footer links it added.
Links are written as ordinary custom menu items into the same documents the Menus and Footer editors use, so anything created this way can be moved, renamed, given an icon or removed there afterwards — it is not a second, invisible source of links.
- Added the Add page dialog, with live URL availability checking and the option to link the page into the header menu, the footer, or both.
- Added owner-added pages to the Pages studio and its editor, including the URL field, the publish switch, SEO fields and delete.
- Added rendering for them on the public site, styled by the same rules the editor previews them with, so what you compose is what visitors get.
A gallery of avatars, and two ways to set one
Twenty-six illustrated portraits have shipped in the platform since the first release and nothing referenced them. The only profile picture a customer could have was a photo they went and found, and clicking the avatar opened the file dialog immediately — one option presented as though it were the only one.
Clicking the avatar now offers Choose avatar and Upload photo. The gallery marks the one in use, saves on the click, and updates the header and sidebar at once. Upload is unchanged: PNG, JPG or WebP, resized to 400px.
- Added the avatar gallery, reachable from the profile hero and from the Personal information card.
- Added the same picker to both of those places from one component, so the upload rules cannot drift between them.
An icon picker for menu items
The menu model has always been able to store an icon per item, the navbar has always drawn one, and the documentation has always said you could set it — but no control ever wrote the value. It was reachable only by editing the stored document by hand.
Press the pencil on any row in Menus and the control to the left of the label box is the icon picker, sitting where the glyph sits in the rendered menu. It opens a searchable grid of roughly 350 icons; the search matches whole words, so credit card finds the card. The first tile is No icon, which removes one. The same picker sits beside the label on the Add item form, so an item you create can arrive with its icon.
Every row in the editor now draws its own glyph, so you can see the menu you are building.
- Added the icon picker to the menu and footer-link editors, for shipped items and for items you add.
- Added the icon column to the editor's rows.
"Coming Soon" for the mobile app band
The home page's Mobile app band renders nothing unless an App Store or Google Play link is set in system settings — which is exactly the state of an operator whose app is not built yet. The band an owner most wants while an app is in review was the one they could not show.
Default Pages → Home → Mobile app gains a Show Coming Soon switch. It replaces the two store buttons with a single plate carrying both store marks, reads Coming Soon unless you write something else in the field below it, and drops the "Scan QR to Download" line because there is nothing to scan yet.
It also wins over links that are set, which is the point of it being a switch rather than a consequence of the links being empty: you can hold the buttons back during a store review without deleting the URLs and having to find them again.
- Added the Show Coming Soon switch and its Coming Soon text field.
- Added the ability for that band to render with no store link configured.
A dot that says whether somebody is there
Every surface that showed a person showed them identically whether they had been online for an hour or absent since March. Three separate components drew a presence dot of their own and no two agreed on the rule; the P2P one drew a green dot when a trader was online and nothing at all otherwise, so idle and abandoned looked the same.
There is now one component with one rule: green within five minutes, grey between sessions, red after three days, and nothing when there is no reading at all — an honest gap beats a plausible wrong colour. Every dot carries its wording as an accessible name, so it means something to a reader who cannot see it.
- Added the dot to blog post bylines, the author box, the comment list and the author profile page.
- Added a request heartbeat, which is what makes any of it true. Presence used to come from the last sign-in, and a session lives a fortnight — so somebody reading a page right now was reported as last seen the day they typed their password. It is stamped on ordinary browsing, at most once a minute per person, and never on API-key traffic: a cron job says nothing about whether its owner is at a screen.
Changed
The blog publishes whether an author is around, never when they signed in
A trader advertising on a public board has chosen to say when they were last seen. An author did not put themselves on a blog so anonymous readers could learn what time they sat down at their desk, and a commenter certainly did not.
- Changed the public-payload redaction pass to convert
lastLogininto a three-statepresencebucket and delete the timestamp. It runs on every public blog endpoint already, so a query that adds the column gets the dot and cannot leak the instant.
The avatar and menu editors write only what you changed
- Changed the menu editor to store a renamed label only when the text actually differs from what ships. Setting an icon and saving used to store the shipped title as a rename, which badged the item Renamed and — more quietly — pinned that wording: an admin label opts out of translation by design, so the item would have kept the old text through a release that renamed it and in every language a visitor selected.
What survives sanitising on a page you wrote yourself
The five built-in pages are produced by a template wizard that styles everything
with classes and never emits an inline style, so the sanitiser that cleans them
strips one. A page typed into the rich-text editor, or pasted in from a document,
carries inline styling on nearly every element — and removing it there deletes
the owner's own formatting and tells them nothing.
- Changed the sanitiser for owner-added pages to keep inline
style. Scripts, iframes, embeds and objects are still refused, event handlers andjavascript:URLs are still removed, and the five built-in pages keep the stricter policy they had. - Added an
@importstrip to page CSS and to<style>blocks. A stylesheet import is an outbound request made on behalf of every visitor, and it is the one way styling could arrive on a published page without passing through any of the above.
Fixed
"Log In" and "Sign Up" could wrap onto two lines
Adding a control to the header squeezed the signed-out call-to-action buttons until their labels broke across two lines, which grew the whole bar. The two buttons a signed-out visitor is there for now hold their size and the flexible controls beside them give up the width instead.
- Fixed the auth buttons reflowing when the header runs short of room.
A refused search left the previous results on screen
Every query parameter on every route is screened for injection patterns before a handler runs, and one of those patterns matches ordinary English — a search containing both a word like delete and a word like from is refused. The search panel now clears its results and says the search could not be run, rather than leaving the previous query's rows under the new text where they read as a confident wrong answer.
- Fixed the search panel keeping stale results when a query is rejected.
Opening an added page in the Page Builder replaced it with a blank one
Both kinds of page live in the same table, so the builder's URL would open one it cannot read. It parsed the HTML body as a builder document, got nothing, and showed an empty canvas — and one Save, or one Ctrl-S, wrote that empty document over the owner's page. There is no undo for it.
- Fixed the builder refusing to open a page that holds HTML. It says so and sends you to the editor that can edit it.
- Fixed the save path as well as the load path, because the keyboard shortcut can fire before the redirect lands.
More than about six rules of page CSS was rejected
The Custom CSS and Custom JS fields are stored in columns that hold documents, and the request validator capped them at 255 characters — a default inherited from fields meant for names and titles, stated nowhere the owner could see it. Writing a real stylesheet produced a validation error naming a field they had every right to fill.
- Fixed the caps on page CSS, page JS and page settings, now 64 KB each.
- Fixed the same inherited cap on SEO keywords and the Open Graph description, now 1,000 and 500 characters.
CSS written at the top of a page vanished on save
A <style> block at the very start of a document is moved into the document's
head by the HTML parser, which put it outside the part the sanitiser returns — so
an owner who opened the HTML tab and put their CSS first, which is where anyone
would put it, watched it disappear with no error anywhere.
- Fixed the leading
<style>block being dropped. Position no longer decides whether the styling exists. - Fixed a page whose whole body was removed by sanitising answering 200 with a blank column between the header and the footer. It is a 404, which is what it is.
The page list ignored the page-size picker
/admin/builder asked for its rows with the wrong parameter name, so the list
served the default page size whatever the picker was set to.
- Fixed the page-size picker on the page list.
Save stayed greyed out after retyping an added page's URL
The editor decides whether there is anything to save by comparing the draft against what was loaded, and the URL was not in that comparison. Changing it left Save disabled with nothing explaining why, and leaving the screen discarded the edit without even the usual prompt.
- Fixed the URL counting as a change.
- Fixed a duplicate URL surfacing as a generic server error with no mention of the URL, on a collision the screen was already showing in red.
Geo-restriction told correctly configured servers to change their proxy setting
Forwarding headers are honoured from a proxy on the same machine with no
configuration at all, but the settings screen read the absent environment
variable as "switched off" and advised every such install to set
TRUST_PROXY=true — which is the one mode that believes a forwarding header from
a public peer. A second banner warned that visitor countries were wrong on every
healthy same-host nginx or Apache install.
- Fixed the first warning to appear only where
TRUST_PROXY=falsehas actually been set, and to say what to do instead — remove it, or list the proxy's address inTRUST_PROXY_CIDRSif it sits on another host. - Fixed the second warning firing on a loopback peer, which is the normal shape of a proxied request. It now appears only when forwarding headers arrive and the address the engine ends up with is still a private one, which is the condition that genuinely means your visitors are being geolocated as your proxy.