Skip to content

Commit 6e565b8

Browse files
descope[bot]shuni[bot]
andauthored
Add deleteUserTokens and deleteTokenById to outbound app management (#620)
Co-authored-by: shuni[bot] <shuni[bot]@users.noreply.github.com>
1 parent 195d72d commit 6e565b8

File tree

4 files changed

+145
-0
lines changed

4 files changed

+145
-0
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,21 @@ const latestTenantToken = await descopeClient.management.outboundApplication.fet
14531453
'tenant-id',
14541454
{ forceRefresh: false }
14551455
);
1456+
1457+
// Delete user tokens by appId and/or userId
1458+
// At least one of appId or userId should be provided
1459+
// Token deletion cannot be undone. Use carefully.
1460+
await descopeClient.management.outboundApplication.deleteUserTokens('my-app-id', 'user-id');
1461+
1462+
// Delete all tokens for a specific app
1463+
await descopeClient.management.outboundApplication.deleteUserTokens('my-app-id');
1464+
1465+
// Delete all tokens for a specific user
1466+
await descopeClient.management.outboundApplication.deleteUserTokens(undefined, 'user-id');
1467+
1468+
// Delete a specific token by its ID
1469+
// Token deletion cannot be undone. Use carefully.
1470+
await descopeClient.management.outboundApplication.deleteTokenById('token-id');
14561471
```
14571472

14581473
### Manage Inbound Applications

lib/management/outboundapplication.test.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,4 +489,120 @@ describe('Management OutboundApplication', () => {
489489
});
490490
});
491491
});
492+
493+
describe('deleteUserTokens', () => {
494+
it('should send the correct request with both appId and userId', async () => {
495+
const httpResponse = {
496+
ok: true,
497+
json: () => ({}),
498+
clone: () => ({
499+
json: () => Promise.resolve({}),
500+
}),
501+
status: 200,
502+
};
503+
mockHttpClient.delete.mockResolvedValue(httpResponse);
504+
505+
const resp = await management.outboundApplication.deleteUserTokens('app123', 'user456');
506+
507+
expect(mockHttpClient.delete).toHaveBeenCalledWith(
508+
apiPaths.outboundApplication.deleteUserTokens,
509+
{
510+
queryParams: { appId: 'app123', userId: 'user456' },
511+
},
512+
);
513+
514+
expect(resp).toEqual({
515+
code: 200,
516+
data: {},
517+
ok: true,
518+
response: httpResponse,
519+
});
520+
});
521+
522+
it('should work with only appId', async () => {
523+
const httpResponse = {
524+
ok: true,
525+
json: () => ({}),
526+
clone: () => ({
527+
json: () => Promise.resolve({}),
528+
}),
529+
status: 200,
530+
};
531+
mockHttpClient.delete.mockResolvedValue(httpResponse);
532+
533+
const resp = await management.outboundApplication.deleteUserTokens('app123');
534+
535+
expect(mockHttpClient.delete).toHaveBeenCalledWith(
536+
apiPaths.outboundApplication.deleteUserTokens,
537+
{
538+
queryParams: { appId: 'app123', userId: undefined },
539+
},
540+
);
541+
542+
expect(resp).toEqual({
543+
code: 200,
544+
data: {},
545+
ok: true,
546+
response: httpResponse,
547+
});
548+
});
549+
550+
it('should work with only userId', async () => {
551+
const httpResponse = {
552+
ok: true,
553+
json: () => ({}),
554+
clone: () => ({
555+
json: () => Promise.resolve({}),
556+
}),
557+
status: 200,
558+
};
559+
mockHttpClient.delete.mockResolvedValue(httpResponse);
560+
561+
const resp = await management.outboundApplication.deleteUserTokens(undefined, 'user456');
562+
563+
expect(mockHttpClient.delete).toHaveBeenCalledWith(
564+
apiPaths.outboundApplication.deleteUserTokens,
565+
{
566+
queryParams: { appId: undefined, userId: 'user456' },
567+
},
568+
);
569+
570+
expect(resp).toEqual({
571+
code: 200,
572+
data: {},
573+
ok: true,
574+
response: httpResponse,
575+
});
576+
});
577+
});
578+
579+
describe('deleteTokenById', () => {
580+
it('should send the correct request and receive correct response', async () => {
581+
const httpResponse = {
582+
ok: true,
583+
json: () => ({}),
584+
clone: () => ({
585+
json: () => Promise.resolve({}),
586+
}),
587+
status: 200,
588+
};
589+
mockHttpClient.delete.mockResolvedValue(httpResponse);
590+
591+
const resp = await management.outboundApplication.deleteTokenById('token123');
592+
593+
expect(mockHttpClient.delete).toHaveBeenCalledWith(
594+
apiPaths.outboundApplication.deleteTokenById,
595+
{
596+
queryParams: { id: 'token123' },
597+
},
598+
);
599+
600+
expect(resp).toEqual({
601+
code: 200,
602+
data: {},
603+
ok: true,
604+
response: httpResponse,
605+
});
606+
});
607+
});
492608
});

lib/management/outboundapplication.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ const withOutboundApplication = (httpClient: HttpClient) => ({
108108
}),
109109
(data) => data.token,
110110
),
111+
deleteUserTokens: (appId?: string, userId?: string): Promise<SdkResponse<never>> =>
112+
transformResponse(
113+
httpClient.delete(apiPaths.outboundApplication.deleteUserTokens, {
114+
queryParams: { appId, userId },
115+
}),
116+
),
117+
deleteTokenById: (id: string): Promise<SdkResponse<never>> =>
118+
transformResponse(
119+
httpClient.delete(apiPaths.outboundApplication.deleteTokenById, {
120+
queryParams: { id },
121+
}),
122+
),
111123
});
112124

113125
export default withOutboundApplication;

lib/management/paths.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ export default {
105105
fetchTokenByScopes: '/v1/mgmt/outbound/app/user/token',
106106
fetchTenantToken: '/v1/mgmt/outbound/app/tenant/token/latest',
107107
fetchTenantTokenByScopes: '/v1/mgmt/outbound/app/tenant/token',
108+
deleteUserTokens: '/v1/mgmt/outbound/user/tokens',
109+
deleteTokenById: '/v1/mgmt/outbound/token',
108110
},
109111
sso: {
110112
settings: '/v1/mgmt/sso/settings',

0 commit comments

Comments
 (0)