From f47544f70aef7d3e8b17237f8f11a7b5d8dc59b8 Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 14:58:40 +0100 Subject: [PATCH 1/7] feat(server): admin-initiated password reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- doc/openapi.yaml | 49 ++++++++ server/dashboard/src/api/types.ts | 1 + .../users/components/ResetPasswordDialog.tsx | 117 ++++++++++++++++++ .../modules/users/components/UsersTable.tsx | 2 + server/dashboard/src/modules/users/hooks.ts | 10 ++ server/internal/httpapi/auth.go | 48 +++++++ server/internal/httpapi/auth_test.go | 117 ++++++++++++++++++ server/internal/httpapi/router.go | 7 ++ server/internal/users/users.go | 27 ++++ 9 files changed, 378 insertions(+) create mode 100644 server/dashboard/src/modules/users/components/ResetPasswordDialog.tsx diff --git a/doc/openapi.yaml b/doc/openapi.yaml index 1f87ebc..06fcf3f 100644 --- a/doc/openapi.yaml +++ b/doc/openapi.yaml @@ -396,6 +396,44 @@ paths: "404": $ref: "#/components/responses/NotFound" + /api/v1/admin/users/{id}/reset-password: + parameters: + - name: id + in: path + required: true + schema: + type: string + post: + operationId: resetUserPassword + tags: [admin] + summary: Reset a user's password (admin only) + description: | + Sets a new admin-chosen temporary password and forces the user to + change it on next login (must_change_password=true), mirroring the + invite flow. Any admin may reset any user, including another admin. + The target user's existing sessions are revoked. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ResetUserPasswordRequest" + responses: + "200": + description: Password reset + content: + application/json: + schema: + $ref: "#/components/schemas/User" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "422": + $ref: "#/components/responses/Unprocessable" + /api/v1/admin/runtime-config: get: operationId: getRuntimeConfig @@ -3063,6 +3101,17 @@ components: type: string enum: [admin, user] + ResetUserPasswordRequest: + type: object + required: [new_password] + properties: + new_password: + type: string + minLength: 8 + description: | + One-time password the user must change on next login. + The admin shares this out-of-band. + UpdateUserRequest: type: object properties: diff --git a/server/dashboard/src/api/types.ts b/server/dashboard/src/api/types.ts index a1d8707..1712bdf 100644 --- a/server/dashboard/src/api/types.ts +++ b/server/dashboard/src/api/types.ts @@ -19,6 +19,7 @@ export type CreateGroupRequest = components['schemas']['CreateGroupRequest']; export type UpdateGroupRequest = components['schemas']['UpdateGroupRequest']; export type GroupIdListResponse = components['schemas']['GroupIdListResponse']; export type UserWithStats = components['schemas']['UserWithStats']; +export type ResetUserPasswordRequest = components['schemas']['ResetUserPasswordRequest']; export type Session = components['schemas']['Session']; export type ApiKey = components['schemas']['ApiKey']; export type ApiKeyCreated = components['schemas']['ApiKeyCreated']; diff --git a/server/dashboard/src/modules/users/components/ResetPasswordDialog.tsx b/server/dashboard/src/modules/users/components/ResetPasswordDialog.tsx new file mode 100644 index 0000000..425aace --- /dev/null +++ b/server/dashboard/src/modules/users/components/ResetPasswordDialog.tsx @@ -0,0 +1,117 @@ +import { useState } from 'react'; +import { KeyRound, Loader2 } from 'lucide-react'; +import { toast } from 'sonner'; +import { ApiError } from '@/api/client'; +import { Alert, AlertDescription } from '@/ui/alert'; +import { Button } from '@/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/ui/dialog'; +import { Input } from '@/ui/input'; +import { Label } from '@/ui/label'; +import { useResetUserPassword } from '../hooks'; + +// Admin-initiated reset. Mirrors the invite flow: the admin sets a temporary +// password and shares it out-of-band. The server flags the user +// must_change_password=true and revokes their sessions, so on next login they +// are forced to pick a new password (same as first login). Field minimum +// (≥8 chars) mirrors the server. +export function ResetPasswordDialog({ + userId, + email, +}: { + userId: string; + email: string; +}) { + const [open, setOpen] = useState(false); + const [pw, setPw] = useState(''); + const reset = useResetUserPassword(); + + function clear() { + setPw(''); + reset.reset(); + } + + async function onSubmit() { + if (pw.length < 8) return; + try { + await reset.mutateAsync({ id: userId, body: { new_password: pw } }); + toast.success('Password reset', { + description: `Share the temporary password with ${email}. They will be required to change it on next login.`, + }); + setOpen(false); + clear(); + } catch (err) { + const detail = err instanceof ApiError ? err.detail : String(err); + toast.error('Failed to reset password', { description: detail }); + } + } + + return ( + { + setOpen(next); + if (!next) clear(); + }} + > + + + + + + Reset password + + Sets a temporary password for {email}. They are forced to change it + on next login and any active sessions are signed out. + + + +
+
+ + setPw(e.target.value)} + placeholder="At least 8 characters" + /> +

+ Shown once. Share via your team’s preferred secure channel. +

+
+ + + The account will be flagged{' '} + must_change_password{' '} + and its sessions revoked; the user cannot continue until they pick + a new password. + + +
+ + + + + +
+
+ ); +} diff --git a/server/dashboard/src/modules/users/components/UsersTable.tsx b/server/dashboard/src/modules/users/components/UsersTable.tsx index 733c1df..56f3d68 100644 --- a/server/dashboard/src/modules/users/components/UsersTable.tsx +++ b/server/dashboard/src/modules/users/components/UsersTable.tsx @@ -12,6 +12,7 @@ import { cn } from '@/lib/cn'; import { formatDateTime, formatRelative } from '@/lib/formatDate'; import { DeleteUserDialog } from './DeleteUserDialog'; import { DisableUserButton } from './DisableUserButton'; +import { ResetPasswordDialog } from './ResetPasswordDialog'; import { UserRoleSelect } from './UserRoleSelect'; import { UserLocalProjectToggle } from './UserLocalProjectToggle'; @@ -97,6 +98,7 @@ export function UsersTable({
{isSelf ? null : ( <> + diff --git a/server/dashboard/src/modules/users/hooks.ts b/server/dashboard/src/modules/users/hooks.ts index d8baab6..fd3171d 100644 --- a/server/dashboard/src/modules/users/hooks.ts +++ b/server/dashboard/src/modules/users/hooks.ts @@ -2,6 +2,7 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { api } from '@/api/client'; import type { CreateUserRequest, + ResetUserPasswordRequest, UpdateUserRequest, User, UserListResponse, @@ -35,6 +36,15 @@ export function useUpdateUser() { }); } +export function useResetUserPassword() { + const qc = useQueryClient(); + return useMutation({ + mutationFn: ({ id, body }: { id: string; body: ResetUserPasswordRequest }) => + api.post(`/admin/users/${id}/reset-password`, body), + onSuccess: () => qc.invalidateQueries({ queryKey: userKeys.all }), + }); +} + export function useDeleteUser() { const qc = useQueryClient(); return useMutation({ diff --git a/server/internal/httpapi/auth.go b/server/internal/httpapi/auth.go index eec77eb..3eebfa1 100644 --- a/server/internal/httpapi/auth.go +++ b/server/internal/httpapi/auth.go @@ -11,6 +11,7 @@ import ( "github.com/dvcdsys/code-index/server/internal/httpapi/openapi" "github.com/dvcdsys/code-index/server/internal/sessions" "github.com/dvcdsys/code-index/server/internal/users" + "github.com/go-chi/chi/v5" ) // userPayload mirrors the OpenAPI `User` schema. Built by hand instead of @@ -473,6 +474,53 @@ func (s *Server) DeleteUser(w http.ResponseWriter, r *http.Request, id string) { w.WriteHeader(http.StatusNoContent) } +// ResetUserPassword — POST /api/v1/admin/users/{id}/reset-password (admin only). +// +// Sets a new admin-chosen temporary password and forces the user to change it +// on next login (must_change_password=1), mirroring the invite flow. Any admin +// may reset any user, including another admin — a reset neither demotes nor +// disables anyone, so no last-admin guard applies. The target user's existing +// sessions are revoked so they must log back in and pass the change-password +// gate. +// +// Mounted directly in router.go (chi.URLParam for {id}) rather than through the +// generated OpenAPI mux: the committed openapi.gen.go predates the pinned +// oapi-codegen and several other admin endpoints (embedding providers) follow +// the same direct-mount pattern. The endpoint still lives in doc/openapi.yaml +// as the source of truth. +func (s *Server) ResetUserPassword(w http.ResponseWriter, r *http.Request) { + if _, ok := s.mustBeAdmin(w, r); !ok { + return + } + id := chi.URLParam(r, "id") + var body struct { + NewPassword string `json:"new_password"` + } + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + writeError(w, http.StatusUnprocessableEntity, "invalid JSON body") + return + } + if len(body.NewPassword) < 8 { + writeError(w, http.StatusUnprocessableEntity, "new_password must be at least 8 characters") + return + } + if err := s.Deps.Users.AdminResetPassword(r.Context(), id, body.NewPassword); err != nil { + respondUserMutationError(w, err) + return + } + // Force re-login: best-effort revoke of all the target user's sessions. + // Failure here is non-fatal — the new password and flag are already set. + if s.Deps.Sessions != nil { + _ = s.Deps.Sessions.DeleteAllForUser(r.Context(), id) + } + u, err := s.Deps.Users.GetByID(r.Context(), id) + if err != nil { + respondUserMutationError(w, err) + return + } + writeJSON(w, http.StatusOK, userToPayload(u)) +} + func respondUserMutationError(w http.ResponseWriter, err error) { switch { case errors.Is(err, users.ErrNotFound): diff --git a/server/internal/httpapi/auth_test.go b/server/internal/httpapi/auth_test.go index 0e65431..b80537c 100644 --- a/server/internal/httpapi/auth_test.go +++ b/server/internal/httpapi/auth_test.go @@ -318,6 +318,123 @@ func TestCreateUser_AdminOnly(t *testing.T) { } } +// resetPasswordRR POSTs to the admin reset-password endpoint as the caller +// holding `cookie` and returns the recorder. +func resetPasswordRR(t *testing.T, router http.Handler, cookie, userID, newPassword string) *httptest.ResponseRecorder { + t.Helper() + body, _ := json.Marshal(map[string]string{"new_password": newPassword}) + req := withCookie(httptest.NewRequest(http.MethodPost, "/api/v1/admin/users/"+userID+"/reset-password", bytes.NewReader(body)), cookie) + req.Header.Set("Content-Type", "application/json") + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + return rr +} + +func TestResetUserPassword_AdminFlow(t *testing.T) { + f := newAuthFixture(t) + adminCookie := sessionCookie(loginRR(t, f.Router, "admin@example.com", "secret-password")) + + // Seed a target user who is NOT flagged to change their password (so we + // can prove the reset sets the flag). + target, err := f.Deps.Users.Create(context.Background(), "target@example.com", "oldpassword1", users.RoleUser, false) + if err != nil { + t.Fatalf("seed target: %v", err) + } + // The target logs in once — gives us a live session to prove revocation. + targetCookie := sessionCookie(loginRR(t, f.Router, "target@example.com", "oldpassword1")) + if targetCookie == "" { + t.Fatalf("target login did not set a cookie") + } + + // Admin resets the target's password. + rr := resetPasswordRR(t, f.Router, adminCookie, target.ID, "freshpass123") + if rr.Code != http.StatusOK { + t.Fatalf("admin reset status = %d (body=%s)", rr.Code, rr.Body.String()) + } + var payload struct { + MustChangePassword bool `json:"must_change_password"` + } + _ = json.Unmarshal(rr.Body.Bytes(), &payload) + if !payload.MustChangePassword { + t.Errorf("response must_change_password = false, want true") + } + + // The old password no longer works; the new temp password does. + if rr := loginRR(t, f.Router, "target@example.com", "oldpassword1"); rr.Code == http.StatusOK { + t.Errorf("login with OLD password succeeded, want failure") + } + relogin := loginRR(t, f.Router, "target@example.com", "freshpass123") + if relogin.Code != http.StatusOK { + t.Fatalf("login with NEW password status = %d (body=%s)", relogin.Code, relogin.Body.String()) + } + var loginBody struct { + User struct { + MustChangePassword bool `json:"must_change_password"` + } `json:"user"` + } + _ = json.Unmarshal(relogin.Body.Bytes(), &loginBody) + if !loginBody.User.MustChangePassword { + t.Errorf("login payload must_change_password = false, want true") + } + + // The target's PRE-EXISTING session was revoked. + req := withCookie(httptest.NewRequest(http.MethodGet, "/api/v1/auth/me", nil), targetCookie) + meRR := httptest.NewRecorder() + f.Router.ServeHTTP(meRR, req) + if meRR.Code != http.StatusUnauthorized { + t.Errorf("pre-reset session /auth/me status = %d, want 401", meRR.Code) + } +} + +func TestResetUserPassword_AdminOnly(t *testing.T) { + f := newAuthFixture(t) + + // Seed a non-admin who will both be the target and attempt the reset. + viewer, err := f.Deps.Users.Create(context.Background(), "viewer@example.com", "viewerpass1", users.RoleUser, false) + if err != nil { + t.Fatalf("seed viewer: %v", err) + } + viewerCookie := sessionCookie(loginRR(t, f.Router, "viewer@example.com", "viewerpass1")) + + rr := resetPasswordRR(t, f.Router, viewerCookie, viewer.ID, "newpass12345") + if rr.Code != http.StatusForbidden { + t.Errorf("viewer reset status = %d, want 403", rr.Code) + } +} + +func TestResetUserPassword_CanResetAnotherAdmin(t *testing.T) { + f := newAuthFixture(t) + adminCookie := sessionCookie(loginRR(t, f.Router, "admin@example.com", "secret-password")) + + other, err := f.Deps.Users.Create(context.Background(), "other-admin@example.com", "otheradmin1", users.RoleAdmin, false) + if err != nil { + t.Fatalf("seed other admin: %v", err) + } + rr := resetPasswordRR(t, f.Router, adminCookie, other.ID, "resetadmin123") + if rr.Code != http.StatusOK { + t.Errorf("reset another admin status = %d (body=%s), want 200", rr.Code, rr.Body.String()) + } +} + +func TestResetUserPassword_Validation(t *testing.T) { + f := newAuthFixture(t) + adminCookie := sessionCookie(loginRR(t, f.Router, "admin@example.com", "secret-password")) + + // Unknown user id → 404. + if rr := resetPasswordRR(t, f.Router, adminCookie, "does-not-exist", "validpass123"); rr.Code != http.StatusNotFound { + t.Errorf("unknown id status = %d, want 404 (body=%s)", rr.Code, rr.Body.String()) + } + + // Seed a real target, then send a too-short password → 422. + target, err := f.Deps.Users.Create(context.Background(), "shortpw@example.com", "oldpassword1", users.RoleUser, false) + if err != nil { + t.Fatalf("seed target: %v", err) + } + if rr := resetPasswordRR(t, f.Router, adminCookie, target.ID, "short"); rr.Code != http.StatusUnprocessableEntity { + t.Errorf("short password status = %d, want 422 (body=%s)", rr.Code, rr.Body.String()) + } +} + // --- API key CRUD via HTTP --- func TestApiKey_CreateListRevokeFlow(t *testing.T) { diff --git a/server/internal/httpapi/router.go b/server/internal/httpapi/router.go index 59fad07..57267e3 100644 --- a/server/internal/httpapi/router.go +++ b/server/internal/httpapi/router.go @@ -201,5 +201,12 @@ func NewRouter(d Deps) http.Handler { r.Put("/api/v1/admin/embedding-providers/active", srv.SwitchEmbeddingProvider) r.Post("/api/v1/admin/embedding-providers/{kind}/test", srv.TestEmbeddingProvider) + // Admin password reset — mounted directly for the same reason as the + // embedding-provider routes above (the committed openapi.gen.go is stale + // vs the pinned oapi-codegen, so we don't regenerate it here). The + // endpoint is documented in doc/openapi.yaml. The handler gates on + // mustBeAdmin. + r.Post("/api/v1/admin/users/{id}/reset-password", srv.ResetUserPassword) + return r } diff --git a/server/internal/users/users.go b/server/internal/users/users.go index 79ac35d..91aefb8 100644 --- a/server/internal/users/users.go +++ b/server/internal/users/users.go @@ -330,6 +330,33 @@ func (s *Service) UpdatePassword(ctx context.Context, id, newPassword string) er return nil } +// AdminResetPassword sets a new password and FORCES must_change_password=1, +// mirroring user creation. It is the admin-initiated counterpart to +// UpdatePassword (which clears the flag for self-service changes): after a +// reset the user is required to pick a new password on next login. The caller +// is responsible for revoking the target user's existing sessions — see +// internal/sessions DeleteAllForUser. +func (s *Service) AdminResetPassword(ctx context.Context, id, newPassword string) error { + if newPassword == "" { + return fmt.Errorf("new password required") + } + hash, err := bcrypt.GenerateFromPassword([]byte(newPassword), BcryptCost) + if err != nil { + return fmt.Errorf("hash password: %w", err) + } + now := time.Now().UTC().Format(time.RFC3339Nano) + res, err := s.DB.ExecContext(ctx, + `UPDATE users SET password_hash = ?, must_change_password = 1, updated_at = ? WHERE id = ?`, + string(hash), now, id) + if err != nil { + return fmt.Errorf("reset password: %w", err) + } + if n, _ := res.RowsAffected(); n == 0 { + return ErrNotFound + } + return nil +} + // SetRole changes a user's role. Refuses to demote the last active admin // to keep the system reachable. func (s *Service) SetRole(ctx context.Context, id, role string) error { From 27dc36007e1be33bc3d1422e064ed8944703128e Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 15:02:01 +0100 Subject: [PATCH 2/7] chore(openapi): regenerate gen.go and route admin endpoints through the generated mux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- server/internal/httpapi/admin_embeddings.go | 6 +- server/internal/httpapi/auth.go | 10 +- .../internal/httpapi/openapi/openapi.gen.go | 1357 +++++++++++------ server/internal/httpapi/router.go | 21 +- 4 files changed, 905 insertions(+), 489 deletions(-) diff --git a/server/internal/httpapi/admin_embeddings.go b/server/internal/httpapi/admin_embeddings.go index c4529e0..5ed2b1c 100644 --- a/server/internal/httpapi/admin_embeddings.go +++ b/server/internal/httpapi/admin_embeddings.go @@ -22,7 +22,7 @@ import ( "github.com/dvcdsys/code-index/server/internal/embeddings" "github.com/dvcdsys/code-index/server/internal/embeddings/provider" "github.com/dvcdsys/code-index/server/internal/embeddingscfg" - "github.com/go-chi/chi/v5" + "github.com/dvcdsys/code-index/server/internal/httpapi/openapi" ) // providerInfoPayload is the per-kind entry in GET /embedding-providers. @@ -249,11 +249,11 @@ func (s *Server) SwitchEmbeddingProvider(w http.ResponseWriter, r *http.Request) // persisting it), Starts it, then Stops it. Returns the detected // dimension and a success flag, or a typed error message the // dashboard can render verbatim. -func (s *Server) TestEmbeddingProvider(w http.ResponseWriter, r *http.Request) { +func (s *Server) TestEmbeddingProvider(w http.ResponseWriter, r *http.Request, kindParam openapi.TestEmbeddingProviderParamsKind) { if _, ok := s.mustBeAdmin(w, r); !ok { return } - kind := chi.URLParam(r, "kind") + kind := string(kindParam) if kind == "" { writeError(w, http.StatusBadRequest, "kind is required") return diff --git a/server/internal/httpapi/auth.go b/server/internal/httpapi/auth.go index 3eebfa1..7ed1fdb 100644 --- a/server/internal/httpapi/auth.go +++ b/server/internal/httpapi/auth.go @@ -11,7 +11,6 @@ import ( "github.com/dvcdsys/code-index/server/internal/httpapi/openapi" "github.com/dvcdsys/code-index/server/internal/sessions" "github.com/dvcdsys/code-index/server/internal/users" - "github.com/go-chi/chi/v5" ) // userPayload mirrors the OpenAPI `User` schema. Built by hand instead of @@ -482,17 +481,10 @@ func (s *Server) DeleteUser(w http.ResponseWriter, r *http.Request, id string) { // disables anyone, so no last-admin guard applies. The target user's existing // sessions are revoked so they must log back in and pass the change-password // gate. -// -// Mounted directly in router.go (chi.URLParam for {id}) rather than through the -// generated OpenAPI mux: the committed openapi.gen.go predates the pinned -// oapi-codegen and several other admin endpoints (embedding providers) follow -// the same direct-mount pattern. The endpoint still lives in doc/openapi.yaml -// as the source of truth. -func (s *Server) ResetUserPassword(w http.ResponseWriter, r *http.Request) { +func (s *Server) ResetUserPassword(w http.ResponseWriter, r *http.Request, id string) { if _, ok := s.mustBeAdmin(w, r); !ok { return } - id := chi.URLParam(r, "id") var body struct { NewPassword string `json:"new_password"` } diff --git a/server/internal/httpapi/openapi/openapi.gen.go b/server/internal/httpapi/openapi/openapi.gen.go index 25551c2..c35d4c1 100644 --- a/server/internal/httpapi/openapi/openapi.gen.go +++ b/server/internal/httpapi/openapi/openapi.gen.go @@ -26,6 +26,27 @@ const ( BearerAuthScopes bearerAuthContextKey = "bearerAuth.Scopes" ) +// Defines values for ActiveEmbeddingProviderKind. +const ( + ActiveEmbeddingProviderKindOllama ActiveEmbeddingProviderKind = "ollama" + ActiveEmbeddingProviderKindOpenai ActiveEmbeddingProviderKind = "openai" + ActiveEmbeddingProviderKindVoyage ActiveEmbeddingProviderKind = "voyage" +) + +// Valid indicates whether the value is a known member of the ActiveEmbeddingProviderKind enum. +func (e ActiveEmbeddingProviderKind) Valid() bool { + switch e { + case ActiveEmbeddingProviderKindOllama: + return true + case ActiveEmbeddingProviderKindOpenai: + return true + case ActiveEmbeddingProviderKindVoyage: + return true + default: + return false + } +} + // Defines values for AddGitRepoRequestWebhookMode. const ( AddGitRepoRequestWebhookModeAuto AddGitRepoRequestWebhookMode = "auto" @@ -65,6 +86,27 @@ func (e CreateUserRequestRole) Valid() bool { } } +// Defines values for EmbeddingProviderInfoKind. +const ( + EmbeddingProviderInfoKindOllama EmbeddingProviderInfoKind = "ollama" + EmbeddingProviderInfoKindOpenai EmbeddingProviderInfoKind = "openai" + EmbeddingProviderInfoKindVoyage EmbeddingProviderInfoKind = "voyage" +) + +// Valid indicates whether the value is a known member of the EmbeddingProviderInfoKind enum. +func (e EmbeddingProviderInfoKind) Valid() bool { + switch e { + case EmbeddingProviderInfoKindOllama: + return true + case EmbeddingProviderInfoKindOpenai: + return true + case EmbeddingProviderInfoKindVoyage: + return true + default: + return false + } +} + // Defines values for GitRepoWebhookMode. const ( GitRepoWebhookModeAuto GitRepoWebhookMode = "auto" @@ -419,6 +461,27 @@ func (e StatusResponseStatus) Valid() bool { } } +// Defines values for SwitchEmbeddingProviderRequestKind. +const ( + SwitchEmbeddingProviderRequestKindOllama SwitchEmbeddingProviderRequestKind = "ollama" + SwitchEmbeddingProviderRequestKindOpenai SwitchEmbeddingProviderRequestKind = "openai" + SwitchEmbeddingProviderRequestKindVoyage SwitchEmbeddingProviderRequestKind = "voyage" +) + +// Valid indicates whether the value is a known member of the SwitchEmbeddingProviderRequestKind enum. +func (e SwitchEmbeddingProviderRequestKind) Valid() bool { + switch e { + case SwitchEmbeddingProviderRequestKindOllama: + return true + case SwitchEmbeddingProviderRequestKindOpenai: + return true + case SwitchEmbeddingProviderRequestKindVoyage: + return true + default: + return false + } +} + // Defines values for TunnelBinaryProvider. const ( TunnelBinaryProviderCloudflare TunnelBinaryProvider = "cloudflare" @@ -740,6 +803,27 @@ func (e WorkspaceSearchResponseStatus) Valid() bool { } } +// Defines values for TestEmbeddingProviderParamsKind. +const ( + TestEmbeddingProviderParamsKindOllama TestEmbeddingProviderParamsKind = "ollama" + TestEmbeddingProviderParamsKindOpenai TestEmbeddingProviderParamsKind = "openai" + TestEmbeddingProviderParamsKindVoyage TestEmbeddingProviderParamsKind = "voyage" +) + +// Valid indicates whether the value is a known member of the TestEmbeddingProviderParamsKind enum. +func (e TestEmbeddingProviderParamsKind) Valid() bool { + switch e { + case TestEmbeddingProviderParamsKindOllama: + return true + case TestEmbeddingProviderParamsKindOpenai: + return true + case TestEmbeddingProviderParamsKindVoyage: + return true + default: + return false + } +} + // Defines values for ListApiKeysParamsOwner. const ( All ListApiKeysParamsOwner = "all" @@ -851,6 +935,21 @@ func (e UpdateTunnelBinaryParamsProvider) Valid() bool { } } +// ActiveEmbeddingProvider defines model for ActiveEmbeddingProvider. +type ActiveEmbeddingProvider struct { + // Config Persisted provider config blob. Shape varies by kind; API + // keys are NOT stored — only env-var names are. + Config *map[string]interface{} `json:"config,omitempty"` + + // Id `Provider.ID()` fingerprint, e.g. `voyage:voyage-code-3:1024:float`. + // Matches `embedding_model` on /status. + Id string `json:"id"` + Kind ActiveEmbeddingProviderKind `json:"kind"` +} + +// ActiveEmbeddingProviderKind defines model for ActiveEmbeddingProvider.Kind. +type ActiveEmbeddingProviderKind string + // AddGitRepoRequest defines model for AddGitRepoRequest. type AddGitRepoRequest struct { Branch string `json:"branch"` @@ -1024,6 +1123,40 @@ type DirEntry struct { Path string `json:"path"` } +// EmbeddingProviderInfo defines model for EmbeddingProviderInfo. +type EmbeddingProviderInfo struct { + Kind EmbeddingProviderInfoKind `json:"kind"` + + // Schema ConfigSchema as JSON — describes the form fields the + // provider accepts. Shape is `{fields: [{name, label, kind, + // required, default, enum, description}]}`. Hardcoded React + // forms ignore this; it's exposed for external tooling. + Schema map[string]interface{} `json:"schema"` + + // SecretEnvs Env-var names this provider reads for credentials, with a + // flag telling whether each is currently set on the server. + // Used by the dashboard to render the missing-key banner + // before save. + SecretEnvs []EmbeddingProviderSecretEnv `json:"secret_envs"` +} + +// EmbeddingProviderInfoKind defines model for EmbeddingProviderInfo.Kind. +type EmbeddingProviderInfoKind string + +// EmbeddingProviderList defines model for EmbeddingProviderList. +type EmbeddingProviderList struct { + Providers []EmbeddingProviderInfo `json:"providers"` +} + +// EmbeddingProviderSecretEnv defines model for EmbeddingProviderSecretEnv. +type EmbeddingProviderSecretEnv struct { + // Name Env-var name (e.g. `CIX_VOYAGE_API_KEY`). + Name string `json:"name"` + + // Set True when the env var is present (and non-empty) on the server. + Set bool `json:"set"` +} + // Error defines model for Error. type Error struct { Detail string `json:"detail"` @@ -1620,6 +1753,13 @@ type ReindexEnqueuedResponseMode string // ReindexEnqueuedResponseStatus defines model for ReindexEnqueuedResponse.Status. type ReindexEnqueuedResponseStatus string +// ResetUserPasswordRequest defines model for ResetUserPasswordRequest. +type ResetUserPasswordRequest struct { + // NewPassword One-time password the user must change on next login. + // The admin shares this out-of-band. + NewPassword string `json:"new_password"` +} + // RestartAccepted defines model for RestartAccepted. type RestartAccepted struct { // RestartId Opaque ID; future versions may expose per-restart progress under this id. @@ -1760,9 +1900,25 @@ type StatusResponse struct { // Backend Backend identifier (e.g. `go`). Backend string `json:"backend"` - // EmbeddingModel Hugging Face model id (e.g. `awhiteside/CodeRankEmbed-Q8_0-GGUF`). + // EmbeddingModel Active provider fingerprint — formerly the HuggingFace repo id, + // now `Provider.ID()` e.g. `ollama:CodeRankEmbed`, + // `openai:text-embedding-3-small`, `voyage:voyage-code-3:1024:float`. + // Used by the dashboard to compare against each project's + // `indexed_with_model` and render the stale-model badge. EmbeddingModel string `json:"embedding_model"` + // EmbeddingProvider Active provider kind: `ollama`, `openai`, or `voyage`. Empty + // when the embedding service is disabled or the fake fixtures + // substitute a non-Service implementation. + EmbeddingProvider *string `json:"embedding_provider,omitempty"` + + // EmbeddingProviderManagesProcess True when the active provider owns an in-process child + // (currently only `ollama`). The footer renders a green/red + // liveness dot when true, and a permanent green dot otherwise + // (HTTP-only providers have no process to die — Ready failures + // surface at request time, not on every footer poll). + EmbeddingProviderManagesProcess *bool `json:"embedding_provider_manages_process,omitempty"` + // LatestVersion Latest released server version (without the `server/v` prefix, // e.g. `0.5.1`). Null until the first successful poll completes. LatestVersion *string `json:"latest_version,omitempty"` @@ -1790,6 +1946,15 @@ type StatusResponse struct { // StatusResponseStatus defines model for StatusResponse.Status. type StatusResponseStatus string +// SwitchEmbeddingProviderRequest defines model for SwitchEmbeddingProviderRequest. +type SwitchEmbeddingProviderRequest struct { + Config map[string]interface{} `json:"config"` + Kind SwitchEmbeddingProviderRequestKind `json:"kind"` +} + +// SwitchEmbeddingProviderRequestKind defines model for SwitchEmbeddingProviderRequest.Kind. +type SwitchEmbeddingProviderRequestKind string + // SymbolEntry defines model for SymbolEntry. type SymbolEntry struct { FilePath string `json:"file_path"` @@ -1823,6 +1988,14 @@ type SymbolSearchResponse struct { Total int `json:"total"` } +// TestEmbeddingProviderResponse defines model for TestEmbeddingProviderResponse. +type TestEmbeddingProviderResponse struct { + // Dimension Embedding dimension as reported by the provider after + // Start. 0 when the provider learns the dimension lazily. + Dimension *int `json:"dimension,omitempty"` + Ok bool `json:"ok"` +} + // TunnelBinary defines model for TunnelBinary. type TunnelBinary struct { Installed bool `json:"installed"` @@ -1966,6 +2139,11 @@ type UpdateUserRequest struct { // the last enabled admin when set to true. Disabled *bool `json:"disabled,omitempty"` + // LocalProjectDisabled When true, the user may not create local projects or + // index/reindex any project. Search and workspace creation stay + // allowed; admins are always exempt. Has no last-admin guard. + LocalProjectDisabled *bool `json:"local_project_disabled,omitempty"` + // Role New role for the user. Refused for the last enabled admin // when set to `user`. Role *UpdateUserRequestRole `json:"role,omitempty"` @@ -1989,13 +2167,21 @@ type User struct { // Disabled True when `disabled_at` is set. Disabled users cannot // authenticate via password OR API key. - Disabled bool `json:"disabled"` - DisabledAt *time.Time `json:"disabled_at,omitempty"` - Email openapi_types.Email `json:"email"` - Id string `json:"id"` - MustChangePassword bool `json:"must_change_password"` - Role UserRole `json:"role"` - UpdatedAt time.Time `json:"updated_at"` + Disabled bool `json:"disabled"` + DisabledAt *time.Time `json:"disabled_at,omitempty"` + Email openapi_types.Email `json:"email"` + Id string `json:"id"` + + // LocalProjectDisabled When true, the user may not create local projects or + // index/reindex any project (both return 403). Search of + // already-indexed projects and workspace creation remain + // allowed. Admins are always exempt regardless of this flag. + // Defaults to false; existing users created before this field + // was introduced are false (allowed) for backward compatibility. + LocalProjectDisabled bool `json:"local_project_disabled"` + MustChangePassword bool `json:"must_change_password"` + Role UserRole `json:"role"` + UpdatedAt time.Time `json:"updated_at"` } // UserRole defines model for User.Role. @@ -2025,10 +2211,18 @@ type UserWithStats struct { // LastLoginAt Most recent session creation timestamp (RFC3339). // Null if the user has never logged in. - LastLoginAt *time.Time `json:"last_login_at,omitempty"` - MustChangePassword bool `json:"must_change_password"` - Role UserWithStatsRole `json:"role"` - UpdatedAt time.Time `json:"updated_at"` + LastLoginAt *time.Time `json:"last_login_at,omitempty"` + + // LocalProjectDisabled When true, the user may not create local projects or + // index/reindex any project (both return 403). Search of + // already-indexed projects and workspace creation remain + // allowed. Admins are always exempt regardless of this flag. + // Defaults to false; existing users created before this field + // was introduced are false (allowed) for backward compatibility. + LocalProjectDisabled bool `json:"local_project_disabled"` + MustChangePassword bool `json:"must_change_password"` + Role UserWithStatsRole `json:"role"` + UpdatedAt time.Time `json:"updated_at"` } // UserWithStatsRole defines model for UserWithStats.Role. @@ -2280,6 +2474,9 @@ type WorkspaceSearchStaleFTSRepo struct { // ProjectHash defines model for ProjectHash. type ProjectHash = string +// BadRequest defines model for BadRequest. +type BadRequest = Error + // Conflict defines model for Conflict. type Conflict = Error @@ -2307,6 +2504,12 @@ type WorkspacesDisabled = Error // bearerAuthContextKey is the context key for bearerAuth security scheme type bearerAuthContextKey string +// TestEmbeddingProviderJSONBody defines parameters for TestEmbeddingProvider. +type TestEmbeddingProviderJSONBody map[string]interface{} + +// TestEmbeddingProviderParamsKind defines parameters for TestEmbeddingProvider. +type TestEmbeddingProviderParamsKind string + // ListApiKeysParams defines parameters for ListApiKeys. type ListApiKeysParams struct { // Owner `all` — admin-only, returns every key in the system. @@ -2395,6 +2598,12 @@ type WorkspaceSearchParams struct { MinScore *float32 `form:"min_score,omitempty" json:"min_score,omitempty"` } +// SwitchEmbeddingProviderJSONRequestBody defines body for SwitchEmbeddingProvider for application/json ContentType. +type SwitchEmbeddingProviderJSONRequestBody = SwitchEmbeddingProviderRequest + +// TestEmbeddingProviderJSONRequestBody defines body for TestEmbeddingProvider for application/json ContentType. +type TestEmbeddingProviderJSONRequestBody TestEmbeddingProviderJSONBody + // PutRuntimeConfigJSONRequestBody defines body for PutRuntimeConfig for application/json ContentType. type PutRuntimeConfigJSONRequestBody = RuntimeConfigUpdate @@ -2404,6 +2613,9 @@ type CreateUserJSONRequestBody = CreateUserRequest // UpdateUserJSONRequestBody defines body for UpdateUser for application/json ContentType. type UpdateUserJSONRequestBody = UpdateUserRequest +// ResetUserPasswordJSONRequestBody defines body for ResetUserPassword for application/json ContentType. +type ResetUserPasswordJSONRequestBody = ResetUserPasswordRequest + // CreateApiKeyJSONRequestBody defines body for CreateApiKey for application/json ContentType. type CreateApiKeyJSONRequestBody = CreateApiKeyRequest @@ -2487,6 +2699,18 @@ type ShareWorkspaceToGroupJSONRequestBody = ShareToGroupRequest // ServerInterface represents all server handlers. type ServerInterface interface { + // List registered embedding-provider kinds (admin only) + // (GET /api/v1/admin/embedding-providers) + ListEmbeddingProviders(w http.ResponseWriter, r *http.Request) + // Get the currently active embedding provider (admin only) + // (GET /api/v1/admin/embedding-providers/active) + GetActiveEmbeddingProvider(w http.ResponseWriter, r *http.Request) + // Switch to a different embedding provider (admin only) + // (PUT /api/v1/admin/embedding-providers/active) + SwitchEmbeddingProvider(w http.ResponseWriter, r *http.Request) + // Validate an embedding-provider config without persisting (admin only) + // (POST /api/v1/admin/embedding-providers/{kind}/test) + TestEmbeddingProvider(w http.ResponseWriter, r *http.Request, kind TestEmbeddingProviderParamsKind) // List GGUF model files cached on disk (admin only) // (GET /api/v1/admin/models) ListModels(w http.ResponseWriter, r *http.Request) @@ -2514,6 +2738,9 @@ type ServerInterface interface { // Change role or disabled flag (admin only) // (PATCH /api/v1/admin/users/{id}) UpdateUser(w http.ResponseWriter, r *http.Request, id string) + // Reset a user's password (admin only) + // (POST /api/v1/admin/users/{id}/reset-password) + ResetUserPassword(w http.ResponseWriter, r *http.Request, id string) // List my API keys (or all keys if admin) // (GET /api/v1/api-keys) ListApiKeys(w http.ResponseWriter, r *http.Request, params ListApiKeysParams) @@ -2751,6 +2978,30 @@ type ServerInterface interface { type Unimplemented struct{} +// List registered embedding-provider kinds (admin only) +// (GET /api/v1/admin/embedding-providers) +func (_ Unimplemented) ListEmbeddingProviders(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Get the currently active embedding provider (admin only) +// (GET /api/v1/admin/embedding-providers/active) +func (_ Unimplemented) GetActiveEmbeddingProvider(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Switch to a different embedding provider (admin only) +// (PUT /api/v1/admin/embedding-providers/active) +func (_ Unimplemented) SwitchEmbeddingProvider(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Validate an embedding-provider config without persisting (admin only) +// (POST /api/v1/admin/embedding-providers/{kind}/test) +func (_ Unimplemented) TestEmbeddingProvider(w http.ResponseWriter, r *http.Request, kind TestEmbeddingProviderParamsKind) { + w.WriteHeader(http.StatusNotImplemented) +} + // List GGUF model files cached on disk (admin only) // (GET /api/v1/admin/models) func (_ Unimplemented) ListModels(w http.ResponseWriter, r *http.Request) { @@ -2805,6 +3056,12 @@ func (_ Unimplemented) UpdateUser(w http.ResponseWriter, r *http.Request, id str w.WriteHeader(http.StatusNotImplemented) } +// Reset a user's password (admin only) +// (POST /api/v1/admin/users/{id}/reset-password) +func (_ Unimplemented) ResetUserPassword(w http.ResponseWriter, r *http.Request, id string) { + w.WriteHeader(http.StatusNotImplemented) +} + // List my API keys (or all keys if admin) // (GET /api/v1/api-keys) func (_ Unimplemented) ListApiKeys(w http.ResponseWriter, r *http.Request, params ListApiKeysParams) { @@ -3276,6 +3533,98 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc func(http.Handler) http.Handler +// ListEmbeddingProviders operation middleware +func (siw *ServerInterfaceWrapper) ListEmbeddingProviders(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListEmbeddingProviders(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetActiveEmbeddingProvider operation middleware +func (siw *ServerInterfaceWrapper) GetActiveEmbeddingProvider(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetActiveEmbeddingProvider(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// SwitchEmbeddingProvider operation middleware +func (siw *ServerInterfaceWrapper) SwitchEmbeddingProvider(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.SwitchEmbeddingProvider(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// TestEmbeddingProvider operation middleware +func (siw *ServerInterfaceWrapper) TestEmbeddingProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "kind" ------------- + var kind TestEmbeddingProviderParamsKind + + err = runtime.BindStyledParameterWithOptions("simple", "kind", chi.URLParam(r, "kind"), &kind, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "kind", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.TestEmbeddingProvider(w, r, kind) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // ListModels operation middleware func (siw *ServerInterfaceWrapper) ListModels(w http.ResponseWriter, r *http.Request) { @@ -3480,6 +3829,38 @@ func (siw *ServerInterfaceWrapper) UpdateUser(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } +// ResetUserPassword operation middleware +func (siw *ServerInterfaceWrapper) ResetUserPassword(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id string + + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ResetUserPassword(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // ListApiKeys operation middleware func (siw *ServerInterfaceWrapper) ListApiKeys(w http.ResponseWriter, r *http.Request) { @@ -5965,6 +6346,18 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl ErrorHandlerFunc: options.ErrorHandlerFunc, } + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/api/v1/admin/embedding-providers", wrapper.ListEmbeddingProviders) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/api/v1/admin/embedding-providers/active", wrapper.GetActiveEmbeddingProvider) + }) + r.Group(func(r chi.Router) { + r.Put(options.BaseURL+"/api/v1/admin/embedding-providers/active", wrapper.SwitchEmbeddingProvider) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/api/v1/admin/embedding-providers/{kind}/test", wrapper.TestEmbeddingProvider) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/api/v1/admin/models", wrapper.ListModels) }) @@ -5992,6 +6385,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Patch(options.BaseURL+"/api/v1/admin/users/{id}", wrapper.UpdateUser) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/api/v1/admin/users/{id}/reset-password", wrapper.ResetUserPassword) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/api/v1/api-keys", wrapper.ListApiKeys) }) @@ -6232,455 +6628,494 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/server/internal/httpapi/router.go b/server/internal/httpapi/router.go index 57267e3..daa5e80 100644 --- a/server/internal/httpapi/router.go +++ b/server/internal/httpapi/router.go @@ -190,23 +190,12 @@ func NewRouter(d Deps) http.Handler { // All API operations — chi.HandlerFromMux walks the spec and registers // one chi route per OpenAPI operation, dispatching to Server methods. + // This includes the embedding-provider admin endpoints and the admin + // password-reset endpoint; both used to be mounted directly here while + // the committed openapi.gen.go lagged the spec, but the file is now + // regenerated so the generated mux owns them (a direct mount on top + // would double-register and panic). openapi.HandlerFromMux(srv, r) - // Embedding-provider admin endpoints — mounted directly because - // they are not yet in openapi.yaml. The handlers each gate on - // mustBeAdmin; nothing reaches them without an admin session / - // API key. - r.Get("/api/v1/admin/embedding-providers", srv.ListEmbeddingProviders) - r.Get("/api/v1/admin/embedding-providers/active", srv.GetActiveEmbeddingProvider) - r.Put("/api/v1/admin/embedding-providers/active", srv.SwitchEmbeddingProvider) - r.Post("/api/v1/admin/embedding-providers/{kind}/test", srv.TestEmbeddingProvider) - - // Admin password reset — mounted directly for the same reason as the - // embedding-provider routes above (the committed openapi.gen.go is stale - // vs the pinned oapi-codegen, so we don't regenerate it here). The - // endpoint is documented in doc/openapi.yaml. The handler gates on - // mustBeAdmin. - r.Post("/api/v1/admin/users/{id}/reset-password", srv.ResetUserPassword) - return r } From 01414864975d7896504994e3076e80cae5f1656b Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 15:15:55 +0100 Subject: [PATCH 3/7] review: enforce min password length in AdminResetPassword (defense-in-depth) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- server/internal/httpapi/auth.go | 2 +- server/internal/users/users.go | 9 ++++++-- server/internal/users/users_test.go | 35 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/server/internal/httpapi/auth.go b/server/internal/httpapi/auth.go index 7ed1fdb..0650cad 100644 --- a/server/internal/httpapi/auth.go +++ b/server/internal/httpapi/auth.go @@ -492,7 +492,7 @@ func (s *Server) ResetUserPassword(w http.ResponseWriter, r *http.Request, id st writeError(w, http.StatusUnprocessableEntity, "invalid JSON body") return } - if len(body.NewPassword) < 8 { + if len(body.NewPassword) < users.MinPasswordLength { writeError(w, http.StatusUnprocessableEntity, "new_password must be at least 8 characters") return } diff --git a/server/internal/users/users.go b/server/internal/users/users.go index 91aefb8..c5b3a1c 100644 --- a/server/internal/users/users.go +++ b/server/internal/users/users.go @@ -32,6 +32,11 @@ const ( // mints a user per fixture crawl). const defaultBcryptCost = 12 +// MinPasswordLength is the minimum length for an admin-set / user-chosen +// password. HTTP handlers enforce it at the edge; AdminResetPassword also +// checks it at the service layer as defense-in-depth for non-HTTP callers. +const MinPasswordLength = 8 + // BcryptCost is the work factor actually used by Create / UpdatePassword. It is // resolved once, at package init, from (highest precedence first): // @@ -337,8 +342,8 @@ func (s *Service) UpdatePassword(ctx context.Context, id, newPassword string) er // is responsible for revoking the target user's existing sessions — see // internal/sessions DeleteAllForUser. func (s *Service) AdminResetPassword(ctx context.Context, id, newPassword string) error { - if newPassword == "" { - return fmt.Errorf("new password required") + if len(newPassword) < MinPasswordLength { + return fmt.Errorf("new password must be at least %d characters", MinPasswordLength) } hash, err := bcrypt.GenerateFromPassword([]byte(newPassword), BcryptCost) if err != nil { diff --git a/server/internal/users/users_test.go b/server/internal/users/users_test.go index 44bc212..8e6df15 100644 --- a/server/internal/users/users_test.go +++ b/server/internal/users/users_test.go @@ -89,6 +89,41 @@ func TestUpdatePassword_ClearsMustChange(t *testing.T) { } } +func TestAdminResetPassword_SetsMustChange(t *testing.T) { + s := newTestService(t) + u, _ := s.Create(context.Background(), "a@b.com", "initial-password", RoleUser, false) + if err := s.AdminResetPassword(context.Background(), u.ID, "freshpass123"); err != nil { + t.Fatalf("AdminResetPassword: %v", err) + } + got, err := s.GetByID(context.Background(), u.ID) + if err != nil { + t.Fatalf("GetByID: %v", err) + } + if !got.MustChangePassword { + t.Errorf("MustChangePassword should be SET after AdminResetPassword") + } + if _, err := s.Authenticate(context.Background(), "a@b.com", "freshpass123"); err != nil { + t.Errorf("Authenticate with reset password: %v", err) + } + if _, err := s.Authenticate(context.Background(), "a@b.com", "initial-password"); !errors.Is(err, ErrInvalidLogin) { + t.Errorf("old password should no longer authenticate, got %v", err) + } +} + +func TestAdminResetPassword_RejectsShort(t *testing.T) { + s := newTestService(t) + u, _ := s.Create(context.Background(), "a@b.com", "initial-password", RoleUser, false) + // Service-level defense-in-depth: too-short passwords are refused even + // when the HTTP edge check is bypassed. + if err := s.AdminResetPassword(context.Background(), u.ID, "short"); err == nil { + t.Errorf("AdminResetPassword accepted a %d-char password, want rejection", len("short")) + } + // The rejected reset must not have mutated the account. + if _, err := s.Authenticate(context.Background(), "a@b.com", "initial-password"); err != nil { + t.Errorf("original password should still authenticate after rejected reset: %v", err) + } +} + func TestSetRole_LastAdminBlock(t *testing.T) { s := newTestService(t) a, _ := s.Create(context.Background(), "a@b.com", "password1", RoleAdmin, false) From 2a5f9d575ffbcc120e3db645ea79df85bd60f488 Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 15:41:08 +0100 Subject: [PATCH 4/7] feat(server): admin UI to view and reset login rate-limit locks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- doc/openapi.yaml | 102 ++ server/dashboard/src/api/types.ts | 3 + .../modules/login-locks/LoginLocksPage.tsx | 58 + .../components/LoginLocksTable.tsx | 62 + .../components/ResetLockButton.tsx | 49 + .../src/modules/login-locks/hooks.ts | 27 + .../src/modules/login-locks/index.ts | 13 + server/dashboard/src/modules/registry.ts | 2 + server/internal/httpapi/loginlimiter.go | 81 ++ server/internal/httpapi/loginlocks_admin.go | 102 ++ .../internal/httpapi/loginlocks_admin_test.go | 141 ++ .../internal/httpapi/openapi/openapi.gen.go | 1139 ++++++++++------- 12 files changed, 1291 insertions(+), 488 deletions(-) create mode 100644 server/dashboard/src/modules/login-locks/LoginLocksPage.tsx create mode 100644 server/dashboard/src/modules/login-locks/components/LoginLocksTable.tsx create mode 100644 server/dashboard/src/modules/login-locks/components/ResetLockButton.tsx create mode 100644 server/dashboard/src/modules/login-locks/hooks.ts create mode 100644 server/dashboard/src/modules/login-locks/index.ts create mode 100644 server/internal/httpapi/loginlocks_admin.go create mode 100644 server/internal/httpapi/loginlocks_admin_test.go diff --git a/doc/openapi.yaml b/doc/openapi.yaml index 06fcf3f..9255428 100644 --- a/doc/openapi.yaml +++ b/doc/openapi.yaml @@ -434,6 +434,55 @@ paths: "422": $ref: "#/components/responses/Unprocessable" + /api/v1/admin/login-locks: + get: + operationId: listLoginLocks + tags: [admin] + summary: List active login rate-limit locks (admin only) + description: | + Returns the in-memory login-limiter counters that are currently at or + over their threshold — the IPs and (IP, email) pairs a login would be + rejected for right now with 429. State is per-process and self-heals as + the sliding windows expire, so this is a point-in-time snapshot. + responses: + "200": + description: Active locks + content: + application/json: + schema: + $ref: "#/components/schemas/LoginLockListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + + /api/v1/admin/login-locks/reset: + post: + operationId: resetLoginLock + tags: [admin] + summary: Clear a login rate-limit lock (admin only) + description: | + Lifts a single lock surfaced by `GET /admin/login-locks`. `type` picks + the counter: `ip` clears the per-IP horizontal-sweep counter; `ip_email` + clears the per-(IP, email) counter for one account. The admin selects + the exact row to clear — the server never clears across keys. + Idempotent: clearing a key that is no longer locked returns 204. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ResetLoginLockRequest" + responses: + "204": + description: Lock cleared (or already absent) + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "422": + $ref: "#/components/responses/Unprocessable" + /api/v1/admin/runtime-config: get: operationId: getRuntimeConfig @@ -3112,6 +3161,59 @@ components: One-time password the user must change on next login. The admin shares this out-of-band. + LoginLock: + type: object + required: [type, ip, attempts, limit, expires_at] + properties: + type: + type: string + enum: [ip, ip_email] + description: | + `ip` — the per-IP horizontal-sweep counter (many emails from one + source). `ip_email` — the per-(IP, email) counter for one account. + ip: + type: string + description: Source IP the lock is keyed on. + email: + type: string + description: Lower-cased email; present only for type `ip_email`. + attempts: + type: integer + description: Attempts currently inside the sliding window. + limit: + type: integer + description: The cap that tripped the lock. + expires_at: + type: string + format: date-time + description: RFC3339 — when the oldest attempt ages out and a slot frees. + + LoginLockListResponse: + type: object + required: [locks, total] + properties: + locks: + type: array + items: + $ref: "#/components/schemas/LoginLock" + total: + type: integer + + ResetLoginLockRequest: + type: object + required: [type, ip] + properties: + type: + type: string + enum: [ip, ip_email] + description: Which counter to clear — matches the `type` from the list. + ip: + type: string + description: Source IP of the lock to clear. + email: + type: string + description: Required when `type` is `ip_email`; ignored otherwise. + UpdateUserRequest: type: object properties: diff --git a/server/dashboard/src/api/types.ts b/server/dashboard/src/api/types.ts index 1712bdf..8ae3c7d 100644 --- a/server/dashboard/src/api/types.ts +++ b/server/dashboard/src/api/types.ts @@ -20,6 +20,9 @@ export type UpdateGroupRequest = components['schemas']['UpdateGroupRequest']; export type GroupIdListResponse = components['schemas']['GroupIdListResponse']; export type UserWithStats = components['schemas']['UserWithStats']; export type ResetUserPasswordRequest = components['schemas']['ResetUserPasswordRequest']; +export type LoginLock = components['schemas']['LoginLock']; +export type LoginLockListResponse = components['schemas']['LoginLockListResponse']; +export type ResetLoginLockRequest = components['schemas']['ResetLoginLockRequest']; export type Session = components['schemas']['Session']; export type ApiKey = components['schemas']['ApiKey']; export type ApiKeyCreated = components['schemas']['ApiKeyCreated']; diff --git a/server/dashboard/src/modules/login-locks/LoginLocksPage.tsx b/server/dashboard/src/modules/login-locks/LoginLocksPage.tsx new file mode 100644 index 0000000..6492566 --- /dev/null +++ b/server/dashboard/src/modules/login-locks/LoginLocksPage.tsx @@ -0,0 +1,58 @@ +import { AlertCircle, ShieldCheck } from 'lucide-react'; +import { ApiError } from '@/api/client'; +import { Alert, AlertDescription, AlertTitle } from '@/ui/alert'; +import { Skeleton } from '@/ui/skeleton'; +import { LoginLocksTable } from './components/LoginLocksTable'; +import { useLoginLocks } from './hooks'; + +export default function LoginLocksPage() { + const { data, error, isLoading } = useLoginLocks(); + + return ( +
+
+
+

Login security

+

+ Accounts and source IPs currently blocked by the login rate limiter + after too many failed attempts. Locks clear themselves as their + window expires — reset one to let a user back in immediately. +

+
+
+ + {isLoading ? ( +
+ {Array.from({ length: 3 }).map((_, i) => ( + + ))} +
+ ) : error ? ( + + + Failed to load login locks + + {error instanceof ApiError ? error.detail : String(error)} + + + ) : !data || data.locks.length === 0 ? ( + + ) : ( + + )} +
+ ); +} + +function EmptyState() { + return ( +
+ +

No active login locks

+

+ Nobody is currently rate-limited. Locks appear here automatically when + an account or IP exceeds the failed-login threshold. +

+
+ ); +} diff --git a/server/dashboard/src/modules/login-locks/components/LoginLocksTable.tsx b/server/dashboard/src/modules/login-locks/components/LoginLocksTable.tsx new file mode 100644 index 0000000..22ec2b2 --- /dev/null +++ b/server/dashboard/src/modules/login-locks/components/LoginLocksTable.tsx @@ -0,0 +1,62 @@ +import type { LoginLock } from '@/api/types'; +import { Badge } from '@/ui/badge'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/ui/table'; +import { formatDateTime, formatRelative } from '@/lib/formatDate'; +import { ResetLockButton } from './ResetLockButton'; + +export function LoginLocksTable({ locks }: { locks: LoginLock[] }) { + return ( +
+ + + + Type + IP + Email + Attempts + Frees + Actions + + + + {locks.map((l) => ( + + + {l.type === 'ip_email' ? ( + + IP + email + + ) : ( + + IP only + + )} + + {l.ip} + {l.email || '—'} + + {l.attempts}/{l.limit} + + + {formatRelative(l.expires_at)} + + + + + + ))} + +
+
+ ); +} diff --git a/server/dashboard/src/modules/login-locks/components/ResetLockButton.tsx b/server/dashboard/src/modules/login-locks/components/ResetLockButton.tsx new file mode 100644 index 0000000..f283a7b --- /dev/null +++ b/server/dashboard/src/modules/login-locks/components/ResetLockButton.tsx @@ -0,0 +1,49 @@ +import { Loader2, Unlock } from 'lucide-react'; +import { toast } from 'sonner'; +import { ApiError } from '@/api/client'; +import type { LoginLock } from '@/api/types'; +import { Button } from '@/ui/button'; +import { useResetLoginLock } from '../hooks'; + +// One-click unlock for a single row. The lock carries its own exact key +// (type + ip + optional email), so we clear precisely that counter — never a +// scan across keys. +export function ResetLockButton({ lock }: { lock: LoginLock }) { + const reset = useResetLoginLock(); + + async function onReset() { + try { + await reset.mutateAsync({ + type: lock.type, + ip: lock.ip, + email: lock.email, + }); + toast.success('Login lock cleared', { + description: + lock.type === 'ip_email' + ? `${lock.email} from ${lock.ip}` + : `IP ${lock.ip}`, + }); + } catch (err) { + const detail = err instanceof ApiError ? err.detail : String(err); + toast.error('Could not clear lock', { description: detail }); + } + } + + return ( + + ); +} diff --git a/server/dashboard/src/modules/login-locks/hooks.ts b/server/dashboard/src/modules/login-locks/hooks.ts new file mode 100644 index 0000000..a5e9eff --- /dev/null +++ b/server/dashboard/src/modules/login-locks/hooks.ts @@ -0,0 +1,27 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { api } from '@/api/client'; +import type { LoginLockListResponse, ResetLoginLockRequest } from '@/api/types'; + +export const loginLockKeys = { + all: ['login-locks'] as const, +}; + +// Locks self-heal as the limiter windows slide, so poll periodically to keep +// the table honest without the admin having to refresh by hand. +export function useLoginLocks() { + return useQuery({ + queryKey: loginLockKeys.all, + queryFn: ({ signal }) => + api.get('/admin/login-locks', { signal }), + refetchInterval: 15_000, + }); +} + +export function useResetLoginLock() { + const qc = useQueryClient(); + return useMutation({ + mutationFn: (body: ResetLoginLockRequest) => + api.post('/admin/login-locks/reset', body), + onSuccess: () => qc.invalidateQueries({ queryKey: loginLockKeys.all }), + }); +} diff --git a/server/dashboard/src/modules/login-locks/index.ts b/server/dashboard/src/modules/login-locks/index.ts new file mode 100644 index 0000000..2b4d405 --- /dev/null +++ b/server/dashboard/src/modules/login-locks/index.ts @@ -0,0 +1,13 @@ +import { ShieldAlert } from 'lucide-react'; +import type { Module } from '../types'; +import LoginLocksPage from './LoginLocksPage'; + +export const LoginLocksModule: Module = { + id: 'login-locks', + label: 'Login security', + icon: ShieldAlert, + path: '/login-locks', + element: LoginLocksPage, + requiredRole: 'admin', + weight: 45, +}; diff --git a/server/dashboard/src/modules/registry.ts b/server/dashboard/src/modules/registry.ts index 90bce6e..52c1d85 100644 --- a/server/dashboard/src/modules/registry.ts +++ b/server/dashboard/src/modules/registry.ts @@ -2,6 +2,7 @@ import { ApiKeysModule } from './api-keys'; import { GithubIntegrationModule } from './github-integration'; import { GroupsModule } from './groups'; import { HomeModule } from './home'; +import { LoginLocksModule } from './login-locks'; import { ManagedTunnelsModule } from './managed-tunnels'; import { ProjectsModule } from './projects'; import { SearchModule } from './search'; @@ -28,6 +29,7 @@ export const MODULES: Module[] = [ GithubIntegrationModule, ManagedTunnelsModule, UsersModule, + LoginLocksModule, GroupsModule, SettingsModule, ServerModule, diff --git a/server/internal/httpapi/loginlimiter.go b/server/internal/httpapi/loginlimiter.go index 5c72b32..3bff715 100644 --- a/server/internal/httpapi/loginlimiter.go +++ b/server/internal/httpapi/loginlimiter.go @@ -91,6 +91,87 @@ func (l *loginLimiter) reset(ip, email string) { delete(l.perKey, loginLimiterKey(ip, email)) } +// lockEntry describes one counter that is currently at or over its limit — +// i.e. a login attempt matching it right now would be rejected with 429. +type lockEntry struct { + Type string // "ip" or "ip_email" + IP string // source IP + Email string // lower-cased email; empty for a per-IP lock + Attempts int // attempts currently inside the window + Limit int // the window's cap + ExpiresAt time.Time // when the oldest attempt ages out and a slot frees +} + +// locks returns every counter that is currently blocking new attempts. It +// prunes expired timestamps as it walks (and drops emptied entries) so the +// maps do not grow without bound between logins — the same prune-on-touch +// discipline allow() applies. Callers get a point-in-time snapshot; the +// windows keep sliding, so an entry may self-heal a moment later. +func (l *loginLimiter) locks() []lockEntry { + l.mu.Lock() + defer l.mu.Unlock() + now := l.now() + out := []lockEntry{} + + for ip, ts := range l.perIP { + pruned := pruneOlder(ts, now.Add(-l.ipWindow)) + if len(pruned) == 0 { + delete(l.perIP, ip) + continue + } + l.perIP[ip] = pruned + if len(pruned) >= l.ipLimit { + out = append(out, lockEntry{ + Type: "ip", + IP: ip, + Attempts: len(pruned), + Limit: l.ipLimit, + ExpiresAt: pruned[0].Add(l.ipWindow), + }) + } + } + + for key, ts := range l.perKey { + pruned := pruneOlder(ts, now.Add(-l.keyWindow)) + if len(pruned) == 0 { + delete(l.perKey, key) + continue + } + l.perKey[key] = pruned + if len(pruned) >= l.keyLimit { + // Key is "ip|lower(email)"; IPv6 contains ':' but never '|', + // so a split on the first '|' recovers both halves cleanly. + ip, email, _ := strings.Cut(key, "|") + out = append(out, lockEntry{ + Type: "ip_email", + IP: ip, + Email: email, + Attempts: len(pruned), + Limit: l.keyLimit, + ExpiresAt: pruned[0].Add(l.keyWindow), + }) + } + } + return out +} + +// clearIP drops the per-IP counter, immediately lifting a per-IP lock. Used +// by the admin unlock endpoint; the normal post-login path never clears it. +func (l *loginLimiter) clearIP(ip string) { + l.mu.Lock() + defer l.mu.Unlock() + delete(l.perIP, ip) +} + +// clearKey drops the per-(IP, email) counter. Same effect as reset but named +// for the admin unlock path, which the admin invokes against a specific row +// surfaced by locks() rather than as a success-side effect. +func (l *loginLimiter) clearKey(ip, email string) { + l.mu.Lock() + defer l.mu.Unlock() + delete(l.perKey, loginLimiterKey(ip, email)) +} + func checkSlidingWindow(ts []time.Time, now time.Time, window time.Duration, limit int) ([]time.Time, time.Duration, bool) { pruned := pruneOlder(ts, now.Add(-window)) if len(pruned) >= limit { diff --git a/server/internal/httpapi/loginlocks_admin.go b/server/internal/httpapi/loginlocks_admin.go new file mode 100644 index 0000000..ca0e8bf --- /dev/null +++ b/server/internal/httpapi/loginlocks_admin.go @@ -0,0 +1,102 @@ +package httpapi + +import ( + "encoding/json" + "net/http" + "strings" + "time" +) + +// Admin visibility + control over the in-memory login rate limiter +// (loginlimiter.go). The limiter blocks brute-force login attempts per IP and +// per (IP, email); both counters self-heal as their sliding windows expire, +// but a legitimate user who fat-fingered their password from a shared office +// IP can be stuck for the full 15-minute window. These endpoints let an admin +// see who is currently locked and lift a specific lock early. +// +// State is per-process and wiped on restart, so this is an operational +// convenience, not a persisted store — there is nothing to reconcile across +// replicas (the server runs single-instance) and no audit trail beyond the +// structured request log. + +type loginLockPayload struct { + Type string `json:"type"` // "ip" or "ip_email" + IP string `json:"ip"` // source IP + Email string `json:"email,omitempty"` // present only for type "ip_email" + Attempts int `json:"attempts"` // attempts inside the window right now + Limit int `json:"limit"` // the cap that tripped the lock + ExpiresAt string `json:"expires_at"` // RFC3339 — when a slot next frees +} + +// ListLoginLocks — GET /api/v1/admin/login-locks (admin only). +// +// Returns every limiter counter currently at or over its threshold, i.e. the +// IPs and (IP, email) pairs a login would be rejected for right now with 429. +func (s *Server) ListLoginLocks(w http.ResponseWriter, r *http.Request) { + if _, ok := s.mustBeAdmin(w, r); !ok { + return + } + locks := []loginLockPayload{} + if s.loginLimiter != nil { + for _, e := range s.loginLimiter.locks() { + locks = append(locks, loginLockPayload{ + Type: e.Type, + IP: e.IP, + Email: e.Email, + Attempts: e.Attempts, + Limit: e.Limit, + ExpiresAt: e.ExpiresAt.UTC().Format(time.RFC3339), + }) + } + } + writeJSON(w, http.StatusOK, map[string]any{ + "locks": locks, + "total": len(locks), + }) +} + +// ResetLoginLock — POST /api/v1/admin/login-locks/reset (admin only). +// +// Clears one counter surfaced by ListLoginLocks. `type` selects the map: +// "ip" clears the per-IP horizontal-sweep counter; "ip_email" clears the +// per-(IP, email) counter for a single account. The admin picks the exact row +// to clear from the list, so we never guess across keys (clearing every IP +// for an email would need a map scan and could lift more than intended). +// Idempotent — clearing a key that is no longer locked is a no-op 204. +func (s *Server) ResetLoginLock(w http.ResponseWriter, r *http.Request) { + if _, ok := s.mustBeAdmin(w, r); !ok { + return + } + var body struct { + Type string `json:"type"` + IP string `json:"ip"` + Email string `json:"email"` + } + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + writeError(w, http.StatusUnprocessableEntity, "invalid JSON body") + return + } + body.IP = strings.TrimSpace(body.IP) + if body.IP == "" { + writeError(w, http.StatusUnprocessableEntity, "ip is required") + return + } + if s.loginLimiter == nil { + w.WriteHeader(http.StatusNoContent) + return + } + switch body.Type { + case "ip": + s.loginLimiter.clearIP(body.IP) + case "ip_email": + if strings.TrimSpace(body.Email) == "" { + writeError(w, http.StatusUnprocessableEntity, "email is required for type ip_email") + return + } + s.loginLimiter.clearKey(body.IP, body.Email) + default: + writeError(w, http.StatusUnprocessableEntity, `type must be "ip" or "ip_email"`) + return + } + w.WriteHeader(http.StatusNoContent) +} diff --git a/server/internal/httpapi/loginlocks_admin_test.go b/server/internal/httpapi/loginlocks_admin_test.go new file mode 100644 index 0000000..495962b --- /dev/null +++ b/server/internal/httpapi/loginlocks_admin_test.go @@ -0,0 +1,141 @@ +package httpapi + +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/dvcdsys/code-index/server/internal/users" +) + +// loginLocksRR issues GET /api/v1/admin/login-locks as the given session. +func loginLocksRR(t *testing.T, router http.Handler, cookie string) *httptest.ResponseRecorder { + t.Helper() + req := withCookie(httptest.NewRequest(http.MethodGet, "/api/v1/admin/login-locks", nil), cookie) + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + return rr +} + +// resetLoginLockRR issues POST /api/v1/admin/login-locks/reset with body. +func resetLoginLockRR(t *testing.T, router http.Handler, cookie string, body map[string]string) *httptest.ResponseRecorder { + t.Helper() + raw, _ := json.Marshal(body) + req := withCookie(httptest.NewRequest(http.MethodPost, "/api/v1/admin/login-locks/reset", bytes.NewReader(raw)), cookie) + req.Header.Set("Content-Type", "application/json") + rr := httptest.NewRecorder() + router.ServeHTTP(rr, req) + return rr +} + +type loginLockListBody struct { + Locks []struct { + Type string `json:"type"` + IP string `json:"ip"` + Email string `json:"email"` + Attempts int `json:"attempts"` + Limit int `json:"limit"` + } `json:"locks"` + Total int `json:"total"` +} + +func TestLoginLocks_AdminOnly(t *testing.T) { + f := newAuthFixture(t) + + if _, err := f.Deps.Users.Create(context.Background(), "viewer@example.com", "viewerpass1", users.RoleUser, false); err != nil { + t.Fatalf("seed viewer: %v", err) + } + viewerCookie := sessionCookie(loginRR(t, f.Router, "viewer@example.com", "viewerpass1")) + + if rr := loginLocksRR(t, f.Router, viewerCookie); rr.Code != http.StatusForbidden { + t.Errorf("viewer GET login-locks status = %d, want 403", rr.Code) + } + rr := resetLoginLockRR(t, f.Router, viewerCookie, map[string]string{"type": "ip", "ip": "1.2.3.4"}) + if rr.Code != http.StatusForbidden { + t.Errorf("viewer reset status = %d, want 403", rr.Code) + } +} + +func TestLoginLocks_ListAndReset(t *testing.T) { + f := newAuthFixture(t) + adminCookie := sessionCookie(loginRR(t, f.Router, "admin@example.com", "secret-password")) + + // Drive the per-(IP, email) counter to its limit with bad passwords. The + // default httptest RemoteAddr is 192.0.2.1, so every attempt shares one IP. + for range 5 { + if rr := loginRR(t, f.Router, "admin@example.com", "WRONG"); rr.Code != http.StatusUnauthorized { + t.Fatalf("warmup attempt status = %d, want 401", rr.Code) + } + } + // The lock is now active: a 6th attempt (even with the right password) 429s. + if rr := loginRR(t, f.Router, "admin@example.com", "secret-password"); rr.Code != http.StatusTooManyRequests { + t.Fatalf("post-limit status = %d, want 429", rr.Code) + } + + // The admin can see exactly one ip_email lock for that IP/email. + listRR := loginLocksRR(t, f.Router, adminCookie) + if listRR.Code != http.StatusOK { + t.Fatalf("list status = %d (body=%s)", listRR.Code, listRR.Body.String()) + } + var list loginLockListBody + if err := json.Unmarshal(listRR.Body.Bytes(), &list); err != nil { + t.Fatalf("decode list: %v", err) + } + if list.Total != 1 || len(list.Locks) != 1 { + t.Fatalf("total = %d, locks = %d, want 1/1 (body=%s)", list.Total, len(list.Locks), listRR.Body.String()) + } + lock := list.Locks[0] + if lock.Type != "ip_email" || lock.IP != "192.0.2.1" || lock.Email != "admin@example.com" { + t.Errorf("lock = %+v, want type ip_email ip 192.0.2.1 email admin@example.com", lock) + } + if lock.Attempts < lock.Limit { + t.Errorf("attempts %d < limit %d — should be at or over limit", lock.Attempts, lock.Limit) + } + + // Admin clears that exact row. + if rr := resetLoginLockRR(t, f.Router, adminCookie, map[string]string{ + "type": "ip_email", "ip": "192.0.2.1", "email": "admin@example.com", + }); rr.Code != http.StatusNoContent { + t.Fatalf("reset status = %d (body=%s), want 204", rr.Code, rr.Body.String()) + } + + // The lock is gone from the list and login is no longer throttled (a wrong + // password now reaches the authenticator and returns 401, not 429). + if rr := loginLocksRR(t, f.Router, adminCookie); rr.Code == http.StatusOK { + var after loginLockListBody + _ = json.Unmarshal(rr.Body.Bytes(), &after) + if after.Total != 0 { + t.Errorf("post-reset total = %d, want 0", after.Total) + } + } + if rr := loginRR(t, f.Router, "admin@example.com", "WRONG"); rr.Code != http.StatusUnauthorized { + t.Errorf("post-reset login status = %d, want 401 (limiter cleared)", rr.Code) + } +} + +func TestLoginLocks_ResetValidation(t *testing.T) { + f := newAuthFixture(t) + adminCookie := sessionCookie(loginRR(t, f.Router, "admin@example.com", "secret-password")) + + cases := []struct { + name string + body map[string]string + want int + }{ + {"missing ip", map[string]string{"type": "ip"}, http.StatusUnprocessableEntity}, + {"bad type", map[string]string{"type": "nonsense", "ip": "1.2.3.4"}, http.StatusUnprocessableEntity}, + {"ip_email without email", map[string]string{"type": "ip_email", "ip": "1.2.3.4"}, http.StatusUnprocessableEntity}, + {"ip ok (idempotent no-op)", map[string]string{"type": "ip", "ip": "9.9.9.9"}, http.StatusNoContent}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + rr := resetLoginLockRR(t, f.Router, adminCookie, tc.body) + if rr.Code != tc.want { + t.Errorf("status = %d, want %d (body=%s)", rr.Code, tc.want, rr.Body.String()) + } + }) + } +} diff --git a/server/internal/httpapi/openapi/openapi.gen.go b/server/internal/httpapi/openapi/openapi.gen.go index c35d4c1..875ce96 100644 --- a/server/internal/httpapi/openapi/openapi.gen.go +++ b/server/internal/httpapi/openapi/openapi.gen.go @@ -305,6 +305,24 @@ func (e JobStatus) Valid() bool { } } +// Defines values for LoginLockType. +const ( + LoginLockTypeIp LoginLockType = "ip" + LoginLockTypeIpEmail LoginLockType = "ip_email" +) + +// Valid indicates whether the value is a known member of the LoginLockType enum. +func (e LoginLockType) Valid() bool { + switch e { + case LoginLockTypeIp: + return true + case LoginLockTypeIpEmail: + return true + default: + return false + } +} + // Defines values for MeResponseAuthMethod. const ( MeResponseAuthMethodApiKey MeResponseAuthMethod = "api_key" @@ -398,6 +416,24 @@ func (e ReindexEnqueuedResponseStatus) Valid() bool { } } +// Defines values for ResetLoginLockRequestType. +const ( + ResetLoginLockRequestTypeIp ResetLoginLockRequestType = "ip" + ResetLoginLockRequestTypeIpEmail ResetLoginLockRequestType = "ip_email" +) + +// Valid indicates whether the value is a known member of the ResetLoginLockRequestType enum. +func (e ResetLoginLockRequestType) Valid() bool { + switch e { + case ResetLoginLockRequestTypeIp: + return true + case ResetLoginLockRequestTypeIpEmail: + return true + default: + return false + } +} + // Defines values for RuntimeConfigSource. const ( Db RuntimeConfigSource = "db" @@ -1538,6 +1574,38 @@ type LinkProjectRequest struct { ProjectHash string `json:"project_hash"` } +// LoginLock defines model for LoginLock. +type LoginLock struct { + // Attempts Attempts currently inside the sliding window. + Attempts int `json:"attempts"` + + // Email Lower-cased email; present only for type `ip_email`. + Email *string `json:"email,omitempty"` + + // ExpiresAt RFC3339 — when the oldest attempt ages out and a slot frees. + ExpiresAt time.Time `json:"expires_at"` + + // Ip Source IP the lock is keyed on. + Ip string `json:"ip"` + + // Limit The cap that tripped the lock. + Limit int `json:"limit"` + + // Type `ip` — the per-IP horizontal-sweep counter (many emails from one + // source). `ip_email` — the per-(IP, email) counter for one account. + Type LoginLockType `json:"type"` +} + +// LoginLockType `ip` — the per-IP horizontal-sweep counter (many emails from one +// source). `ip_email` — the per-(IP, email) counter for one account. +type LoginLockType string + +// LoginLockListResponse defines model for LoginLockListResponse. +type LoginLockListResponse struct { + Locks []LoginLock `json:"locks"` + Total int `json:"total"` +} + // LoginRequest defines model for LoginRequest. type LoginRequest struct { Email openapi_types.Email `json:"email"` @@ -1753,6 +1821,21 @@ type ReindexEnqueuedResponseMode string // ReindexEnqueuedResponseStatus defines model for ReindexEnqueuedResponse.Status. type ReindexEnqueuedResponseStatus string +// ResetLoginLockRequest defines model for ResetLoginLockRequest. +type ResetLoginLockRequest struct { + // Email Required when `type` is `ip_email`; ignored otherwise. + Email *string `json:"email,omitempty"` + + // Ip Source IP of the lock to clear. + Ip string `json:"ip"` + + // Type Which counter to clear — matches the `type` from the list. + Type ResetLoginLockRequestType `json:"type"` +} + +// ResetLoginLockRequestType Which counter to clear — matches the `type` from the list. +type ResetLoginLockRequestType string + // ResetUserPasswordRequest defines model for ResetUserPasswordRequest. type ResetUserPasswordRequest struct { // NewPassword One-time password the user must change on next login. @@ -2604,6 +2687,9 @@ type SwitchEmbeddingProviderJSONRequestBody = SwitchEmbeddingProviderRequest // TestEmbeddingProviderJSONRequestBody defines body for TestEmbeddingProvider for application/json ContentType. type TestEmbeddingProviderJSONRequestBody TestEmbeddingProviderJSONBody +// ResetLoginLockJSONRequestBody defines body for ResetLoginLock for application/json ContentType. +type ResetLoginLockJSONRequestBody = ResetLoginLockRequest + // PutRuntimeConfigJSONRequestBody defines body for PutRuntimeConfig for application/json ContentType. type PutRuntimeConfigJSONRequestBody = RuntimeConfigUpdate @@ -2711,6 +2797,12 @@ type ServerInterface interface { // Validate an embedding-provider config without persisting (admin only) // (POST /api/v1/admin/embedding-providers/{kind}/test) TestEmbeddingProvider(w http.ResponseWriter, r *http.Request, kind TestEmbeddingProviderParamsKind) + // List active login rate-limit locks (admin only) + // (GET /api/v1/admin/login-locks) + ListLoginLocks(w http.ResponseWriter, r *http.Request) + // Clear a login rate-limit lock (admin only) + // (POST /api/v1/admin/login-locks/reset) + ResetLoginLock(w http.ResponseWriter, r *http.Request) // List GGUF model files cached on disk (admin only) // (GET /api/v1/admin/models) ListModels(w http.ResponseWriter, r *http.Request) @@ -3002,6 +3094,18 @@ func (_ Unimplemented) TestEmbeddingProvider(w http.ResponseWriter, r *http.Requ w.WriteHeader(http.StatusNotImplemented) } +// List active login rate-limit locks (admin only) +// (GET /api/v1/admin/login-locks) +func (_ Unimplemented) ListLoginLocks(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Clear a login rate-limit lock (admin only) +// (POST /api/v1/admin/login-locks/reset) +func (_ Unimplemented) ResetLoginLock(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + // List GGUF model files cached on disk (admin only) // (GET /api/v1/admin/models) func (_ Unimplemented) ListModels(w http.ResponseWriter, r *http.Request) { @@ -3625,6 +3729,46 @@ func (siw *ServerInterfaceWrapper) TestEmbeddingProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } +// ListLoginLocks operation middleware +func (siw *ServerInterfaceWrapper) ListLoginLocks(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListLoginLocks(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ResetLoginLock operation middleware +func (siw *ServerInterfaceWrapper) ResetLoginLock(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ResetLoginLock(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // ListModels operation middleware func (siw *ServerInterfaceWrapper) ListModels(w http.ResponseWriter, r *http.Request) { @@ -6358,6 +6502,12 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/api/v1/admin/embedding-providers/{kind}/test", wrapper.TestEmbeddingProvider) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/api/v1/admin/login-locks", wrapper.ListLoginLocks) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/api/v1/admin/login-locks/reset", wrapper.ResetLoginLock) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/api/v1/admin/models", wrapper.ListModels) }) @@ -6628,494 +6778,507 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", + "HQUfzk5MZYl8l9zHHz7+fwAAAP//", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, From f45647510aa724514f155c52e77a9817a7f7b308 Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 15:55:30 +0100 Subject: [PATCH 5/7] review: audit-log lock resets + delegate clearKey to reset 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 --- server/internal/httpapi/loginlimiter.go | 11 +++++------ server/internal/httpapi/loginlocks_admin.go | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/server/internal/httpapi/loginlimiter.go b/server/internal/httpapi/loginlimiter.go index 3bff715..0cee046 100644 --- a/server/internal/httpapi/loginlimiter.go +++ b/server/internal/httpapi/loginlimiter.go @@ -163,13 +163,12 @@ func (l *loginLimiter) clearIP(ip string) { delete(l.perIP, ip) } -// clearKey drops the per-(IP, email) counter. Same effect as reset but named -// for the admin unlock path, which the admin invokes against a specific row -// surfaced by locks() rather than as a success-side effect. +// clearKey drops the per-(IP, email) counter for the admin unlock path, which +// targets a specific row surfaced by locks() rather than reacting to a login +// success. It delegates to reset so the key-derivation logic lives in exactly +// one place — the only difference is the calling context, not the behaviour. func (l *loginLimiter) clearKey(ip, email string) { - l.mu.Lock() - defer l.mu.Unlock() - delete(l.perKey, loginLimiterKey(ip, email)) + l.reset(ip, email) } func checkSlidingWindow(ts []time.Time, now time.Time, window time.Duration, limit int) ([]time.Time, time.Duration, bool) { diff --git a/server/internal/httpapi/loginlocks_admin.go b/server/internal/httpapi/loginlocks_admin.go index ca0e8bf..c7f3e7a 100644 --- a/server/internal/httpapi/loginlocks_admin.go +++ b/server/internal/httpapi/loginlocks_admin.go @@ -64,7 +64,8 @@ func (s *Server) ListLoginLocks(w http.ResponseWriter, r *http.Request) { // for an email would need a map scan and could lift more than intended). // Idempotent — clearing a key that is no longer locked is a no-op 204. func (s *Server) ResetLoginLock(w http.ResponseWriter, r *http.Request) { - if _, ok := s.mustBeAdmin(w, r); !ok { + ac, ok := s.mustBeAdmin(w, r) + if !ok { return } var body struct { @@ -98,5 +99,20 @@ func (s *Server) ResetLoginLock(w http.ResponseWriter, r *http.Request) { writeError(w, http.StatusUnprocessableEntity, `type must be "ip" or "ip_email"`) return } + // Clearing a lock weakens the brute-force defence, so record who did it + // to what, in an explicit audit line — not only the generic request log. + if s.Deps.Logger != nil { + actorID, actorEmail := "", "" + if ac != nil { + actorID, actorEmail = ac.User.ID, ac.User.Email + } + s.Deps.Logger.Info("admin cleared login rate-limit lock", + "actor_id", actorID, + "actor_email", actorEmail, + "lock_type", body.Type, + "lock_ip", body.IP, + "lock_email", body.Email, + ) + } w.WriteHeader(http.StatusNoContent) } From ef93af5d5c5ac3541abb4485a55d3e00deb38689 Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 17:31:53 +0100 Subject: [PATCH 6/7] feat(chunker): add Solidity language support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- cli/internal/discovery/language.go | 1 + server/internal/chunker/chunker.go | 9 ++++ server/internal/chunker/chunker_test.go | 51 +++++++++++++++++++ server/internal/langdetect/langdetect.go | 43 ++++++++-------- server/internal/langdetect/langdetect_test.go | 3 +- 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/cli/internal/discovery/language.go b/cli/internal/discovery/language.go index ac6e91f..951e4be 100644 --- a/cli/internal/discovery/language.go +++ b/cli/internal/discovery/language.go @@ -27,6 +27,7 @@ var ExtensionMap = map[string]string{ ".swift": "swift", ".kt": "kotlin", ".scala": "scala", + ".sol": "solidity", ".r": "r", ".lua": "lua", ".sh": "bash", diff --git a/server/internal/chunker/chunker.go b/server/internal/chunker/chunker.go index b5e34a2..f8768b0 100644 --- a/server/internal/chunker/chunker.go +++ b/server/internal/chunker/chunker.go @@ -432,6 +432,15 @@ func defaultRegistry() map[string]languageEntry { }, identifiers: idID("type_identifier"), }, + "solidity": { + factory: grammars.SolidityLanguage, + nodes: map[string][]string{ + "function": {"function_definition", "modifier_definition", "constructor_definition", "fallback_receive_definition"}, + "class": {"contract_declaration", "library_declaration"}, + "type": {"interface_declaration", "struct_declaration", "enum_declaration", "event_definition"}, + }, + identifiers: idID(), + }, } } diff --git a/server/internal/chunker/chunker_test.go b/server/internal/chunker/chunker_test.go index 15310c5..6287ee5 100644 --- a/server/internal/chunker/chunker_test.go +++ b/server/internal/chunker/chunker_test.go @@ -475,6 +475,56 @@ end } } +func TestChunkFile_Solidity(t *testing.T) { + src := `// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC20 { + function transfer(address to, uint256 amount) external returns (bool); +} + +contract Token is IERC20 { + enum State { Active, Paused } + + function transfer(address to, uint256 amount) external returns (bool) { + return true; + } +} +` + chunks, _, err := ChunkFile("Token.sol", src, "solidity", 0) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(chunks) == 0 { + t.Fatal("expected chunks from Solidity source") + } + counts := chunkTypeCounts(chunks) + if counts["class"] == 0 { + t.Errorf("expected a class chunk for the contract, got: %v", counts) + } + + var names []string + for _, c := range chunks { + if c.SymbolName != nil { + names = append(names, *c.SymbolName) + } + } + if len(names) == 0 { + t.Fatalf("expected named symbols from Solidity source, got none (chunk types: %v)", counts) + } + want := map[string]bool{"Token": false, "transfer": false} + for _, n := range names { + if _, ok := want[n]; ok { + want[n] = true + } + } + for sym, found := range want { + if !found { + t.Errorf("expected symbol %q among extracted symbols %v", sym, names) + } + } +} + // --- Configure() filtering --- func TestConfigure_FilterToSubset(t *testing.T) { @@ -605,6 +655,7 @@ func TestRegistry_NodeNamesMatchAST(t *testing.T) { "fortran": "subroutine s\nend subroutine\n", "haskell": "module M where\n\nf :: Int -> Int\nf x = x\n", "ocaml": "let f x = x\n", + "solidity": "contract C {\n function f() public {}\n}\n", } for lang, src := range fixtures { diff --git a/server/internal/langdetect/langdetect.go b/server/internal/langdetect/langdetect.go index 4568fdf..eef4755 100644 --- a/server/internal/langdetect/langdetect.go +++ b/server/internal/langdetect/langdetect.go @@ -12,29 +12,30 @@ import ( // Ported 1:1 from EXTENSION_MAP in api/app/core/language.py. var extensionMap = map[string]string{ // Systems / compiled - ".py": "python", - ".go": "go", - ".rs": "rust", - ".java": "java", - ".c": "c", - ".h": "c", - ".cpp": "cpp", - ".cc": "cpp", - ".cxx": "cpp", - ".hpp": "cpp", - ".cs": "c_sharp", + ".py": "python", + ".go": "go", + ".rs": "rust", + ".java": "java", + ".c": "c", + ".h": "c", + ".cpp": "cpp", + ".cc": "cpp", + ".cxx": "cpp", + ".hpp": "cpp", + ".cs": "c_sharp", ".swift": "swift", - ".kt": "kotlin", - ".kts": "kotlin", + ".kt": "kotlin", + ".kts": "kotlin", ".scala": "scala", - ".zig": "zig", - ".jl": "julia", - ".f90": "fortran", - ".f95": "fortran", - ".f03": "fortran", - ".f": "fortran", - ".m": "objc", - ".mm": "objc", + ".zig": "zig", + ".jl": "julia", + ".f90": "fortran", + ".f95": "fortran", + ".f03": "fortran", + ".f": "fortran", + ".m": "objc", + ".mm": "objc", + ".sol": "solidity", // Web / scripting ".ts": "typescript", ".tsx": "tsx", diff --git a/server/internal/langdetect/langdetect_test.go b/server/internal/langdetect/langdetect_test.go index 27e94f7..defe8fb 100644 --- a/server/internal/langdetect/langdetect_test.go +++ b/server/internal/langdetect/langdetect_test.go @@ -33,8 +33,9 @@ func TestDetect(t *testing.T) { {"README.md", "markdown"}, {"unknown.xyz", ""}, {"/some/path/to/main.go", "go"}, - {"script.R", "r"}, // uppercase .R + {"script.R", "r"}, // uppercase .R {"script.sh", "bash"}, + {"Token.sol", "solidity"}, {"build.gradle.kts", "kotlin"}, {"app.kts", "kotlin"}, } From 1eddfa3cdd0d4c1b1e9f922f20dde624640324c6 Mon Sep 17 00:00:00 2001 From: dvcdsys Date: Fri, 5 Jun 2026 17:39:46 +0100 Subject: [PATCH 7/7] review: update LANGUAGES.md, strict node-kind regression for Solidity 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 --- doc/LANGUAGES.md | 3 +- server/internal/chunker/chunker_test.go | 85 ++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/doc/LANGUAGES.md b/doc/LANGUAGES.md index 70ef5c4..69164af 100644 --- a/doc/LANGUAGES.md +++ b/doc/LANGUAGES.md @@ -2,7 +2,7 @@ cix uses tree-sitter (via `github.com/odvcencio/gotreesitter`) to extract semantic chunks (functions, classes, methods, types) from source code. Files in unsupported languages still get indexed via a sliding-window fallback — they're searchable, just without per-symbol granularity. -## Default language set (30) +## Default language set (31) | ID | gotreesitter factory | Function | Class | Method | Type | |---|---|:-:|:-:|:-:|:-:| @@ -36,6 +36,7 @@ cix uses tree-sitter (via `github.com/odvcencio/gotreesitter`) to extract semant | `fortran` | `FortranLanguage` | ✓ | ✓ | | | | `haskell` | `HaskellLanguage` | ✓ | | | ✓ | | `ocaml` | `OcamlLanguage` | ✓ | ✓ | | ✓ | +| `solidity` | `SolidityLanguage` | ✓ | ✓ | | ✓ | The exact AST node types per language live in `server/internal/chunker/chunker.go` (`defaultRegistry`). File-extension mapping lives in `server/internal/langdetect/langdetect.go`. diff --git a/server/internal/chunker/chunker_test.go b/server/internal/chunker/chunker_test.go index 6287ee5..78463f8 100644 --- a/server/internal/chunker/chunker_test.go +++ b/server/internal/chunker/chunker_test.go @@ -525,6 +525,74 @@ contract Token is IERC20 { } } +// TestRegistry_SolidityAllNodeKindsPresent is a stricter sibling to +// TestRegistry_NodeNamesMatchAST: the generic test passes if *any* one of a +// language's configured node types appears in the AST, which would let a +// grammar rename of e.g. `modifier_definition` slip through unnoticed. +// +// Solidity's registry entry advertises 10 node kinds. This test parses a +// contract that exercises every one of them and fails loudly if any single +// kind is missing from the AST — protecting downstream `cix def` / `cix refs` +// behavior for modifiers, events, constructors, and receive/fallback +// functions, which are easy to overlook in the broader smoke test. +func TestRegistry_SolidityAllNodeKindsPresent(t *testing.T) { + defer Configure(nil) + Configure(nil) + + src := `// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface I { function f() external; } +library L { function g() internal pure returns (uint) { return 1; } } +contract C { + struct S { uint x; } + enum E { A, B } + event Ev(uint x); + modifier m() { _; } + constructor() {} + receive() external payable {} + function f() public {} +} +` + + registryMu.RLock() + fn, ok := languageRegistry["solidity"] + nodes := languageNodes["solidity"] + registryMu.RUnlock() + if !ok { + t.Fatal("solidity not in registry") + } + if nodes == nil { + t.Fatal("solidity has no node map") + } + + grammar := fn() + if grammar == nil { + t.Fatal("nil solidity grammar") + } + + parser := sitter.NewParser(grammar) + tree, err := parser.Parse([]byte(src)) + if err != nil { + t.Fatalf("parse error: %v", err) + } + root := tree.RootNode() + if root == nil { + t.Fatal("nil root") + } + + seen := map[string]struct{}{} + collectNodeTypes(root, grammar, seen) + + for _, types := range nodes { + for _, ty := range types { + if _, found := seen[ty]; !found { + t.Errorf("configured Solidity node type %q not present in AST — grammar rename?", ty) + } + } + } +} + // --- Configure() filtering --- func TestConfigure_FilterToSubset(t *testing.T) { @@ -655,7 +723,22 @@ func TestRegistry_NodeNamesMatchAST(t *testing.T) { "fortran": "subroutine s\nend subroutine\n", "haskell": "module M where\n\nf :: Int -> Int\nf x = x\n", "ocaml": "let f x = x\n", - "solidity": "contract C {\n function f() public {}\n}\n", + // Covers every configured kind: contract_declaration, library_declaration, + // interface_declaration, struct_declaration, enum_declaration, event_definition, + // function_definition, modifier_definition, constructor_definition, + // fallback_receive_definition. Guards against grammar renames for any of them. + "solidity": "" + + "interface I { function f() external; }\n" + + "library L { function g() internal pure returns (uint) { return 1; } }\n" + + "contract C {\n" + + " struct S { uint x; }\n" + + " enum E { A, B }\n" + + " event Ev(uint x);\n" + + " modifier m() { _; }\n" + + " constructor() {}\n" + + " receive() external payable {}\n" + + " function f() public {}\n" + + "}\n", } for lang, src := range fixtures {