fix: one-time-access-token CLI fails with "RuntimePSKs is required" (#1637)

This commit is contained in:
Salvatore Catroppa
2026-07-31 00:09:10 +02:00
committed by GitHub
parent 27199f61d4
commit 8815e5968b
2 changed files with 23 additions and 7 deletions
+11 -6
View File
@@ -115,27 +115,32 @@ func (o *NewActorsOpts) getPSK() ([]byte, error) {
// NewActorStateStore creates a minimal actor host that can read and write actor state directly, without joining the cluster or binding a network port.
// It's meant for short-lived contexts such as CLI commands that need to persist actor state (for example, one-time access tokens) without running the full actor host.
// The returned host must NOT be Run(): only direct state operations (Get/Set/Delete on state) are supported, and they require the actor state tables to already exist, which is the case whenever the server has run at least once against this database.
func NewActorStateStore(db *gorm.DB, pg *pgxpool.Pool) (*local.Host, error) {
opts := &NewActorsOpts{DB: db, Postgres: pg}
if pg == nil {
sqlDB, err := db.DB()
func NewActorStateStore(o NewActorsOpts) (*local.Host, error) {
if o.Postgres == nil {
sqlDB, err := o.DB.DB()
if err != nil {
return nil, fmt.Errorf("failed to get *sql.DB connection from Gorm: %w", err)
}
opts.SQLite = sqlDB
o.SQLite = sqlDB
}
providerOpt, err := opts.getProviderOption()
providerOpt, err := o.getProviderOption()
if err != nil {
return nil, err
}
psk, err := o.getPSK()
if err != nil {
return nil, fmt.Errorf("failed to derive PSK: %w", err)
}
return local.NewHost(
// The address is required by the host but never bound, since the host is not Run
local.WithAddress("127.0.0.1:1"),
local.WithLogger(slog.Default().With("scope", "actor-state-store")),
// The health-check deadline only needs to exceed the provider's query timeout to pass validation
local.WithHostHealthCheckDeadline(90*time.Second),
local.WithRuntimePSKs(psk),
providerOpt,
)
}
+12 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/pocket-id/pocket-id/backend/internal/bootstrap"
"github.com/pocket-id/pocket-id/backend/internal/common"
"github.com/pocket-id/pocket-id/backend/internal/instanceid"
"github.com/pocket-id/pocket-id/backend/internal/model"
"github.com/pocket-id/pocket-id/backend/internal/onetimeaccess"
)
@@ -47,9 +48,19 @@ var oneTimeAccessTokenCmd = &cobra.Command{
return errors.New("invalid user loaded: ID is empty")
}
instanceID, err := instanceid.Load(cmd.Context(), db)
if err != nil {
return err
}
// One-time access tokens are stored in the actor state store
// The CLI doesn't run the full actor host, so it uses a minimal state store to persist the token directly
actorStore, err := bootstrap.NewActorStateStore(db, pg)
actorStore, err := bootstrap.NewActorStateStore(bootstrap.NewActorsOpts{
DB: db,
Postgres: pg,
EnvConfig: &common.EnvConfig,
InstanceID: instanceID,
})
if err != nil {
return fmt.Errorf("failed to initialize the actor state store: %w", err)
}