Conversation
Add POST /api/v1/admin/users/{id}/reset-password (admin only). Mirrors
the invite flow: an admin sets a new temporary password, the server flags
the user must_change_password=1 and revokes the target's existing
sessions, so on next login the existing ChangePasswordPage forces a new
password (same as first login). Any admin may reset any user, including
another admin — a reset neither demotes nor disables anyone, so no
last-admin guard applies.
- users.AdminResetPassword: sibling of UpdatePassword that SETS the flag
instead of clearing it.
- Handler gates on mustBeAdmin, validates new_password (>=8), revokes
sessions via Sessions.DeleteAllForUser, returns the updated user.
- Dashboard: ResetPasswordDialog (cloned from InviteUserDialog) wired into
the users table, plus the useResetUserPassword hook.
- Documented in doc/openapi.yaml (source of truth).
Mounted directly in router.go, matching the existing embedding-provider
admin routes — the committed openapi.gen.go predates the pinned
oapi-codegen, so it is not regenerated here. The follow-up commit
reconciles that drift and moves these routes onto the generated mux.
Purely additive: no DB migration, no changed/removed endpoints or
behavior; the dashboard ships inside the server binary so there is no
version skew. Backward-compatible.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…he generated mux The committed internal/httpapi/openapi/openapi.gen.go had drifted from the pinned oapi-codegen (v2.7.0): it predated the embedding-provider endpoints, which were added to doc/openapi.yaml but mounted directly in router.go as a stopgap. The previous commit added the password-reset endpoint the same way. Regenerate gen.go from the spec so the generated mux owns all of them, and drop the direct mounts (keeping both would double-register the routes and panic chi at startup): - TestEmbeddingProvider and ResetUserPassword now take their path params from the generated wrapper (kind/id) instead of chi.URLParam; chi import dropped from auth.go, swapped for the openapi pkg in admin_embeddings.go. - router.go no longer hand-mounts the embedding-provider or reset-password routes — HandlerFromMux registers them from the spec. - The embedded /openapi.json blob now lists these endpoints (previously it under-reported the API in Swagger UI / docs). Incidental churn: regeneration also reorders some struct fields and adds .Valid() enum helpers that the stale file lacked. `make openapi-check` is green again. No wire/behavior change — same routes, methods, and shapes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-depth) The ≥8 length check previously lived only in the HTTP handler. Move the policy behind a shared users.MinPasswordLength constant and also enforce it in the AdminResetPassword service method, so a non-HTTP caller can't set a too-short password. The handler now references the constant instead of a literal. Adds service-level tests for the set-flag and reject-short paths. Pre-existing Create/UpdatePassword keep their empty-only checks (untouched to avoid affecting bootstrap and other flows); hardening those uniformly is a separate concern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(server): admin-initiated password reset
The login limiter (loginlimiter.go) blocks brute-force attempts per IP and per (IP, email), but the only way to lift a lock early was a server restart (which wipes all in-memory state). A legitimate user who fat-fingered their password from a shared office IP was stuck for the full 15-minute window with no admin recourse. Add observability + targeted clear to the limiter and an admin surface: - loginLimiter.locks() snapshots every counter currently at/over its limit (prune-on-read so the maps don't grow); clearIP/clearKey lift one lock. - GET /api/v1/admin/login-locks lists active locks; POST .../reset clears the exact row the admin picked (type=ip | ip_email). Both Admin-only, idempotent reset returns 204. - Dashboard "Login security" admin module: table of active locks with a per-row Reset button, 15s polling, empty state. Spec-first: doc/openapi.yaml + regenerated openapi.gen.go. Gating tests cover non-admin 403, the full lock→list→reset→unthrottled cycle, and validation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses review feedback on the login-lock admin feature: - ResetLoginLock now emits an explicit structured audit line (actor id/email, lock type/ip/email) on every clear. Lifting a lock weakens the brute-force defence, so it deserves its own audit record, not just the generic request log. Nil-guarded; actor fields blank under AuthDisabled. - clearKey delegates to reset instead of duplicating the delete, so the key derivation lives in one place and the two paths can't drift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(server): admin UI to view and reset login rate-limit locks
Solidity (`.sol`) files were detected as unknown language and indexed as plain text via sliding window — no symbols, no contract/function navigation, no `cix def` / `cix refs`. Repos cloned by the server-side `repoindexer` skipped `.sol` files entirely because their language resolved to "". Fix on three sides: - `server/internal/langdetect`: map `.sol` → "solidity" - `server/internal/chunker`: register `grammars.SolidityLanguage` with node kinds for contract / library (class), interface / struct / enum / event (type), and function / modifier / constructor / fallback-receive (function). Tree-sitter grammar was already shipped by gotreesitter. - `cli/internal/discovery`: mirror `.sol` → "solidity" in the CLI's own extension map so locally-discovered files reach the server with the right language tag instead of "". Tests: - new `TestChunkFile_Solidity` verifies contract / function symbols are extracted with correct kind and parent linkage - `TestRegistry_NodeNamesMatchAST` fixture extended with a Solidity snippet so node names stay in sync with the grammar - langdetect test gets a `Token.sol → solidity` case Verified on a sample contract: 10 symbols extracted (contract, library, interface, struct, enum, event, function, modifier, method) where before everything came out as a single `block` chunk with no symbol name. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR review feedback: 1. doc/LANGUAGES.md was missed in the original PR. Bump default set header from (30) -> (31) and add the `solidity` row to the table. 2. TestRegistry_NodeNamesMatchAST's `matched := false` logic passes if any *one* of a language's configured kinds appears in the AST -- so a future grammar rename of `modifier_definition` (or any of the other 8 Solidity kinds beyond contract/function) would slip through. Reviewer flagged this as a low-priority shared limitation; rather than reshape the generic test for every language, add a focused `TestRegistry_SolidityAllNodeKindsPresent` that parses a contract exercising all 10 advertised node kinds and fails if any is missing. Also widen the Solidity fixture in the generic test for parity. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(chunker): add Solidity language support
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.
What
Release PR — promote
developtomain. Bundles three merged featurebranches since the last release:
feat(server): admin-initiated password reset (with min-lengthenforcement, OpenAPI regen, generated-mux routing)
feat(server): admin UI + API to view and reset loginrate-limit locks (audit-logged,
clearKeydelegates to reset)fix(chunker): full Solidity (.sol) language support —langdetect + chunker registry + CLI discovery, 10 node kinds
Why
Cuts the next server release. Each change landed via its own reviewed PR
into
develop; this PR is the integration gate tomainbefore tagging.How
generated OpenAPI mux and enforce
Admin-level auth per thedocs/AUTH_REVIEW.mdmatrix (gating tests inauth_test.go,loginlocks_admin_test.go).against the real gotreesitter grammar, with a strict all-kinds
regression test.
openapi.gen.goregenerated (no hand-edits);doc/openapi.yamlis thesource of truth.
Type of change
Checklist
go test ./...green on server (chunker, langdetect, httpapi auth/locks, users)go build ./...green on server + CLImake openapi-gen(no manual edits to gen.go)Release follow-up (after merge)
cd server && make scout-cuda→ verify 0 HIGH/CRITICALserver/cmd/cix-server/version.goserver/vX.Y.Z→ GitHub Actions builds & pushes images🤖 Generated with Claude Code