Skip to content

feat: add refresh callback to update token claims during refresh - #319

Open
swalker326 wants to merge 2 commits into
anomalyco:masterfrom
swalker326:fix/275
Open

feat: add refresh callback to update token claims during refresh#319
swalker326 wants to merge 2 commits into
anomalyco:masterfrom
swalker326:fix/275

Conversation

@swalker326

Copy link
Copy Markdown

Summary

Adds an optional refresh() callback to the issuer configuration that allows updating token properties during refresh operations without requiring users to re-authenticate.

This addresses issue #275 where dynamic user attributes (permissions, roles, profile data) stored in external sources like Redis or databases could not be updated during token refresh.

Changes

  • New refresh callback in IssuerInput interface - Optional callback that mirrors the success() callback pattern
  • Integration with token refresh flow - The refresh callback is invoked during refresh_token grant type operations
  • Backward compatible - When no refresh callback is provided, the original behavior of using cached properties is maintained
  • Comprehensive test coverage - Added test to verify refresh callback updates token properties correctly

Usage Example

issuer({
  success: async (ctx, value) => {
    const user = await db.findUser(value.email)
    const permissions = await redis.get(`permissions:${user.id}`)
    return ctx.subject("user", {
      id: user.id,
      email: user.email,
      permissions,
    })
  },

  // NEW: Refresh callback to update dynamic attributes
  refresh: async (ctx, value) => {
    // Re-fetch permissions on every refresh
    const permissions = await redis.get(`permissions:${value.properties.id}`)
    return ctx.subject("user", {
      ...value.properties,
      permissions, // Updated value!
    })
  },
})

Test Plan

- All existing tests pass (28/28)
- New test verifies refresh callback is invoked with correct payload
- New test verifies updated properties appear in refreshed tokens
- TypeScript compilation passes with no errors
- Backward compatibility verified - existing behavior unchanged when callback not provided

Related Issues

Fixes #275

Add optional refresh() callback to IssuerInput that allows updating
token properties during refresh operations without re-authentication.
This enables dynamic user attributes (permissions, roles, etc.) to be
refreshed from external sources like Redis or databases.

When the refresh callback is not provided, the original behavior of
using cached properties is maintained for backward compatibility.

Fixes anomalyco#275
andrewmd5 added a commit to 6over3/openauth that referenced this pull request Apr 26, 2026
Cherry-picks from anomalyco/openauth open PRs:

- anomalyco#305 spec-compliant redirect_uri (require `allow`, RFC 9700 §4.1)
- anomalyco#309 client-side JWT audience validation (RFC 7519 §4.1.3)
- anomalyco#318 token_type=Bearer on token responses
- anomalyco#304 implicit-flow no refresh token (RFC 6749 §4.2.2)
- anomalyco#258 iat claim (deterministic across reuse interval)
- anomalyco#323 fix Cloudflare KV runaway key creation under eventual consistency
- anomalyco#315 loosen CloudflareStorageOptions to structural KV shape
- anomalyco#319 refresh callback hook
- anomalyco#156 OAuth2 scope (authorize, token, well-known, JWT claim)
- anomalyco#236 basePath option
- anomalyco#278 allowRegistration / userExists / allowClaims
- anomalyco#221 configurable Select copy
- anomalyco#310 anomalyco#308 code UI resend action + sendCode types
- anomalyco#325 example actions: keep session when access token still valid
- anomalyco#317 add MIT license to package.json

Bump 0.3.12 -> 0.4.0 (breaking: `allow` is now required).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant