Summary
UserAccessToken.get(key, { namespace }) reads an expired token from the requested namespace, but a successful refresh is written back without that namespace. The refreshed token therefore lands under the app-ID namespace while the requested namespace remains expired.
Affected version
@larksuiteoapi/node-sdk 1.73.0
main at f54b49f3566c52b54c598194b7ed3015e3e24224
Reproduction
- Initialize an expired entry for
user-1 under a custom namespace, for example tenant-a.
- Mock
authen.oidcRefreshAccessToken.create to return a successful refreshed access token.
- Call
client.userAccessToken.get('user-1', { namespace: 'tenant-a' }) twice.
The first call returns the refreshed token, but the second call refreshes again. Inspecting the cache shows the refreshed entry under the default app-ID namespace, while the tenant-a entry is still expired.
In a local memory-cache reproduction, two consecutive reads produced two refresh requests (new-1, then new-2) and the default namespace contained new-2.
Expected behavior
The successful refresh should update the same cache namespace from which the token was read. A second read from that namespace should use the refreshed cached token.
Actual behavior
Both successful update paths in client/user-access-token.ts call this.update(...) without forwarding options?.namespace. update consequently falls back to this.client.appId.
This is distinct from #103: that issue fixed a literal key property by changing it to [key]; the custom namespace is still dropped.
Impact
Applications that isolate user tokens with custom namespaces repeatedly call the OAuth refresh endpoint and retain stale entries in the intended namespace. The unexpected write to the app namespace can also break cache isolation assumptions.
Summary
UserAccessToken.get(key, { namespace })reads an expired token from the requested namespace, but a successful refresh is written back without that namespace. The refreshed token therefore lands under the app-ID namespace while the requested namespace remains expired.Affected version
@larksuiteoapi/node-sdk1.73.0mainatf54b49f3566c52b54c598194b7ed3015e3e24224Reproduction
user-1under a custom namespace, for exampletenant-a.authen.oidcRefreshAccessToken.createto return a successful refreshed access token.client.userAccessToken.get('user-1', { namespace: 'tenant-a' })twice.The first call returns the refreshed token, but the second call refreshes again. Inspecting the cache shows the refreshed entry under the default app-ID namespace, while the
tenant-aentry is still expired.In a local memory-cache reproduction, two consecutive reads produced two refresh requests (
new-1, thennew-2) and the default namespace containednew-2.Expected behavior
The successful refresh should update the same cache namespace from which the token was read. A second read from that namespace should use the refreshed cached token.
Actual behavior
Both successful update paths in
client/user-access-token.tscallthis.update(...)without forwardingoptions?.namespace.updateconsequently falls back tothis.client.appId.This is distinct from #103: that issue fixed a literal
keyproperty by changing it to[key]; the custom namespace is still dropped.Impact
Applications that isolate user tokens with custom namespaces repeatedly call the OAuth refresh endpoint and retain stale entries in the intended namespace. The unexpected write to the app namespace can also break cache isolation assumptions.