Repository navigation
0.5.2.0: Citrus core, server groups, balance, CDN, support access and more - #151
Merged
Merged
Conversation
…l levels A grant (ms_ token, 2/6/24 hours, one live at a time) lets an operator in by a one-time browser link or a bearer token. view only reads, change also writes, terminal stores and validates the servers for the coming terminal. Auth, API keys, the grants themselves, the secret path, the audit journal and Telegram backups stay closed. Without show_people names, Telegram, contacts, notes, addresses and subscription links are masked in every JSON answer. The journal gets support.grant/enter/revoke/expire and the operator's actions under actor support:<id>; the admin is told in Telegram when the operator comes and goes.
The panel and the node keep the last 2000 lines of their log in memory with
tokens, keys, passwords, subscription links and secret paths cut out. New
endpoints: GET /api/v1/logs?source=panel|node:<id>&tail=N, POST
/api/v1/system/doctor and /nodes/{id}/doctor, POST /api/v1/system/restart and
/nodes/{id}/restart (session only). The node answers GET /v1/logs, POST
/v1/doctor and POST /v1/restart. The doctor and the restart reach the host
through request files its systemd units watch (internal/hostchan).
…a restart, mikan support mikan doctor --json prints the report with secrets cut out; --requested (the doctor request unit) takes doctor/request and writes doctor/report.json through panelfs. mikan restart --requested does the same for restarts. Both units are written only where they differ and come with mikan update on older installs. mikan support <code> sends the report, mikan status and the last log lines, all redacted, to the support desk; --dry-run shows what would be sent.
Conflicts kept both sides in api.New (support and host operations register). A doctor run is a read-only diagnostic and passes the view level of a support grant; a restart is a write and needs the change level.
…nded by the grant mikan terminal-agent runs one session per request file of a path unit: a pty shell in its own process group, a unix socket for the panel's user alone, an asciicast v2 recording kept 30 days, ended at the grant's end, a revocation marker, the panel letting go or 15 minutes of silence. support/ stays root's through mikan update.
…PI, with recordings
GET /api/v1/support/terminal (WebSocket, same origin, a live grant of the terminal level
that names the target) bridges the operator to the host's agent: the panel's own server
through a unix socket in its data directory, a remote node through POST /v1/terminal on the
panel-only TLS channel. A hub of open sessions closes them when the grant ends; the host's
agents are told through a revocation marker. support.terminal.start/end go to the audit and
the admin's Telegram. GET /api/v1/support/recordings[/{name}] are the admin's only.
coder/websocket (already in go.mod, indirect) is the WebSocket library.
…age, terminal and recordings player Settings > Security gets the Support access card (level, hours, client data, terminal servers with password and TOTP, one-time link with QR and copy, journal, revoke). A strip across every page shows a live grant to the admin and the mode to the operator. /support takes the token from the address fragment once, clears it and enters. The new Diagnostics page has redacted logs with filter and auto refresh, the host check with restart, and the xterm.js terminal (own chunk) for operators with the terminal level. Recordings open in a small asciicast player. Parts closed to operators (credentials, API keys, Telegram backup and broadcast) show a notice. ru and en texts.
…leaks of a masked operator, open the server checks at view level
…ave open; regenerate OpenAPI
…erver's .env Settings support_access (on by default, the admin's session only) and MIKAN_SUPPORT_ACCESS=off in .env (set by mikan support-access on|off): off, no grant can be made, tokens and sessions of the live one open nothing and it ends at once (its terminals too); the server takes no support terminal units. The card shows the switch and why it is off; README and the rules page say there is no standing access.
…desk tells mikan from a fork
…s the checkbox as the panel does
…cs without SSH, the paid support page
…r access as a revoke would
…pages for support access and diagnostics without SSH
…l checks a one-time code from a paid ticket with the support bot and hands the access to it itself, never showing the link; an access the bot did not take is withdrawn
Addons → Community lists third-party addons from the registry a mikan workflow syncs with the authors' releases and signs with the catalog's key; the panel reads only that index. They install as unofficial addons by digest. Every install and every update of an unofficial addon (registry or source) asks the admin to take the risk (ack, refused by the API without it; Update all skips them), an update signed with another author key waits for the admin to accept its fingerprint, and a revoked addon is marked with the reason and installs no more, from the registry or a source of its repository. A source cannot claim an id the registry lists. Migration 0033 (addon_community).
…very unofficial install and update, revocation
…s root The installer is root on a server; a test run by anyone else (CI's runner) failed on the chown of secrets/ and stopped six tests. The owner is checked only under root, as panelfs and the terminal already do.
…EC-2026-0382, RUSTSEC-2026-0381)
…he iPhone Mikan (Android) and Kabosu (Windows, macOS, Linux) are mikan's own apps: first on their platforms, with mikan:// and kabosu:// links no other app takes. INCY joins the iPhone list after Happ. A Kabosu whose User-Agent names no core still gets the Clash profile.
The bot answers a tap at once and draws its screen after; the test waited for the answer only, so the late screen of someone else's tap was now and then taken for the subscriber's own and the link checked before it changed.
…, not its value CodeQL took the assert messages that printed the fake secrets for cleartext logging (alerts 35, 36).
…om the ring CodeQL alerts 32-34. An answer held for masking goes out with its handler's type, or the one net/http would sniff from the same bytes, and nosniff, so a browser never reads it as a page. Tail copies what the ring holds instead of sizing an allocation by the n asked for.
# Conflicts: # CHANGELOG.md # README.es.md # README.fa.md # README.md # README.ru.md # README.tr.md # README.zh-CN.md # site/astro.config.mjs # site/src/content/docs/en/operations/cli.mdx # site/src/content/docs/en/operations/community-addons.mdx # site/src/content/docs/en/operations/diagnostics.mdx # site/src/content/docs/en/operations/support-access.mdx # site/src/content/docs/en/protocols/presets.mdx # site/src/content/docs/en/support/paid.mdx # site/src/content/docs/operations/cli.mdx # site/src/content/docs/operations/community-addons.mdx # site/src/content/docs/operations/diagnostics.mdx # site/src/content/docs/operations/support-access.mdx # site/src/content/docs/protocols/presets.mdx # site/src/content/docs/support/paid.mdx
"In beta 0.5.1.1" becomes "New in 0.5.2.0" ("С версии 0.5.2.0"), "older than 0.5.1.1" becomes "older than 0.5.2.0", and the pointers to the beta channel go: stable panels get all of it with 0.5.2.0.
Miroshka000
marked this pull request as ready for review
October 22, 2026 16:13
…round arrows, not layers
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.190 to 0.2.191. - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.191/CHANGELOG.md) - [Commits](rust-lang/libc@0.2.190...0.2.191) --- updated-dependencies: - dependency-name: libc dependency-version: 0.2.191 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.11.0 to 0.11.1. - [Commits](RustCrypto/hashes@sha2-v0.11.0...sha2-v0.11.1) --- updated-dependencies: - dependency-name: sha2 dependency-version: 0.11.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps the site group with 1 update in the /site directory: [astro](https://github.com/withastro/astro/tree/HEAD/packages/astro). Updates `astro` from 7.3.8 to 7.4.1 - [Changelog](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md) - [Commits](https://github.com/withastro/astro/commits/astro@7.4.1/packages/astro) --- updated-dependencies: - dependency-name: astro dependency-version: 7.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: site ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps the actions group with 1 update in the / directory: [taiki-e/install-action](https://github.com/taiki-e/install-action). Updates `taiki-e/install-action` from 2.87.28 to 2.87.29 - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](taiki-e/install-action@1168f68...8cca091) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-version: 2.87.29 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps the web group with 9 updates in the /web directory: | Package | From | To | | --- | --- | --- | | [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.3.0` | `1.3.1` | | [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.2.0` | `2.2.1` | | [@radix-ui/react-switch](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/switch) | `1.4.0` | `1.4.1` | | [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.104.2` | `5.104.4` | | [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router) | `1.170.42` | `1.170.45` | | [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.55.0` | `1.59.0` | | [motion](https://github.com/motiondivision/motion) | `14.1.0` | `14.4.0` | | [react](https://github.com/react/react/tree/HEAD/packages/react) | `19.3.0` | `19.3.1` | | [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) | `19.3.0` | `19.3.1` | Updates `@radix-ui/react-dialog` from 1.3.0 to 1.3.1 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dialog) Updates `@radix-ui/react-dropdown-menu` from 2.2.0 to 2.2.1 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu) Updates `@radix-ui/react-switch` from 1.4.0 to 1.4.1 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/switch/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/switch) Updates `@tanstack/react-query` from 5.104.2 to 5.104.4 - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.104.4/packages/react-query) Updates `@tanstack/react-router` from 1.170.42 to 1.170.45 - [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.170.45/packages/react-router) Updates `lucide-react` from 1.55.0 to 1.59.0 - [Commits](https://github.com/lucide-icons/lucide/commits/1.59.0/packages/lucide-react) Updates `motion` from 14.1.0 to 14.4.0 - [Changelog](https://github.com/motiondivision/motion/blob/main/CHANGELOG.md) - [Commits](motiondivision/motion@v14.1.0...v14.4.0) Updates `react` from 19.3.0 to 19.3.1 - [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/react/react/commits/v19.3.1/packages/react) Updates `react-dom` from 19.3.0 to 19.3.1 - [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/react/react/commits/v19.3.1/packages/react-dom) --- updated-dependencies: - dependency-name: "@radix-ui/react-dialog" dependency-version: 1.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: "@radix-ui/react-dropdown-menu" dependency-version: 2.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: "@radix-ui/react-switch" dependency-version: 1.4.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: "@tanstack/react-query" dependency-version: 5.104.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: "@tanstack/react-router" dependency-version: 1.170.45 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: lucide-react dependency-version: 1.59.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: web - dependency-name: motion dependency-version: 14.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: web - dependency-name: react dependency-version: 19.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web - dependency-name: react-dom dependency-version: 19.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: web ... Signed-off-by: dependabot[bot] <support@github.com>
… drops the .env of before After a failed migration or start that leaves the new release (no safe rollback), its settings are in config.json and secrets/, but the .env from before stayed, and the next update read the server by it: a move from SQLite whose import had committed was taken for one not made and imported again over the newer data. The .env goes, as after a good update (the update's archive keeps it).
…ept since secrets left .env
The fixture's compose reads ${...} as an older one does; the kept database password is checked in secrets/ and in the .env a rollback writes for the old release; the new release is read from config.json, and a failure that leaves it leaves no .env. The script stopped at its first stale check since the move to secrets, hidden behind the cargo tests that failed before it.
…t goes CodeQL alert 32: the masked API's pass-through write. An answer whose handler wrote without a status gets the type it gave, or what net/http would sniff from the same first bytes, and nosniff, said before the headers go.
…m 2.87.28 to 2.87.29 in the actions group across 1 directory
…in /site in the site group across 1 directory
…ectory with 9 updates
…91 in /installer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 0.5.1.1 betas (rc.1 to rc.15) ship as the stable 0.5.2.0. The full notes are the
## 0.5.2.0section of CHANGELOG.md, which the release and the panel show.Summary
X-Mikan-Groupsfor the Mikan app; Mikan (Android) and Kabosu (desktop) first on the subscription page, INCY on the iPhone.config.json+secrets/), the node's API for the panel's addresses only, diagnostics, logs and restart without SSH, support access with an extended mode and a terminal, the activity log, community addons, the region and geo bases checks, front page for strangers, the panel as an installable app (PWA).mainmerged back intodev: the site and README pages written on main, with the beta notes now saying 0.5.2.0.Before updating
max-time-differencein milliseconds, as Citrus reads it.Migrations
0032 to 0052: support access, community addons, VMess to VLESS, extra devices, campaigns, balancing, node HTTP redirect, balance, sites, node SNI router, node API lockdown, REALITY time in ms, server groups, plan servers, node front page, support extended mode, Telegram clients, dropped tables of inbound settings and bot events, relay traffic.
Not tested live
mikan:///kabosu://links on devices (Kabosu has no release yet)