Skip to content

Commit 8156b59

Browse files
authored
Use separate http clients for auth and management (#564)
1 parent 9f0e0c5 commit 8156b59

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1412
-2251
lines changed

examples/managementCli/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/managementCli/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import DescopeClient, { SdkResponse } from '@descope/node-sdk';
33
import { config } from 'dotenv';
44
import { writeFileSync, readFileSync } from 'fs';
55
import { Command } from 'commander';
6-
import { UserResponse } from '@descope/core-js-sdk';
76

87
config();
98

lib/index.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,11 @@ describe('sdk', () => {
509509
it('should add descope headers to request', async () => {
510510
jest.resetModules();
511511
const createCoreJs = jest.fn();
512+
const createHttpClient = jest.fn();
512513
jest.doMock('@descope/core-js-sdk', () => ({
513514
__esModule: true,
514515
default: createCoreJs,
516+
createHttpClient,
515517
wrapWith: (sdkInstance: object) => sdkInstance,
516518
addHooksToConfig: (config, hooks) => {
517519
// eslint-disable-next-line no-param-reassign
@@ -542,10 +544,12 @@ describe('sdk', () => {
542544
it('should add auth management key to request when there is no token', async () => {
543545
jest.resetModules();
544546
const createCoreJs = jest.fn();
547+
const createHttpClient = jest.fn();
545548

546549
jest.doMock('@descope/core-js-sdk', () => ({
547550
__esModule: true,
548551
default: createCoreJs,
552+
createHttpClient,
549553
wrapWith: (sdkInstance: object) => sdkInstance,
550554
addHooksToConfig: (config, hooks) => {
551555
// eslint-disable-next-line no-param-reassign
@@ -581,10 +585,12 @@ describe('sdk', () => {
581585
it('should add auth management key to request when there is token', async () => {
582586
jest.resetModules();
583587
const createCoreJs = jest.fn();
588+
const createHttpClient = jest.fn();
584589

585590
jest.doMock('@descope/core-js-sdk', () => ({
586591
__esModule: true,
587592
default: createCoreJs,
593+
createHttpClient,
588594
wrapWith: (sdkInstance: object) => sdkInstance,
589595
addHooksToConfig: (config, hooks) => {
590596
// eslint-disable-next-line no-param-reassign
@@ -612,11 +618,13 @@ describe('sdk', () => {
612618
it('should merge before request hooks if they are defined', async () => {
613619
jest.resetModules();
614620
const createCoreJs = jest.fn();
621+
const createHttpClient = jest.fn();
615622
const existingHook = jest.fn((config) => ({ ...config, customField: 'test' }));
616623

617624
jest.doMock('@descope/core-js-sdk', () => ({
618625
__esModule: true,
619626
default: createCoreJs,
627+
createHttpClient,
620628
wrapWith: (sdkInstance: object) => sdkInstance,
621629
addHooksToConfig: (config, hooks) => {
622630
// eslint-disable-next-line no-param-reassign

lib/index.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import createSdk, {
44
SdkResponse,
55
JWTResponse as CoreJWTResponse,
66
wrapWith,
7+
createHttpClient,
8+
CreateHttpClientConfig,
9+
RequestConfig,
710
} from '@descope/core-js-sdk';
811
import { JWK, JWTHeaderParameters, KeyLike, errors, importJWK, jwtVerify } from 'jose';
912
import {
@@ -38,19 +41,24 @@ type NodeSdkArgs = Parameters<typeof createSdk>[0] & {
3841
};
3942

4043
const nodeSdk = ({ authManagementKey, managementKey, publicKey, ...config }: NodeSdkArgs) => {
41-
const coreSdk = createSdk({
44+
const nodeHeaders = {
45+
'x-descope-sdk-name': 'nodejs',
46+
'x-descope-sdk-node-version': process?.versions?.node || '',
47+
'x-descope-sdk-version': BUILD_VERSION,
48+
};
49+
50+
const authSdkConfig = {
4251
fetch,
4352
...config,
4453
baseHeaders: {
4554
...config.baseHeaders,
46-
'x-descope-sdk-name': 'nodejs',
47-
'x-descope-sdk-node-version': process?.versions?.node || '',
48-
'x-descope-sdk-version': BUILD_VERSION,
55+
...nodeHeaders,
4956
},
5057
hooks: {
5158
...config.hooks,
5259
beforeRequest: [
53-
(requestConfig) => {
60+
// auth requests append the auth management key if provided
61+
(requestConfig: RequestConfig) => {
5462
if (authManagementKey) {
5563
// eslint-disable-next-line no-param-reassign
5664
requestConfig.token = !requestConfig.token
@@ -62,7 +70,8 @@ const nodeSdk = ({ authManagementKey, managementKey, publicKey, ...config }: Nod
6270
},
6371
].concat(config.hooks?.beforeRequest || []),
6472
},
65-
});
73+
};
74+
const coreSdk = createSdk(authSdkConfig);
6675

6776
const { projectId, logger } = config;
6877

@@ -98,7 +107,29 @@ const nodeSdk = ({ authManagementKey, managementKey, publicKey, ...config }: Nod
98107
);
99108
};
100109

101-
const management = withManagement(coreSdk, managementKey);
110+
const mgmtSdkConfig = {
111+
fetch,
112+
...config,
113+
baseConfig: {
114+
baseHeaders: {
115+
...config.baseHeaders,
116+
...nodeHeaders,
117+
},
118+
},
119+
hooks: {
120+
...config.hooks,
121+
beforeRequest: [
122+
// management requests always use the management key as the token
123+
(requestConfig: RequestConfig) => {
124+
// eslint-disable-next-line no-param-reassign
125+
requestConfig.token = managementKey;
126+
return requestConfig;
127+
},
128+
].concat(config.hooks?.beforeRequest || []),
129+
},
130+
};
131+
const mgmtHttpClient = createHttpClient(mgmtSdkConfig);
132+
const management = withManagement(mgmtHttpClient);
102133

103134
const sdk = {
104135
...coreSdk,

lib/management/accesskey.test.ts

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { SdkResponse } from '@descope/core-js-sdk';
22
import withManagement from '.';
33
import apiPaths from './paths';
4-
import { mockCoreSdk, mockHttpClient } from './testutils';
4+
import { mockHttpClient, resetMockHttpClient } from './testutils';
55
import { CreatedAccessKeyResponse, AccessKey } from './types';
66

7-
const management = withManagement(mockCoreSdk, 'key');
7+
const management = withManagement(mockHttpClient);
88

99
const mockAccessKeyResponse = {
1010
id: 'ak1',
@@ -23,7 +23,7 @@ const mockMgmtAccessKeysResponse = {
2323
describe('Management Access Keys', () => {
2424
afterEach(() => {
2525
jest.clearAllMocks();
26-
mockHttpClient.reset();
26+
resetMockHttpClient();
2727
});
2828

2929
describe('create', () => {
@@ -53,20 +53,16 @@ describe('Management Access Keys', () => {
5353
['10.0.0.1', '192.168.1.0/24'],
5454
);
5555

56-
expect(mockHttpClient.post).toHaveBeenCalledWith(
57-
apiPaths.accessKey.create,
58-
{
59-
name: 'foo',
60-
expireTime: 123456789,
61-
roleNames: ['r1', 'r2'],
62-
keyTenants: null,
63-
userId: 'uid',
64-
customClaims: { k1: 'v1' },
65-
description: 'hey',
66-
permittedIps: ['10.0.0.1', '192.168.1.0/24'],
67-
},
68-
{ token: 'key' },
69-
);
56+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.create, {
57+
name: 'foo',
58+
expireTime: 123456789,
59+
roleNames: ['r1', 'r2'],
60+
keyTenants: null,
61+
userId: 'uid',
62+
customClaims: { k1: 'v1' },
63+
description: 'hey',
64+
permittedIps: ['10.0.0.1', '192.168.1.0/24'],
65+
});
7066

7167
expect(resp).toEqual({
7268
code: 200,
@@ -93,7 +89,6 @@ describe('Management Access Keys', () => {
9389

9490
expect(mockHttpClient.get).toHaveBeenCalledWith(apiPaths.accessKey.load, {
9591
queryParams: { id: 'id' },
96-
token: 'key',
9792
});
9893

9994
expect(resp).toEqual({
@@ -119,11 +114,9 @@ describe('Management Access Keys', () => {
119114

120115
const resp: SdkResponse<AccessKey[]> = await management.accessKey.searchAll(['t1']);
121116

122-
expect(mockHttpClient.post).toHaveBeenCalledWith(
123-
apiPaths.accessKey.search,
124-
{ tenantIds: ['t1'] },
125-
{ token: 'key' },
126-
);
117+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.search, {
118+
tenantIds: ['t1'],
119+
});
127120

128121
expect(resp).toEqual({
129122
code: 200,
@@ -156,19 +149,15 @@ describe('Management Access Keys', () => {
156149
['1.2.3.4'],
157150
);
158151

159-
expect(mockHttpClient.post).toHaveBeenCalledWith(
160-
apiPaths.accessKey.update,
161-
{
162-
id: 'id',
163-
name: 'name',
164-
description: 'description',
165-
roleNames: ['r1', 'r2'],
166-
keyTenants: undefined,
167-
customClaims: { k1: 'v1' },
168-
permittedIps: ['1.2.3.4'],
169-
},
170-
{ token: 'key' },
171-
);
152+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.update, {
153+
id: 'id',
154+
name: 'name',
155+
description: 'description',
156+
roleNames: ['r1', 'r2'],
157+
keyTenants: undefined,
158+
customClaims: { k1: 'v1' },
159+
permittedIps: ['1.2.3.4'],
160+
});
172161

173162
expect(resp).toEqual({
174163
code: 200,
@@ -193,11 +182,7 @@ describe('Management Access Keys', () => {
193182

194183
const resp: SdkResponse<AccessKey> = await management.accessKey.deactivate('id');
195184

196-
expect(mockHttpClient.post).toHaveBeenCalledWith(
197-
apiPaths.accessKey.deactivate,
198-
{ id: 'id' },
199-
{ token: 'key' },
200-
);
185+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.deactivate, { id: 'id' });
201186

202187
expect(resp).toEqual({
203188
code: 200,
@@ -222,11 +207,7 @@ describe('Management Access Keys', () => {
222207

223208
const resp: SdkResponse<AccessKey> = await management.accessKey.activate('id');
224209

225-
expect(mockHttpClient.post).toHaveBeenCalledWith(
226-
apiPaths.accessKey.activate,
227-
{ id: 'id' },
228-
{ token: 'key' },
229-
);
210+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.activate, { id: 'id' });
230211

231212
expect(resp).toEqual({
232213
code: 200,
@@ -251,11 +232,7 @@ describe('Management Access Keys', () => {
251232

252233
const resp: SdkResponse<AccessKey> = await management.accessKey.delete('id');
253234

254-
expect(mockHttpClient.post).toHaveBeenCalledWith(
255-
apiPaths.accessKey.delete,
256-
{ id: 'id' },
257-
{ token: 'key' },
258-
);
235+
expect(mockHttpClient.post).toHaveBeenCalledWith(apiPaths.accessKey.delete, { id: 'id' });
259236

260237
expect(resp).toEqual({
261238
code: 200,

0 commit comments

Comments
 (0)