package api import ( "net/http" "git.fabledsword.com/bvandeusen/minstrel/internal/apierror" "git.fabledsword.com/bvandeusen/minstrel/internal/audit" "git.fabledsword.com/bvandeusen/minstrel/internal/auth" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) type apiTokenResp struct { APIToken string `json:"api_token"` } // handleRegenerateMyAPIToken implements POST /api/me/api-token. // // Only the key's hash is stored, so this response is the one time the key // can be read. There is deliberately no GET: a key that has been shown and // lost is replaced, not looked up. func (h *handlers) handleRegenerateMyAPIToken(w http.ResponseWriter, r *http.Request) { user, ok := requireUser(w, r) if !ok { return } newToken, err := auth.MintSessionToken() if err != nil { h.logger.Error("regenerate api token: mint failed", "err", err) writeErr(w, apierror.Internal(err)) return } q := dbq.New(h.pool) if err := q.RegenerateApiToken(r.Context(), dbq.RegenerateApiTokenParams{ ID: user.ID, ApiTokenHash: auth.HashAPIToken(newToken), }); err != nil { h.logger.Error("regenerate api token: update failed", "err", err) writeErr(w, apierror.Internal(err)) return } audit.WriteOrLog(r.Context(), h.pool, h.logger, user.ID, user.ID, audit.ActionTokenRegenerate, nil) writeJSON(w, http.StatusOK, apiTokenResp{APIToken: newToken}) }