Skip to content

Commit 135a7e5

Browse files
committed
Ask Claude to rename token exchange callback return properties.
This seems easier to understand. (Transcript included in previous commit.)
1 parent 6e9808b commit 135a7e5

File tree

3 files changed

+54
-50
lines changed

3 files changed

+54
-50
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,12 @@ new OAuthProvider({
218218

219219
return {
220220
// Update the props stored in the access token
221-
tokenProps: {
221+
accessTokenProps: {
222222
...options.props,
223223
upstreamAccessToken: upstreamTokens.access_token
224224
},
225225
// Update the props stored in the grant (for future token refreshes)
226-
grantProps: {
226+
newProps: {
227227
...options.props,
228228
upstreamRefreshToken: upstreamTokens.refresh_token
229229
}
@@ -235,11 +235,11 @@ new OAuthProvider({
235235
const upstreamTokens = await refreshUpstreamToken(options.props.upstreamRefreshToken);
236236

237237
return {
238-
tokenProps: {
238+
accessTokenProps: {
239239
...options.props,
240240
upstreamAccessToken: upstreamTokens.access_token
241241
},
242-
grantProps: {
242+
newProps: {
243243
...options.props,
244244
upstreamRefreshToken: upstreamTokens.refresh_token || options.props.upstreamRefreshToken
245245
}
@@ -250,8 +250,9 @@ new OAuthProvider({
250250
```
251251

252252
The callback can:
253-
- Return both `tokenProps` and `grantProps` to update both
254-
- Return only `tokenProps` or `grantProps` to update just one
253+
- Return both `accessTokenProps` and `newProps` to update both
254+
- Return only `accessTokenProps` to update just the current access token
255+
- Return only `newProps` to update both the grant and access token (the access token inherits these props)
255256
- Return nothing to keep the original props unchanged
256257

257258
The `props` values are end-to-end encrypted, so they can safely contain sensitive information.

__tests__/oauth-provider.test.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,24 +1037,24 @@ describe('OAuthProvider', () => {
10371037
// Return different props based on the grant type
10381038
if (options.grantType === 'authorization_code') {
10391039
return {
1040-
tokenProps: {
1040+
accessTokenProps: {
10411041
...options.props,
10421042
tokenSpecific: true,
10431043
tokenUpdatedAt: 'auth_code_flow'
10441044
},
1045-
grantProps: {
1045+
newProps: {
10461046
...options.props,
10471047
grantUpdated: true
10481048
}
10491049
};
10501050
} else if (options.grantType === 'refresh_token') {
10511051
return {
1052-
tokenProps: {
1052+
accessTokenProps: {
10531053
...options.props,
10541054
tokenSpecific: true,
10551055
tokenUpdatedAt: 'refresh_token_flow'
10561056
},
1057-
grantProps: {
1057+
newProps: {
10581058
...options.props,
10591059
grantUpdated: true,
10601060
refreshCount: (options.props.refreshCount || 0) + 1
@@ -1305,17 +1305,17 @@ describe('OAuthProvider', () => {
13051305
});
13061306

13071307
it('should update token props during refresh when explicitly provided', async () => {
1308-
// Create a provider with a callback that returns both tokenProps and grantProps
1308+
// Create a provider with a callback that returns both accessTokenProps and newProps
13091309
// but with different values for each
13101310
const differentPropsCallback = async (options: any) => {
13111311
if (options.grantType === 'refresh_token') {
13121312
return {
1313-
tokenProps: {
1313+
accessTokenProps: {
13141314
...options.props,
13151315
refreshed: true,
13161316
tokenOnly: true
13171317
},
1318-
grantProps: {
1318+
newProps: {
13191319
...options.props,
13201320
grantUpdated: true
13211321
}
@@ -1416,19 +1416,19 @@ describe('OAuthProvider', () => {
14161416
expect(apiData.user).not.toHaveProperty('grantUpdated');
14171417
});
14181418

1419-
it('should handle callback that returns only tokenProps or only grantProps', async () => {
1420-
// Create a provider with a callback that returns only tokenProps for auth code
1421-
// and only grantProps for refresh token
1422-
// Note: With the enhanced implementation, when only grantProps is returned
1423-
// without tokenProps, the token props will inherit from grantProps
1424-
const tokenPropsOnlyCallback = async (options: any) => {
1419+
it('should handle callback that returns only accessTokenProps or only newProps', async () => {
1420+
// Create a provider with a callback that returns only accessTokenProps for auth code
1421+
// and only newProps for refresh token
1422+
// Note: With the enhanced implementation, when only newProps is returned
1423+
// without accessTokenProps, the token props will inherit from newProps
1424+
const propsCallback = async (options: any) => {
14251425
if (options.grantType === 'authorization_code') {
14261426
return {
1427-
tokenProps: { ...options.props, tokenOnly: true }
1427+
accessTokenProps: { ...options.props, tokenOnly: true }
14281428
};
14291429
} else if (options.grantType === 'refresh_token') {
14301430
return {
1431-
grantProps: { ...options.props, grantOnly: true }
1431+
newProps: { ...options.props, grantOnly: true }
14321432
};
14331433
}
14341434
};
@@ -1441,7 +1441,7 @@ describe('OAuthProvider', () => {
14411441
tokenEndpoint: '/oauth/token',
14421442
clientRegistrationEndpoint: '/oauth/register',
14431443
scopesSupported: ['read', 'write'],
1444-
tokenExchangeCallback: tokenPropsOnlyCallback
1444+
tokenExchangeCallback: propsCallback
14451445
});
14461446

14471447
// Create a client
@@ -1531,7 +1531,7 @@ describe('OAuthProvider', () => {
15311531
const api2Data = await api2Response.json();
15321532

15331533
// With the enhanced implementation, the token props now inherit from grant props
1534-
// when only grantProps is returned but tokenProps is not specified
1534+
// when only newProps is returned but accessTokenProps is not specified
15351535
expect(api2Data.user).toEqual({
15361536
userId: "test-user-123",
15371537
username: "TestUser",
@@ -1622,7 +1622,7 @@ describe('OAuthProvider', () => {
16221622
it('should correctly handle the previous refresh token when callback updates grant props', async () => {
16231623
// This test verifies fixes for two bugs:
16241624
// 1. previousRefreshTokenWrappedKey not being re-wrapped when grant props change
1625-
// 2. tokenProps not inheriting from grantProps when only grantProps is returned
1625+
// 2. accessTokenProps not inheriting from newProps when only newProps is returned
16261626
let callCount = 0;
16271627
const propUpdatingCallback = async (options: any) => {
16281628
callCount++;
@@ -1632,11 +1632,11 @@ describe('OAuthProvider', () => {
16321632
updatedCount: (options.props.updatedCount || 0) + 1
16331633
};
16341634

1635-
// Only return grantProps to test that tokenProps will inherit from it
1635+
// Only return newProps to test that accessTokenProps will inherit from it
16361636
return {
1637-
// Return new grant props to trigger the re-encryption with a new key
1638-
grantProps: updatedProps
1639-
// Intentionally not setting tokenProps to verify inheritance works
1637+
// Return new props to trigger the re-encryption with a new key
1638+
newProps: updatedProps
1639+
// Intentionally not setting accessTokenProps to verify inheritance works
16401640
};
16411641
}
16421642
return undefined;

src/oauth-provider.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,19 @@ type WorkerEntrypointWithFetch = WorkerEntrypoint & Pick<Required<WorkerEntrypoi
3737
*/
3838
export interface TokenExchangeCallbackResult {
3939
/**
40-
* New props to be stored with the access token.
41-
* If not provided, the original props will be used.
40+
* New props to be stored specifically with the access token.
41+
* If not provided but newProps is, the access token will use newProps.
42+
* If neither is provided, the original props will be used.
4243
*/
43-
tokenProps?: any;
44+
accessTokenProps?: any;
4445

4546
/**
4647
* New props to replace the props stored in the grant itself.
48+
* These props will be used for all future token refreshes.
49+
* If accessTokenProps is not provided, these props will also be used for the current access token.
4750
* If not provided, the original props will be used.
4851
*/
49-
grantProps?: any;
52+
newProps?: any;
5053
}
5154

5255
/**
@@ -1255,19 +1258,19 @@ class OAuthProviderImpl {
12551258

12561259
if (callbackResult) {
12571260
// Use the returned props if provided, otherwise keep the original props
1258-
if (callbackResult.grantProps) {
1259-
grantProps = callbackResult.grantProps;
1261+
if (callbackResult.newProps) {
1262+
grantProps = callbackResult.newProps;
12601263

1261-
// If tokenProps wasn't explicitly specified, use the updated grantProps for the token too
1262-
// This ensures token props are updated when only grant props are specified
1263-
if (!callbackResult.tokenProps) {
1264-
accessTokenProps = callbackResult.grantProps;
1264+
// If accessTokenProps wasn't explicitly specified, use the updated newProps for the token too
1265+
// This ensures token props are updated when only newProps are specified
1266+
if (!callbackResult.accessTokenProps) {
1267+
accessTokenProps = callbackResult.newProps;
12651268
}
12661269
}
12671270

1268-
// If tokenProps was explicitly specified, use those
1269-
if (callbackResult.tokenProps) {
1270-
accessTokenProps = callbackResult.tokenProps;
1271+
// If accessTokenProps was explicitly specified, use those
1272+
if (callbackResult.accessTokenProps) {
1273+
accessTokenProps = callbackResult.accessTokenProps;
12711274
}
12721275
}
12731276

@@ -1461,20 +1464,20 @@ class OAuthProviderImpl {
14611464
let grantPropsChanged = false;
14621465
if (callbackResult) {
14631466
// Use the returned props if provided, otherwise keep the original props
1464-
if (callbackResult.grantProps) {
1465-
grantProps = callbackResult.grantProps;
1467+
if (callbackResult.newProps) {
1468+
grantProps = callbackResult.newProps;
14661469
grantPropsChanged = true;
14671470

1468-
// If tokenProps wasn't explicitly specified, use the updated grantProps for the token too
1469-
// This ensures token props are updated when only grant props are specified
1470-
if (!callbackResult.tokenProps) {
1471-
accessTokenProps = callbackResult.grantProps;
1471+
// If accessTokenProps wasn't explicitly specified, use the updated newProps for the token too
1472+
// This ensures token props are updated when only newProps are specified
1473+
if (!callbackResult.accessTokenProps) {
1474+
accessTokenProps = callbackResult.newProps;
14721475
}
14731476
}
14741477

1475-
// If tokenProps was explicitly specified, use those
1476-
if (callbackResult.tokenProps) {
1477-
accessTokenProps = callbackResult.tokenProps;
1478+
// If accessTokenProps was explicitly specified, use those
1479+
if (callbackResult.accessTokenProps) {
1480+
accessTokenProps = callbackResult.accessTokenProps;
14781481
}
14791482
}
14801483

0 commit comments

Comments
 (0)