[bugfix] new token API issues (#4022)

* fix incorrect endpoint being registered for /token/{id}

* update the maximum page value for tokens endpoint to 100

* update the available tokens page options

* set a default limit of 25 to match the first available settings panel option

* ensure OnInvalidateToken() hook is called during token delete
This commit is contained in:
kim
2025-04-18 15:37:50 +00:00
committed by GitHub
parent 2fce027808
commit 14899733c8
4 changed files with 43 additions and 26 deletions

View File

@ -43,6 +43,6 @@ func New(processor *processing.Processor) *Module {
func (m *Module) Route(attachHandler func(method string, path string, f ...gin.HandlerFunc) gin.IRoutes) {
attachHandler(http.MethodGet, BasePath, m.TokensInfoGETHandler)
attachHandler(http.MethodGet, BasePathWithID, m.TokensInfoGETHandler)
attachHandler(http.MethodGet, BasePathWithID, m.TokenInfoGETHandler)
attachHandler(http.MethodPost, InvalidateTokenPath, m.TokenInvalidatePOSTHandler)
}

View File

@ -117,9 +117,9 @@ func (m *Module) TokensInfoGETHandler(c *gin.Context) {
}
page, errWithCode := paging.ParseIDPage(c,
0, // min limit
80, // max limit
20, // default limit
0, // min limit
100, // max limit
25, // default limit
)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)

View File

@ -19,8 +19,10 @@ package bundb
import (
"context"
"errors"
"slices"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/paging"
@ -409,8 +411,11 @@ func (a *applicationDB) UpdateToken(ctx context.Context, token *gtsmodel.Token,
}
func (a *applicationDB) DeleteTokenByID(ctx context.Context, id string) error {
var token gtsmodel.Token
token.ID = id
_, err := a.db.NewDelete().
Table("tokens").
Model(&token).
Where("? = ?", bun.Ident("id"), id).
Exec(ctx)
if err != nil {
@ -418,68 +423,79 @@ func (a *applicationDB) DeleteTokenByID(ctx context.Context, id string) error {
}
a.state.Caches.DB.Token.Invalidate("ID", id)
a.state.Caches.OnInvalidateToken(&token)
return nil
}
func (a *applicationDB) DeleteTokenByCode(ctx context.Context, code string) error {
var token gtsmodel.Token
_, err := a.db.NewDelete().
Table("tokens").
Model(&token).
Where("? = ?", bun.Ident("code"), code).
Returning("?", bun.Ident("id")).
Exec(ctx)
if err != nil {
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return err
}
a.state.Caches.DB.Token.Invalidate("Code", code)
a.state.Caches.OnInvalidateToken(&token)
return nil
}
func (a *applicationDB) DeleteTokenByAccess(ctx context.Context, access string) error {
var token gtsmodel.Token
_, err := a.db.NewDelete().
Table("tokens").
Model(&token).
Where("? = ?", bun.Ident("access"), access).
Returning("?", bun.Ident("id")).
Exec(ctx)
if err != nil {
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return err
}
a.state.Caches.DB.Token.Invalidate("Access", access)
a.state.Caches.OnInvalidateToken(&token)
return nil
}
func (a *applicationDB) DeleteTokenByRefresh(ctx context.Context, refresh string) error {
var token gtsmodel.Token
_, err := a.db.NewDelete().
Table("tokens").
Model(&token).
Where("? = ?", bun.Ident("refresh"), refresh).
Returning("?", bun.Ident("id")).
Exec(ctx)
if err != nil {
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return err
}
a.state.Caches.DB.Token.Invalidate("Refresh", refresh)
a.state.Caches.OnInvalidateToken(&token)
return nil
}
func (a *applicationDB) DeleteTokensByClientID(ctx context.Context, clientID string) error {
var tokens []*gtsmodel.Token
// Delete tokens owned by
// clientID and gather token IDs.
var tokenIDs []string
if _, err := a.db.
NewDelete().
Table("tokens").
if _, err := a.db.NewDelete().
Model(&tokens).
Where("? = ?", bun.Ident("client_id"), clientID).
Returning("id").
Exec(ctx, &tokenIDs); err != nil {
Returning("?", bun.Ident("id")).
Exec(ctx); err != nil && !errors.Is(err, db.ErrNoEntries) {
return err
}
if len(tokenIDs) == 0 {
// Nothing was deleted,
// nothing to invalidate.
return nil
// Invalidate all deleted tokens.
for _, token := range tokens {
a.state.Caches.DB.Token.Invalidate("ID", token.ID)
a.state.Caches.OnInvalidateToken(token)
}
// Invalidate all deleted tokens.
a.state.Caches.DB.Token.InvalidateIDs("ID", tokenIDs)
return nil
}

View File

@ -36,7 +36,7 @@ export default function TokensSearchForm() {
// Populate search form using values from
// urlQueryParams, to allow paging.
const form = {
limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "20" })
limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "25" })
};
// On mount, trigger search.
@ -93,9 +93,10 @@ export default function TokensSearchForm() {
label="Items per page"
options={
<>
<option value="20">20</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="0">No limit / show all</option>
<option value="75">75</option>
<option value="100">100</option>
</>
}
></Select>