Repository navigation
Fix(storage): separate access and refresh token expiries
The previous single-expiry model gave both tokens the same lifetime,
which meant a refresh token was useless as soon as the access token
expired — the exact opposite of what a refresh token is for.
Changes:
- storage.Token: ExpiresAt split into AccessExpiresAt + RefreshExpiresAt
- models.OAuthToken: same two columns, both indexed
- Ent schema regenerated with the two fields
- IsExpired() replaced by IsAccessTokenExpired() / IsRefreshTokenExpired()
- Repository.DeleteExpiredTokens added for background cleanup
- Passport.CleanupExpiredTokens passthrough
- Regression test: TestRefreshTokenOutlivesAccessToken
Fixes a bug where RefreshToken would fail after the access token's
expiry, logging the user out despite a valid refresh token.