Cap refresh chain lifetime via RefreshChainAbsoluteTTL
Sessions had an absolute cap (created_at + SessionAbsoluteTTL) but the JWT path only had per-token TTL on the refresh row, letting a well-behaved client refresh indefinitely. Add chain_started_at to authkit_tokens, copy it forward on every rotation, and reject in RefreshJWT when now > chainStartedAt + RefreshChainAbsoluteTTL. Default 30d, mirroring SessionAbsoluteTTL. Schema, verifier, queries, model, and integration test updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d3c5367492
commit
ca5525d4bd
11 changed files with 129 additions and 53 deletions
|
|
@ -52,17 +52,18 @@ func freshAuth(t *testing.T) *Auth {
|
|||
DB: db,
|
||||
Hasher: hasher.NewArgon2id(hasher.DefaultArgon2idParams(), nil),
|
||||
}, Config{
|
||||
JWTSecret: []byte("integration-secret-thirty-two!!!"),
|
||||
JWTIssuer: "authkit-int",
|
||||
AccessTokenTTL: 2 * time.Minute,
|
||||
RefreshTokenTTL: time.Hour,
|
||||
SessionIdleTTL: time.Hour,
|
||||
SessionAbsoluteTTL: 24 * time.Hour,
|
||||
EmailVerifyTTL: time.Hour,
|
||||
PasswordResetTTL: time.Hour,
|
||||
MagicLinkTTL: time.Minute,
|
||||
EmailOTPTTL: time.Minute,
|
||||
EmailOTPMaxAttempts: 3,
|
||||
JWTSecret: []byte("integration-secret-thirty-two!!!"),
|
||||
JWTIssuer: "authkit-int",
|
||||
AccessTokenTTL: 2 * time.Minute,
|
||||
RefreshTokenTTL: 48 * time.Hour,
|
||||
RefreshChainAbsoluteTTL: 24 * time.Hour,
|
||||
SessionIdleTTL: time.Hour,
|
||||
SessionAbsoluteTTL: 24 * time.Hour,
|
||||
EmailVerifyTTL: time.Hour,
|
||||
PasswordResetTTL: time.Hour,
|
||||
MagicLinkTTL: time.Minute,
|
||||
EmailOTPTTL: time.Minute,
|
||||
EmailOTPMaxAttempts: 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("authkit.New: %v", err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue