Commit Graph
176 Commits
Author SHA1 Message Date
Lemon-miaow 4d4cdd6ea7 fix(api,panel): refuse file operations on a server without a world volume (#58)
Live: the files page against a server whose world claim does not exist (never
started, or reaped) created a Job whose Pod stayed Pending on
FailedScheduling (persistentvolumeclaim not found) until the executor's 90s
wait expired — a 90s spinner answered by a misleading 504 files_timeout, for
a request that is knowably impossible. Backup and restore have refused this
shape with 409 no_world_volume since the #42 round; the file routes now run
the same gate before any Job is created, and the panel maps the code to a
localized message (it previously fell back to the English server text).
2026-09-23 22:17:08 +08:00
Lemon-miaow 70c988e702 fix(panel): render the console command's reply (#57)
sendCommand returns the RCON reply and the component's own contract says it
"displays its plain-text reply", but the reply was discarded and the pod log
does not echo command output, so a sent command produced no visible result at
all (verified live with 'list'). The last command echo + reply now render
above the prompt, terminal-style.
2026-09-23 22:08:19 +08:00
Lemon-miaow 0790f8dfd3 fix(panel): surface the RCON reply for player-access mutations (#56)
The whitelist/ban/kick mutations reported a canned success message and threw
away the server's reply, so a refused command still read as done: live, the
vanilla server answers "That player does not exist" for a name it has never
seen (any player who has not joined yet), while the panel said the player had
been whitelisted/banned. api.ts documents these replies as "surfaced verbatim
as confirmation"; now they are. The localized string stays as the fallback
for a silent server.
2026-09-23 22:08:19 +08:00
Lemon-miaow 168a37542b feat(api,panel): reviewer context download for submissions; dockerfile field documented as audit-only (audit #45) 2026-09-23 16:41:55 +08:00
Lemon-miaow 2f90851c03 fix(panel): mark platform system services read-only in the fleet table
login/lobby carry reserved names, so every per-server route rejects them —
yet the cockpit offered claim/stop/wake and a console link on their rows,
each answering 400 bad_name. The fleet view now marks them (system:true,
shared naming.IsSystemServer) and the panel renders a plain label instead
of dead actions.
2026-09-23 06:51:45 +08:00
Lemon-miaow 0a36b3fda9 feat(panel): add the server files page for the world-volume repair lever
The backend could list/read/write a stopped server's world volume since the
file-editor slice, but the panel had no entry, so the one repair path for a
server that will not boot (a wrong line in server.properties) was API-only.
New /servers/:name/files page: breadcrumb browser, editor dialog with the
base64 []byte codec, binary files open read-only, the stopped gate is owned
up front (with a stop action) instead of letting every call 409, and a
doorway card on the console. i18n files namespace + wire-shape tests.
2026-09-23 06:42:45 +08:00
Lemon-miaow 72c4aa3895 fix(submissions): surface each linked build's outcome to the submitter
/me/submissions (and the admin queue) now attach build_status/build_error by
a read-only Builder.Get — until now a failed build was visible only on the
admin-tier /images/build routes, so the person who submitted the modpack
never learned the build died. A missing build row renders as "no outcome";
any other lookup failure surfaces instead of being swallowed. The panel's
My Submissions page renders the outcome in the expanded row, localised.
2026-09-23 06:31:13 +08:00
Lemon-miaow 11ac4f50e6 feat(panel): expose owner passkey unbind in the user danger zone
DELETE /users/{id}/passkeys shipped as the owner-tier remediation for a
lost or compromised authenticator, but nothing in the panel reached it.
Add the danger-zone action with a confirm dialog; the account keeps its
other doors (email OTP, in-game op-login re-enrollment), so this severs
a credential without locking anyone out. Wire-shape test pins the call.
2026-09-23 06:24:45 +08:00
Lemon-miaow 97a64c8a33 feat(panel): add back up now and recent operations to the backups page
The backups page could list and restore archives but not create one,
and nothing surfaced backup/restore Job outcomes — a failed 202 was
visible only through kubectl. Add a Back up now action (enabled only on
a stopped server, the backend's own gate; a raced 409 is surfaced in
its words) and a Recent operations card fed by GET /servers/{name}/jobs
that shows running/succeeded/failed with the Job's failure message,
re-reads on an interval while a Job is running, and persists across
reloads. Wire-shape tests pin both endpoints.
2026-09-23 06:20:16 +08:00
Lemon-miaow 6907961ce0 fix(panel): the build page trusts the server-side owner tier and drops its mock build seeds 2026-09-23 05:11:49 +08:00
flyemoji 7860152f57 feat(auth)!: go fully passwordless and fix cross-check review findings
Remove password authentication everywhere; the only session doors are
passkey (WebAuthn), email OTP, in-game bind codes, QR scan-login, and
op-login vouching. Remediates the 33-finding cross-check review across
backend, CLI, panel, plugins, and docs.

Backend/CLI:
- Drop password routes and fields from account/user/onboard/auth
  handlers; align tests (new account subtests, naming reserves
  "console", op-login/onboard/qr-login test updates).
- Add migrations 0016_op_login.sql and 0017_drop_password.sql.
- Thread panel/admin hostnames from hostcfg through api.go,
  setup_panel.go, tui_root.go and tui_preflight.go instead of
  hardcoding; bootstrap.sh writes panel-hostname/admin-hostname
  into felis.toml.
- Reword breakglass and TUI copy for passwordless flows.

Panel:
- Delete the ChangePassword page and all password UI; align
  login/auth/api/types with the passwordless contract; add the
  migration and op-login approval flows.
- i18n: convert ImageBuildPage durations/status badges and
  ServerLuckPerms strings to translation keys; drop 72 orphan keys
  per locale; unify the title as "Felis - Console".

Plugins (all six rebuilt):
- Velocity waiting router returns 503 at_capacity during wake;
  MOTD/control-channel copy and config comments.
- Paper zh menu title; Limbo bind-code TTL 600s with panel_url
  preference; unified /link lines in fabric/forge/neoforge; shared
  link-client javadoc contract fixes.

Docs: openapi.yaml, sequence-diagrams.md, deploy/limbo/README.md and
plugins/README.md aligned with the implementation.

BREAKING CHANGE: migration 0017 irreversibly drops
users.password_hash and users.must_change_password; password login
cannot be restored after migrating.
2026-07-20 04:47:32 +09:00
flyemoji 87279a1366 fix(setup): record email unverified so onboarding works without SMTP
At bootstrap there is no SMTP, so the old /setup flow was unreachable: it
requested an emailed OTP that could never arrive. Setup now records the
Owner's email address unverified (no OTP round-trip) and requires a passkey,
deferring SMTP configuration to a later Settings page. Setup completes on
email-recorded + passkey-enrolled, and the lockdown lifts on the passkey, not
on email_verified: a passkey is the Owner's only pre-SMTP login credential
(email-OTP login refuses admin accounts).

The record-email endpoint (POST /account/email) now clears email_verified in
the same write. Only VerifyEmailOTP, which proves control of the address, may
set that flag; recording a fresh unproven address must never leave a stale
email_verified=true asserting a proof the user never gave. The change strictly
tightens the invariant, so no existing reader breaks.

Remove the dead ErrEmailTaken path and its documented 409: no migration puts a
unique index on users.email and the codebase does not enforce email
uniqueness, so the unique-violation branch was unreachable and the 409 an
impossible response.

The /setup route (Setup.tsx, setEmail helper, setup i18n copy) is rewritten to
match: record-email, mandatory passkey, no skip-for-now. The SMTP settings
page and post-setup configure-SMTP nudge are deferred.
2026-07-17 01:41:07 +09:00
flyemoji 5fbb1db4ec feat(setup): add the op.console owner onboarding wizard
The /setup route redeems the one-time token from `felis setup`, then walks
the Owner through email-OTP verification and passkey enrollment before
handing off to the console. It sits outside RequireAuth — the visitor
arrives without a session and the redeem is what mints one — and is
reload-safe: a spent token resumes from the surviving session via
/auth/setup/status.

Adds the Setup page and its /setup route, the setup API client methods
(redeem/status), and the en-US/zh-CN onboarding strings.
2026-07-16 18:03:58 +09:00
Lemon-miaow abad137a01 style(panel): unify vertical spacing below PageHeader across pages 2026-07-06 02:04:54 +08:00
Lemon-miaow bbcfaeb6c4 refactor(panel): remove redundant voxel network topology description subtitle 2026-07-05 16:51:12 +08:00
Lemon-miaow cfe68aedfc fix(panel): align status distribution order to put Stopped at the end 2026-07-05 16:50:16 +08:00
Lemon-miaow 9079a2cd67 feat(panel): implement email otp and passkey login interface 2026-07-05 16:48:03 +08:00
Lemon-miaow bd49313e7e refactor(panel): 抽取 10 个公共组件,消除 ~150 处重复代码
新增组件:
- PageHeader: 统一页面头部(14 个页面)
- StatCard: 统一数值统计卡片(6 个页面)
- MessageLine: 统一错误/成功提示条(16 处)
- ConfirmFooter: 统一 Dialog 底部按钮(8 个文件)
- SearchInput: 统一搜索框(5 个页面)
- SubmissionStatusBadge: 统一提交状态徽章
- RoleBadge / UserStatusBadge: 统一用户角色/状态徽章
- BackLink: 统一返回导航链接(5 个页面)
- InlineConfirm: 统一二次确认交互(3 个 section)

修复:
- Pagination 图标尺寸统一 h-4 w-4
- 右上角按钮统一 size=sm gap-1.5
- StatCard 默认值恢复 text-2xl(24px)

States.tsx 新增 NotYours / NotRunning 通用状态组件

已有文件 -659 行,新组件 +353 行,净减 306 行
2026-07-05 01:15:03 +08:00
Lemon-miaow 627883e89a fix(panel): refine reset password messages and fix empty email placeholder in mock api response 2026-07-04 09:40:14 +08:00
Lemon-miaow 2c95da8d63 fix(panel/i18n): add missing users_col_user key to translation files 2026-07-04 09:36:03 +08:00
Lemon-miaow 67b4e1904e fix(panel): override generic already_exists error message during user creation and profile editing 2026-07-04 09:33:41 +08:00
Lemon-miaow 3347cc05d5 feat(panel): implement user management administration panel with sessions and minecraft link support 2026-07-04 04:08:14 +08:00
Lemon-miaow 83e57b4c45 fix(panel): implement two-step confirmation for claiming a server to prevent accidental operations 2026-07-04 00:52:38 +08:00
Lemon-miaow 439f19e209 fix(panel): prevent page collapse and scroll shifts in players and bans management sections during reload 2026-07-04 00:32:38 +08:00
Lemon-miaow e60784b5b2 fix(panel): eliminate page collapse and scroll shifts during LuckPerms query reload 2026-07-04 00:29:19 +08:00
Lemon-miaow b7d8000eaf feat(panel): implement dedicated LuckPerms permissions and groups management sub-page 2026-07-04 00:27:09 +08:00
Lemon-miaow 5f402b190c fix(panel): force dark mode and pure black bg on server console card 2026-07-03 21:56:36 +08:00
Lemon-miaow f749c2c606 style(panel): resolve double borders and uneven padding in server console 2026-07-03 21:55:25 +08:00
Lemon-miaow a8701c1853 fix(panel): prevent automatic wake during server claim in mock api 2026-07-03 21:53:43 +08:00
Lemon-miaow dd7dff69f0 feat(panel): support importing parameters from submission with owner-restricted unapproved entries 2026-07-03 03:13:16 +08:00
Lemon-miaow 804459c08d feat(panel): implement admin maintenance window settings page 2026-07-03 02:46:50 +08:00
Lemon-miaow 55592ed123 feat(auth): support public auth bind endpoint 2026-07-03 02:11:57 +08:00
Lemon-miaow 5427bc7623 feat(servers): support claiming servers directly from ServersPage list 2026-07-03 02:01:06 +08:00
Lemon-miaow 73d6ec10d0 feat(mock): add mock submissions for owner account 2026-07-03 01:51:33 +08:00
Lemon-miaow adf0d9953c feat(panel): implement user-side modpack submissions with drag & drop context upload 2026-07-02 23:38:46 +08:00
Lemon-miaow 191640c3f5 feat(panel): implement admin submission approval and reject queue 2026-07-02 23:38:46 +08:00
Lemon-miaow 8594622e23 feat(panel): implement email OTP verification and passkey registration management 2026-07-02 18:20:40 +08:00
Lemon-miaow e0bc288444 feat(panel): implement image build pipeline and admin whitelist with mock dev api 2026-07-02 18:01:05 +08:00
Lemon-miaow 19f500b54a style(panel): update destructive red color and rename wake to start 2026-07-02 13:43:35 +08:00
Lemon-miaow c0d333bb98 feat(panel): support full server config edit dialog with status prefilling 2026-07-02 04:24:48 +08:00
Lemon-miaow 3b4298d777 refactor(panel): unify servers cockpit layout, resolve duplicate pages and adjust spacing 2026-07-02 03:30:51 +08:00
Lemon-miaow 6e43a466e0 fix(panel): pin sidebar navigation and enable independent content scroll 2026-07-02 03:30:51 +08:00
Lemon-miaow 92770eade8 style(panel): adjust pagination padding to pt-3 for balanced spacing 2026-07-02 03:30:51 +08:00
Lemon-miaow 5a8eff1935 feat(panel): remove developer comment footer cards from my servers and server admin pages 2026-07-02 03:30:50 +08:00
Lemon-miaow 70d17a0d57 feat(panel): align my servers page search layout with fleet table 2026-07-02 03:30:50 +08:00
Lemon-miaow fa7bab5ec1 style(panel): refine search and filter layout to align with header 2026-07-02 03:30:50 +08:00
Lemon-miaow a9dbc8bc61 feat(panel): add search and status filtering to my servers page 2026-07-02 03:30:50 +08:00
Lemon-miaow 4ecaf3c6cb refactor(panel): set defaultOpen parameter of whitelist card to false 2026-07-02 03:30:50 +08:00
Lemon-miaow 149f01a332 fix(panel): change console button to outline variant on my servers page 2026-07-02 03:30:50 +08:00
Lemon-miaow a15ff55342 refactor(panel): optimize player list layout and horizontal operations 2026-07-02 03:30:50 +08:00