Bicrypto 6.7.1

Pre-release

This 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.

SEARCHPAGESNAVIGATIONADMINPROFILEPRESENCELANDING-PAGEUI

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 updator

Restart 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.

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 lastLogin into a three-state presence bucket 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 and javascript: URLs are still removed, and the five built-in pages keep the stricter policy they had.
  • Added an @import strip 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=false has actually been set, and to say what to do instead — remove it, or list the proxy's address in TRUST_PROXY_CIDRS if 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.