Skip to content

Commit 0c43b86

Browse files
authored
Add customAttributes field to SSO Profile (#1261)
1 parent 9dbeb09 commit 0c43b86

File tree

8 files changed

+51
-18
lines changed

8 files changed

+51
-18
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type UnknownRecord = Record<string, unknown>;

src/sso/__snapshots__/sso.spec.ts.snap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ exports[`SSO SSO getProfileAndToken with all information provided sends a reques
2929
{
3030
"connectionId": "conn_123",
3131
"connectionType": "OktaSAML",
32+
"customAttributes": {
33+
"license": "professional",
34+
},
3235
"email": "[email protected]",
3336
"firstName": "foo",
3437
"groups": [
@@ -47,6 +50,7 @@ exports[`SSO SSO getProfileAndToken with all information provided sends a reques
4750
"Developers",
4851
],
4952
"last_name": "bar",
53+
"license": "professional",
5054
},
5155
"role": {
5256
"slug": "admin",
@@ -69,6 +73,7 @@ exports[`SSO SSO getProfileAndToken without a groups attribute sends a request t
6973
{
7074
"connectionId": "conn_123",
7175
"connectionType": "OktaSAML",
76+
"customAttributes": {},
7277
"email": "[email protected]",
7378
"firstName": "foo",
7479
"groups": undefined,
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import { UnknownRecord } from '../../common/interfaces/unknown-record.interface';
12
import { Profile, ProfileResponse } from './profile.interface';
23

3-
export interface ProfileAndToken {
4+
export interface ProfileAndToken<CustomAttributesType extends UnknownRecord> {
45
accessToken: string;
5-
profile: Profile;
6+
profile: Profile<CustomAttributesType>;
67
}
78

8-
export interface ProfileAndTokenResponse {
9+
export interface ProfileAndTokenResponse<
10+
CustomAttributesType extends UnknownRecord,
11+
> {
912
access_token: string;
10-
profile: ProfileResponse;
13+
profile: ProfileResponse<CustomAttributesType>;
1114
}

src/sso/interfaces/profile.interface.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { UnknownRecord } from '../../common/interfaces/unknown-record.interface';
12
import { RoleResponse } from '../../roles/interfaces';
23
import { ConnectionType } from './connection-type.enum';
34

4-
export interface Profile {
5+
export interface Profile<CustomAttributesType extends UnknownRecord> {
56
id: string;
67
idpId: string;
78
organizationId?: string;
@@ -12,10 +13,11 @@ export interface Profile {
1213
lastName?: string;
1314
role?: RoleResponse;
1415
groups?: string[];
16+
customAttributes?: CustomAttributesType;
1517
rawAttributes?: { [key: string]: any };
1618
}
1719

18-
export interface ProfileResponse {
20+
export interface ProfileResponse<CustomAttributesType extends UnknownRecord> {
1921
id: string;
2022
idp_id: string;
2123
organization_id?: string;
@@ -26,5 +28,6 @@ export interface ProfileResponse {
2628
last_name?: string;
2729
role?: RoleResponse;
2830
groups?: string[];
31+
custom_attributes?: CustomAttributesType;
2932
raw_attributes?: { [key: string]: any };
3033
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { UnknownRecord } from '../../common/interfaces/unknown-record.interface';
12
import { ProfileAndToken, ProfileAndTokenResponse } from '../interfaces';
23
import { deserializeProfile } from './profile.serializer';
34

4-
export const deserializeProfileAndToken = (
5-
profileAndToken: ProfileAndTokenResponse,
6-
): ProfileAndToken => ({
5+
export const deserializeProfileAndToken = <
6+
CustomAttributesType extends UnknownRecord,
7+
>(
8+
profileAndToken: ProfileAndTokenResponse<CustomAttributesType>,
9+
): ProfileAndToken<CustomAttributesType> => ({
710
accessToken: profileAndToken.access_token,
811
profile: deserializeProfile(profileAndToken.profile),
912
});

src/sso/serializers/profile.serializer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { UnknownRecord } from '../../common/interfaces/unknown-record.interface';
12
import { Profile, ProfileResponse } from '../interfaces';
23

3-
export const deserializeProfile = (profile: ProfileResponse): Profile => ({
4+
export const deserializeProfile = <CustomAttributesType extends UnknownRecord>(
5+
profile: ProfileResponse<CustomAttributesType>,
6+
): Profile<CustomAttributesType> => ({
47
id: profile.id,
58
idpId: profile.idp_id,
69
organizationId: profile.organization_id,
@@ -11,5 +14,6 @@ export const deserializeProfile = (profile: ProfileResponse): Profile => ({
1114
lastName: profile.last_name,
1215
role: profile.role,
1316
groups: profile.groups,
17+
customAttributes: profile.custom_attributes,
1418
rawAttributes: profile.raw_attributes,
1519
});

src/sso/sso.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ describe('SSO', () => {
218218
first_name: 'foo',
219219
last_name: 'bar',
220220
groups: ['Admins', 'Developers'],
221+
license: 'professional',
222+
},
223+
custom_attributes: {
224+
license: 'professional',
221225
},
222226
},
223227
});
@@ -258,6 +262,7 @@ describe('SSO', () => {
258262
first_name: 'foo',
259263
last_name: 'bar',
260264
},
265+
custom_attributes: {},
261266
},
262267
});
263268

@@ -298,6 +303,7 @@ describe('SSO', () => {
298303
last_name: 'bar',
299304
groups: ['Admins', 'Developers'],
300305
},
306+
custom_attributes: {},
301307
});
302308

303309
const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');

src/sso/sso.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
serializeListConnectionsOptions,
2020
} from './serializers';
2121
import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize';
22+
import { UnknownRecord } from '../common/interfaces/unknown-record.interface';
2223

2324
const toQueryString = (options: Record<string, string | undefined>): string => {
2425
const searchParams = new URLSearchParams();
@@ -109,27 +110,34 @@ export class SSO {
109110
return deserializeConnection(data);
110111
}
111112

112-
async getProfileAndToken({
113+
async getProfileAndToken<
114+
CustomAttributesType extends UnknownRecord = UnknownRecord,
115+
>({
113116
code,
114117
clientId,
115-
}: GetProfileAndTokenOptions): Promise<ProfileAndToken> {
118+
}: GetProfileAndTokenOptions): Promise<
119+
ProfileAndToken<CustomAttributesType>
120+
> {
116121
const form = new URLSearchParams({
117122
client_id: clientId,
118123
client_secret: this.workos.key as string,
119124
grant_type: 'authorization_code',
120125
code,
121126
});
122127

123-
const { data } = await this.workos.post<ProfileAndTokenResponse>(
124-
'/sso/token',
125-
form,
126-
);
128+
const { data } = await this.workos.post<
129+
ProfileAndTokenResponse<CustomAttributesType>
130+
>('/sso/token', form);
127131

128132
return deserializeProfileAndToken(data);
129133
}
130134

131-
async getProfile({ accessToken }: GetProfileOptions): Promise<Profile> {
132-
const { data } = await this.workos.get<ProfileResponse>('/sso/profile', {
135+
async getProfile<CustomAttributesType extends UnknownRecord = UnknownRecord>({
136+
accessToken,
137+
}: GetProfileOptions): Promise<Profile<CustomAttributesType>> {
138+
const { data } = await this.workos.get<
139+
ProfileResponse<CustomAttributesType>
140+
>('/sso/profile', {
133141
accessToken,
134142
});
135143

0 commit comments

Comments
 (0)