Files
sm-user-plugin/blacklist.go
Jakub Zych 4bf44fc6ea fix: logout revokes the session under serve: the jwt blacklist and GORM hooks are wired when the database is published
Boot runs before summer serve publishes the database, so the plugin's GORM
hooks, the Postgres jwt_blacklist store and its sweep now go through
lagoon.OnDatabase, and the jwt guard resolves the published store on every
request. A logged-out token is refused on jwt.auth, /fetch and /refresh.

The jwt guard reads the cookie names from classes.SessionCookieNames().
2026-10-22 22:29:59 +02:00

62 lines
1.6 KiB
Go

package user
import (
"context"
"time"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/bouncer"
)
var _ bouncer.BlacklistStore = (*appBlacklist)(nil)
// appBlacklist is the blacklist store the jwt guard is built with. The guard
// is built in Boot, which under summer serve runs before the database is
// published, so the store the plugin publishes on lagoon.Publish is resolved
// on every call. While none is published, no token counts as blacklisted and
// Add and Sweep do nothing. An appBlacklist must never be published as the
// app's bouncer.BlacklistStore: the lookup would then find itself.
type appBlacklist struct {
app *backpack.App
}
// store returns the published blacklist store, or nil when there is none
// (or the published value is an appBlacklist).
func (b *appBlacklist) store() bouncer.BlacklistStore {
if b == nil || b.app == nil {
return nil
}
s, ok := b.app.Lookup[bouncer.BlacklistStore]()
if !ok || s == nil {
return nil
}
if _, self := s.(*appBlacklist); self {
return nil
}
return s
}
func (b *appBlacklist) Add(ctx context.Context, jti string, expiresAt, validUntil time.Time) error {
s := b.store()
if s == nil {
return nil
}
return s.Add(ctx, jti, expiresAt, validUntil)
}
func (b *appBlacklist) IsBlacklisted(ctx context.Context, jti string) (bool, error) {
s := b.store()
if s == nil {
return false, nil
}
return s.IsBlacklisted(ctx, jti)
}
func (b *appBlacklist) Sweep(ctx context.Context, now time.Time) error {
s := b.store()
if s == nil {
return nil
}
return s.Sweep(ctx, now)
}