Skip to content

Commit 91935d6

Browse files
authored
Add userManagement.listSessions (#1316)
## Description This endpoint will list the active sessions for a given user. ## Documentation ``` [X] Yes ``` If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required. <!-- av pr metadata This information is embedded by the av CLI when creating PRs to track the status of stacks when using Aviator. Please do not delete or edit this section of the PR. ``` {"parent":"main","parentHead":"","trunk":"main"} ``` -->
1 parent 3bef703 commit 91935d6

File tree

11 files changed

+141
-6
lines changed

11 files changed

+141
-6
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"object": "list",
3+
"data": [
4+
{
5+
"object": "session",
6+
"id": "session_01K0T5TNC755C7FGRQFJRS4QK5",
7+
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
8+
"ip_address": "192.168.65.1",
9+
"user_id": "user_01K0T5T62NBSETXQD3NVGEA2RN",
10+
"auth_method": "oauth",
11+
"status": "active",
12+
"expires_at": "2026-07-22T22:59:48.743Z",
13+
"ended_at": null,
14+
"created_at": "2025-07-23T04:59:48.738Z",
15+
"updated_at": "2025-07-23T04:59:48.738Z"
16+
}
17+
],
18+
"list_metadata": {
19+
"before": null,
20+
"after": null
21+
}
22+
}

src/user-management/interfaces/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export * from './invitation.interface';
2525
export * from './list-auth-factors-options.interface';
2626
export * from './list-invitations-options.interface';
2727
export * from './list-organization-memberships-options.interface';
28+
export * from './list-sessions-options.interface';
2829
export * from './list-users-options.interface';
2930
export * from './magic-auth.interface';
3031
export * from './oauth-tokens.interface';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { PaginationOptions } from '../../common/interfaces/pagination-options.interface';
2+
3+
// tslint:disable-next-line:no-empty-interface
4+
export interface ListSessionsOptions extends PaginationOptions {}
5+
6+
// tslint:disable-next-line:no-empty-interface
7+
export interface SerializedListSessionsOptions extends PaginationOptions {}

src/user-management/interfaces/session.interface.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import { Impersonator } from './impersonator.interface';
22

3+
export type AuthMethod =
4+
| 'external_auth'
5+
| 'impersonation'
6+
| 'magic_code'
7+
| 'migrated_session'
8+
| 'oauth'
9+
| 'passkey'
10+
| 'password'
11+
| 'sso'
12+
| 'unknown';
13+
14+
export type SessionStatus = 'active' | 'expired' | 'revoked';
15+
316
export interface Session {
417
object: 'session';
518
id: string;
@@ -8,6 +21,12 @@ export interface Session {
821
userAgent: string | null;
922
organizationId?: string;
1023
impersonator?: Impersonator;
24+
authMethod: AuthMethod;
25+
status: SessionStatus;
26+
expiresAt: string;
27+
endedAt: string | null;
28+
createdAt: string;
29+
updatedAt: string;
1130
}
1231

1332
export interface SessionResponse {
@@ -18,4 +37,10 @@ export interface SessionResponse {
1837
user_agent: string | null;
1938
organization_id?: string;
2039
impersonator?: Impersonator;
40+
auth_method: AuthMethod;
41+
status: SessionStatus;
42+
expires_at: string;
43+
ended_at: string | null;
44+
created_at: string;
45+
updated_at: string;
2146
}

src/user-management/serializers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ export * from './email-verification.serializer';
1212
export * from './enroll-auth-factor-options.serializer';
1313
export * from './factor.serializer';
1414
export * from './invitation.serializer';
15+
export * from './list-sessions-options.serializer';
1516
export * from './magic-auth.serializer';
1617
export * from './password-reset.serializer';
1718
export * from './reset-password-options.serializer';
1819
export * from './send-password-reset-email.serializer';
20+
export * from './session.serializer';
1921
export * from './create-user-options.serializer';
2022
export * from './send-magic-auth-code-options.serializer';
2123
export * from './update-user-options.serializer';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {
2+
ListSessionsOptions,
3+
SerializedListSessionsOptions,
4+
} from '../interfaces/list-sessions-options.interface';
5+
6+
export const serializeListSessionsOptions = (
7+
options: ListSessionsOptions,
8+
): SerializedListSessionsOptions => ({
9+
...options,
10+
});

src/user-management/serializers/session.serializer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ export const deserializeSession = (session: SessionResponse): Session => ({
88
userAgent: session.user_agent,
99
organizationId: session.organization_id,
1010
impersonator: session.impersonator,
11+
authMethod: session.auth_method,
12+
status: session.status,
13+
expiresAt: session.expires_at,
14+
endedAt: session.ended_at,
15+
createdAt: session.created_at,
16+
updatedAt: session.updated_at,
1117
});

src/user-management/session.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { WorkOS } from '../workos';
2-
import { Session } from './session';
2+
import { CookieSession } from './session';
33
import * as jose from 'jose';
44
import { sealData } from 'iron-session';
55
import userFixture from './fixtures/user.json';
@@ -33,7 +33,7 @@ describe('Session', () => {
3333
cookiePassword: 'cookiePassword',
3434
});
3535

36-
expect(session).toBeInstanceOf(Session);
36+
expect(session).toBeInstanceOf(CookieSession);
3737
});
3838
});
3939

src/user-management/session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type RefreshOptions = {
1818
organizationId?: string;
1919
};
2020

21-
export class Session {
21+
export class CookieSession {
2222
private jwks: ReturnType<typeof createRemoteJWKSet> | undefined;
2323
private userManagement: UserManagement;
2424
private ironSessionProvider: IronSessionProvider;

src/user-management/user-management.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import invitationFixture from './fixtures/invitation.json';
1212
import listFactorFixture from './fixtures/list-factors.json';
1313
import listInvitationsFixture from './fixtures/list-invitations.json';
1414
import listOrganizationMembershipsFixture from './fixtures/list-organization-memberships.json';
15+
import listSessionsFixture from './fixtures/list-sessions.json';
1516
import listUsersFixture from './fixtures/list-users.json';
1617
import magicAuthFixture from './fixtures/magic_auth.json';
1718
import organizationMembershipFixture from './fixtures/organization-membership.json';
@@ -1537,6 +1538,40 @@ describe('UserManagement', () => {
15371538
});
15381539
});
15391540

1541+
describe('listSessions', () => {
1542+
it('sends a listSessions request', async () => {
1543+
fetchOnce(listSessionsFixture);
1544+
1545+
const resp = await workos.userManagement.listSessions(userId);
1546+
1547+
expect(fetchURL()).toContain(`/user_management/users/${userId}/sessions`);
1548+
1549+
expect(resp).toMatchObject({
1550+
object: 'list',
1551+
data: [
1552+
{
1553+
object: 'session',
1554+
id: 'session_01K0T5TNC755C7FGRQFJRS4QK5',
1555+
userId: 'user_01K0T5T62NBSETXQD3NVGEA2RN',
1556+
userAgent:
1557+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
1558+
ipAddress: '192.168.65.1',
1559+
authMethod: 'oauth',
1560+
status: 'active',
1561+
expiresAt: '2026-07-22T22:59:48.743Z',
1562+
endedAt: null,
1563+
createdAt: '2025-07-23T04:59:48.738Z',
1564+
updatedAt: '2025-07-23T04:59:48.738Z',
1565+
},
1566+
],
1567+
listMetadata: {
1568+
before: null,
1569+
after: null,
1570+
},
1571+
});
1572+
});
1573+
});
1574+
15401575
describe('deleteUser', () => {
15411576
it('sends a deleteUser request', async () => {
15421577
fetchOnce();

0 commit comments

Comments
 (0)