From daeb89532cbe285b496f99a80b395bc0621fba01 Mon Sep 17 00:00:00 2001 From: Colin Barber Date: Thu, 29 Jan 2026 14:59:17 -0400 Subject: [PATCH 1/3] feat: Add organization role support --- src/authorization/authorization.spec.ts | 207 ++++++++++++++++++ src/authorization/authorization.ts | 104 +++++++++ .../fixtures/list-organization-roles.json | 27 +++ .../fixtures/organization-role.json | 11 + ...ate-organization-role-options.interface.ts | 12 + src/authorization/interfaces/index.ts | 4 + ...st-organization-roles-options.interface.ts | 4 + .../interfaces/organization-role.interface.ts | 33 +++ ...ate-organization-role-options.interface.ts | 9 + ...te-organization-role-options.serializer.ts | 12 + src/authorization/serializers/index.ts | 3 + .../organization-role.serializer.ts | 18 ++ ...te-organization-role-options.serializer.ts | 11 + 13 files changed, 455 insertions(+) create mode 100644 src/authorization/fixtures/list-organization-roles.json create mode 100644 src/authorization/fixtures/organization-role.json create mode 100644 src/authorization/interfaces/create-organization-role-options.interface.ts create mode 100644 src/authorization/interfaces/list-organization-roles-options.interface.ts create mode 100644 src/authorization/interfaces/organization-role.interface.ts create mode 100644 src/authorization/interfaces/update-organization-role-options.interface.ts create mode 100644 src/authorization/serializers/create-organization-role-options.serializer.ts create mode 100644 src/authorization/serializers/organization-role.serializer.ts create mode 100644 src/authorization/serializers/update-organization-role-options.serializer.ts diff --git a/src/authorization/authorization.spec.ts b/src/authorization/authorization.spec.ts index 92769db9c..bd349241c 100644 --- a/src/authorization/authorization.spec.ts +++ b/src/authorization/authorization.spec.ts @@ -8,8 +8,11 @@ import { import { WorkOS } from '../workos'; import environmentRoleFixture from './fixtures/environment-role.json'; import listEnvironmentRolesFixture from './fixtures/list-environment-roles.json'; +import organizationRoleFixture from './fixtures/organization-role.json'; +import listOrganizationRolesFixture from './fixtures/list-organization-roles.json'; const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); +const testOrgId = 'org_01HXYZ123ABC456DEF789ABC'; describe('Authorization', () => { beforeEach(() => fetch.resetMocks()); @@ -236,4 +239,208 @@ describe('Authorization', () => { ); }); }); + + // === Organization Roles === + + describe('createOrganizationRole', () => { + it('creates an organization role', async () => { + fetchOnce(organizationRoleFixture, { status: 201 }); + + const role = await workos.authorization.createOrganizationRole({ + organizationId: testOrgId, + slug: 'org-admin', + name: 'Org Admin', + description: 'Organization administrator', + }); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles`, + ); + expect(fetchBody()).toEqual({ + slug: 'org-admin', + name: 'Org Admin', + description: 'Organization administrator', + }); + expect(role).toMatchObject({ + object: 'role', + id: 'role_01HXYZ123ABC456DEF789ORG', + slug: 'org-admin', + name: 'Org Admin', + type: 'OrganizationRole', + }); + }); + }); + + describe('listOrganizationRoles', () => { + it('returns organization roles', async () => { + fetchOnce(listOrganizationRolesFixture); + + const { data, object } = await workos.authorization.listOrganizationRoles( + { organizationId: testOrgId }, + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles`, + ); + expect(object).toEqual('list'); + expect(data).toHaveLength(2); + expect(data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + slug: 'org-admin', + type: 'OrganizationRole', + }), + expect.objectContaining({ + slug: 'org-member', + type: 'OrganizationRole', + }), + ]), + ); + }); + + it('passes expand parameter', async () => { + fetchOnce(listOrganizationRolesFixture); + + await workos.authorization.listOrganizationRoles({ + organizationId: testOrgId, + expand: 'permissions', + }); + + expect(fetchSearchParams()).toEqual({ + expand: 'permissions', + }); + }); + }); + + describe('getOrganizationRole', () => { + it('gets an organization role by slug', async () => { + fetchOnce(organizationRoleFixture); + + const role = await workos.authorization.getOrganizationRole( + testOrgId, + 'org-admin', + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin`, + ); + expect(role).toMatchObject({ + object: 'role', + slug: 'org-admin', + type: 'OrganizationRole', + }); + }); + }); + + describe('updateOrganizationRole', () => { + it('updates an organization role', async () => { + const updatedRoleFixture = { + ...organizationRoleFixture, + name: 'Super Org Admin', + description: 'Updated description', + }; + fetchOnce(updatedRoleFixture); + + const role = await workos.authorization.updateOrganizationRole( + testOrgId, + 'org-admin', + { + name: 'Super Org Admin', + description: 'Updated description', + }, + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin`, + ); + expect(fetchBody()).toEqual({ + name: 'Super Org Admin', + description: 'Updated description', + }); + expect(role).toMatchObject({ + name: 'Super Org Admin', + description: 'Updated description', + }); + }); + }); + + describe('deleteOrganizationRole', () => { + it('deletes an organization role', async () => { + fetchOnce({}, { status: 204 }); + + await workos.authorization.deleteOrganizationRole(testOrgId, 'org-admin'); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin`, + ); + }); + }); + + describe('setOrganizationRolePermissions', () => { + it('sets permissions for an organization role', async () => { + const updatedRoleFixture = { + ...organizationRoleFixture, + permissions: ['org:read', 'org:write'], + }; + fetchOnce(updatedRoleFixture); + + const role = await workos.authorization.setOrganizationRolePermissions( + testOrgId, + 'org-admin', + ['org:read', 'org:write'], + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin/permissions`, + ); + expect(fetchBody()).toEqual({ + permissions: ['org:read', 'org:write'], + }); + expect(role.permissions).toEqual( + expect.arrayContaining(['org:read', 'org:write']), + ); + }); + }); + + describe('addOrganizationRolePermission', () => { + it('adds a permission to an organization role', async () => { + const updatedRoleFixture = { + ...organizationRoleFixture, + permissions: ['org:manage', 'members:invite', 'billing:read'], + }; + fetchOnce(updatedRoleFixture); + + const role = await workos.authorization.addOrganizationRolePermission( + testOrgId, + 'org-admin', + 'billing:read', + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin/permissions`, + ); + expect(fetchBody()).toEqual({ + slug: 'billing:read', + }); + expect(role.permissions).toEqual( + expect.arrayContaining(['billing:read']), + ); + }); + }); + + describe('removeOrganizationRolePermission', () => { + it('removes a permission from an organization role', async () => { + fetchOnce({}, { status: 200 }); + + await workos.authorization.removeOrganizationRolePermission( + testOrgId, + 'org-admin', + 'members:invite', + ); + + expect(fetchURL()).toContain( + `/authorization/organizations/${testOrgId}/roles/org-admin/permissions/members:invite`, + ); + }); + }); }); diff --git a/src/authorization/authorization.ts b/src/authorization/authorization.ts index 4c2e7d193..238c7c856 100644 --- a/src/authorization/authorization.ts +++ b/src/authorization/authorization.ts @@ -7,16 +7,28 @@ import { CreateEnvironmentRoleOptions, UpdateEnvironmentRoleOptions, ListEnvironmentRolesOptions, + OrganizationRole, + OrganizationRoleResponse, + OrganizationRoleList, + OrganizationRoleListResponse, + CreateOrganizationRoleOptions, + UpdateOrganizationRoleOptions, + ListOrganizationRolesOptions, } from './interfaces'; import { deserializeEnvironmentRole, serializeCreateEnvironmentRoleOptions, serializeUpdateEnvironmentRoleOptions, + deserializeOrganizationRole, + serializeCreateOrganizationRoleOptions, + serializeUpdateOrganizationRoleOptions, } from './serializers'; export class Authorization { constructor(private readonly workos: WorkOS) {} + // === Environment Roles === + async createEnvironmentRole( options: CreateEnvironmentRoleOptions, ): Promise { @@ -79,4 +91,96 @@ export class Authorization { ); return deserializeEnvironmentRole(data); } + + // === Organization Roles === + + async createOrganizationRole( + options: CreateOrganizationRoleOptions, + ): Promise { + const { organizationId, ...payload } = options; + const { data } = await this.workos.post( + `/authorization/organizations/${organizationId}/roles`, + serializeCreateOrganizationRoleOptions(options), + ); + return deserializeOrganizationRole(data); + } + + async listOrganizationRoles( + options: ListOrganizationRolesOptions, + ): Promise { + const { organizationId, ...query } = options; + const { data } = await this.workos.get( + `/authorization/organizations/${organizationId}/roles`, + { query }, + ); + return { + object: 'list', + data: data.data.map(deserializeOrganizationRole), + }; + } + + async getOrganizationRole( + organizationId: string, + slug: string, + ): Promise { + const { data } = await this.workos.get( + `/authorization/organizations/${organizationId}/roles/${slug}`, + ); + return deserializeOrganizationRole(data); + } + + async updateOrganizationRole( + organizationId: string, + slug: string, + options: UpdateOrganizationRoleOptions, + ): Promise { + const { data } = await this.workos.patch( + `/authorization/organizations/${organizationId}/roles/${slug}`, + serializeUpdateOrganizationRoleOptions(options), + ); + return deserializeOrganizationRole(data); + } + + async deleteOrganizationRole( + organizationId: string, + slug: string, + ): Promise { + await this.workos.delete( + `/authorization/organizations/${organizationId}/roles/${slug}`, + ); + } + + async setOrganizationRolePermissions( + organizationId: string, + slug: string, + permissions: string[], + ): Promise { + const { data } = await this.workos.put( + `/authorization/organizations/${organizationId}/roles/${slug}/permissions`, + { permissions }, + ); + return deserializeOrganizationRole(data); + } + + async addOrganizationRolePermission( + organizationId: string, + slug: string, + permissionSlug: string, + ): Promise { + const { data } = await this.workos.post( + `/authorization/organizations/${organizationId}/roles/${slug}/permissions`, + { slug: permissionSlug }, + ); + return deserializeOrganizationRole(data); + } + + async removeOrganizationRolePermission( + organizationId: string, + slug: string, + permissionSlug: string, + ): Promise { + await this.workos.delete( + `/authorization/organizations/${organizationId}/roles/${slug}/permissions/${permissionSlug}`, + ); + } } diff --git a/src/authorization/fixtures/list-organization-roles.json b/src/authorization/fixtures/list-organization-roles.json new file mode 100644 index 000000000..939259ea4 --- /dev/null +++ b/src/authorization/fixtures/list-organization-roles.json @@ -0,0 +1,27 @@ +{ + "object": "list", + "data": [ + { + "object": "role", + "id": "role_01HXYZ123ABC456DEF789ORG", + "name": "Org Admin", + "slug": "org-admin", + "description": "Organization administrator", + "permissions": ["org:manage", "members:invite"], + "type": "OrganizationRole", + "created_at": "2024-01-15T09:30:00.000Z", + "updated_at": "2024-01-15T09:30:00.000Z" + }, + { + "object": "role", + "id": "role_01HXYZ123ABC456DEF789MEM", + "name": "Org Member", + "slug": "org-member", + "description": null, + "permissions": ["projects:read"], + "type": "OrganizationRole", + "created_at": "2024-01-15T10:00:00.000Z", + "updated_at": "2024-01-15T10:00:00.000Z" + } + ] +} diff --git a/src/authorization/fixtures/organization-role.json b/src/authorization/fixtures/organization-role.json new file mode 100644 index 000000000..0ae05d0cb --- /dev/null +++ b/src/authorization/fixtures/organization-role.json @@ -0,0 +1,11 @@ +{ + "object": "role", + "id": "role_01HXYZ123ABC456DEF789ORG", + "name": "Org Admin", + "slug": "org-admin", + "description": "Organization administrator", + "permissions": ["org:manage", "members:invite"], + "type": "OrganizationRole", + "created_at": "2024-01-15T09:30:00.000Z", + "updated_at": "2024-01-15T09:30:00.000Z" +} diff --git a/src/authorization/interfaces/create-organization-role-options.interface.ts b/src/authorization/interfaces/create-organization-role-options.interface.ts new file mode 100644 index 000000000..c938f3eff --- /dev/null +++ b/src/authorization/interfaces/create-organization-role-options.interface.ts @@ -0,0 +1,12 @@ +export interface CreateOrganizationRoleOptions { + organizationId: string; + slug: string; + name: string; + description?: string; +} + +export interface SerializedCreateOrganizationRoleOptions { + slug: string; + name: string; + description?: string; +} diff --git a/src/authorization/interfaces/index.ts b/src/authorization/interfaces/index.ts index 6def4d5bd..0f52d5312 100644 --- a/src/authorization/interfaces/index.ts +++ b/src/authorization/interfaces/index.ts @@ -2,3 +2,7 @@ export * from './environment-role.interface'; export * from './create-environment-role-options.interface'; export * from './update-environment-role-options.interface'; export * from './list-environment-roles-options.interface'; +export * from './organization-role.interface'; +export * from './create-organization-role-options.interface'; +export * from './update-organization-role-options.interface'; +export * from './list-organization-roles-options.interface'; diff --git a/src/authorization/interfaces/list-organization-roles-options.interface.ts b/src/authorization/interfaces/list-organization-roles-options.interface.ts new file mode 100644 index 000000000..cf1d1f58a --- /dev/null +++ b/src/authorization/interfaces/list-organization-roles-options.interface.ts @@ -0,0 +1,4 @@ +export interface ListOrganizationRolesOptions { + organizationId: string; + expand?: 'permissions'; +} diff --git a/src/authorization/interfaces/organization-role.interface.ts b/src/authorization/interfaces/organization-role.interface.ts new file mode 100644 index 000000000..56b52290e --- /dev/null +++ b/src/authorization/interfaces/organization-role.interface.ts @@ -0,0 +1,33 @@ +export interface OrganizationRole { + object: 'role'; + id: string; + name: string; + slug: string; + description: string | null; + permissions: string[]; + type: 'OrganizationRole'; + createdAt: string; + updatedAt: string; +} + +export interface OrganizationRoleResponse { + object: 'role'; + id: string; + name: string; + slug: string; + description: string | null; + permissions: string[]; + type: 'OrganizationRole'; + created_at: string; + updated_at: string; +} + +export interface OrganizationRoleList { + object: 'list'; + data: OrganizationRole[]; +} + +export interface OrganizationRoleListResponse { + object: 'list'; + data: OrganizationRoleResponse[]; +} diff --git a/src/authorization/interfaces/update-organization-role-options.interface.ts b/src/authorization/interfaces/update-organization-role-options.interface.ts new file mode 100644 index 000000000..a2fd4a314 --- /dev/null +++ b/src/authorization/interfaces/update-organization-role-options.interface.ts @@ -0,0 +1,9 @@ +export interface UpdateOrganizationRoleOptions { + name?: string; + description?: string | null; +} + +export interface SerializedUpdateOrganizationRoleOptions { + name?: string; + description?: string | null; +} diff --git a/src/authorization/serializers/create-organization-role-options.serializer.ts b/src/authorization/serializers/create-organization-role-options.serializer.ts new file mode 100644 index 000000000..f97bcebe0 --- /dev/null +++ b/src/authorization/serializers/create-organization-role-options.serializer.ts @@ -0,0 +1,12 @@ +import { + CreateOrganizationRoleOptions, + SerializedCreateOrganizationRoleOptions, +} from '../interfaces/create-organization-role-options.interface'; + +export const serializeCreateOrganizationRoleOptions = ( + options: CreateOrganizationRoleOptions, +): SerializedCreateOrganizationRoleOptions => ({ + slug: options.slug, + name: options.name, + description: options.description, +}); diff --git a/src/authorization/serializers/index.ts b/src/authorization/serializers/index.ts index 8aad90ac3..5e0f4c741 100644 --- a/src/authorization/serializers/index.ts +++ b/src/authorization/serializers/index.ts @@ -1,3 +1,6 @@ export * from './environment-role.serializer'; export * from './create-environment-role-options.serializer'; export * from './update-environment-role-options.serializer'; +export * from './organization-role.serializer'; +export * from './create-organization-role-options.serializer'; +export * from './update-organization-role-options.serializer'; diff --git a/src/authorization/serializers/organization-role.serializer.ts b/src/authorization/serializers/organization-role.serializer.ts new file mode 100644 index 000000000..061f8da49 --- /dev/null +++ b/src/authorization/serializers/organization-role.serializer.ts @@ -0,0 +1,18 @@ +import { + OrganizationRole, + OrganizationRoleResponse, +} from '../interfaces/organization-role.interface'; + +export const deserializeOrganizationRole = ( + role: OrganizationRoleResponse, +): OrganizationRole => ({ + object: role.object, + id: role.id, + name: role.name, + slug: role.slug, + description: role.description, + permissions: role.permissions, + type: role.type, + createdAt: role.created_at, + updatedAt: role.updated_at, +}); diff --git a/src/authorization/serializers/update-organization-role-options.serializer.ts b/src/authorization/serializers/update-organization-role-options.serializer.ts new file mode 100644 index 000000000..7bfc5571d --- /dev/null +++ b/src/authorization/serializers/update-organization-role-options.serializer.ts @@ -0,0 +1,11 @@ +import { + UpdateOrganizationRoleOptions, + SerializedUpdateOrganizationRoleOptions, +} from '../interfaces/update-organization-role-options.interface'; + +export const serializeUpdateOrganizationRoleOptions = ( + options: UpdateOrganizationRoleOptions, +): SerializedUpdateOrganizationRoleOptions => ({ + name: options.name, + description: options.description, +}); From 330aa9386b2007a809e4e47b2175bf00223ef51f Mon Sep 17 00:00:00 2001 From: Colin Barber Date: Thu, 29 Jan 2026 16:35:15 -0400 Subject: [PATCH 2/3] More specific types, cleaning up interfaces --- src/authorization/authorization.spec.ts | 30 +++++++++++-------- src/authorization/authorization.ts | 28 +++++++++-------- .../fixtures/list-organization-roles.json | 11 +++++++ ...ate-organization-role-options.interface.ts | 1 - ...st-organization-roles-options.interface.ts | 1 - .../interfaces/organization-role.interface.ts | 26 +++------------- .../organization-role.serializer.ts | 20 +++++++++---- 7 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/authorization/authorization.spec.ts b/src/authorization/authorization.spec.ts index bd349241c..62b48450b 100644 --- a/src/authorization/authorization.spec.ts +++ b/src/authorization/authorization.spec.ts @@ -246,12 +246,14 @@ describe('Authorization', () => { it('creates an organization role', async () => { fetchOnce(organizationRoleFixture, { status: 201 }); - const role = await workos.authorization.createOrganizationRole({ - organizationId: testOrgId, - slug: 'org-admin', - name: 'Org Admin', - description: 'Organization administrator', - }); + const role = await workos.authorization.createOrganizationRole( + testOrgId, + { + slug: 'org-admin', + name: 'Org Admin', + description: 'Organization administrator', + }, + ); expect(fetchURL()).toContain( `/authorization/organizations/${testOrgId}/roles`, @@ -272,20 +274,23 @@ describe('Authorization', () => { }); describe('listOrganizationRoles', () => { - it('returns organization roles', async () => { + it('returns both environment and organization roles', async () => { fetchOnce(listOrganizationRolesFixture); - const { data, object } = await workos.authorization.listOrganizationRoles( - { organizationId: testOrgId }, - ); + const { data, object } = + await workos.authorization.listOrganizationRoles(testOrgId); expect(fetchURL()).toContain( `/authorization/organizations/${testOrgId}/roles`, ); expect(object).toEqual('list'); - expect(data).toHaveLength(2); + expect(data).toHaveLength(3); expect(data).toEqual( expect.arrayContaining([ + expect.objectContaining({ + slug: 'admin', + type: 'EnvironmentRole', + }), expect.objectContaining({ slug: 'org-admin', type: 'OrganizationRole', @@ -301,8 +306,7 @@ describe('Authorization', () => { it('passes expand parameter', async () => { fetchOnce(listOrganizationRolesFixture); - await workos.authorization.listOrganizationRoles({ - organizationId: testOrgId, + await workos.authorization.listOrganizationRoles(testOrgId, { expand: 'permissions', }); diff --git a/src/authorization/authorization.ts b/src/authorization/authorization.ts index 238c7c856..1a4551fb1 100644 --- a/src/authorization/authorization.ts +++ b/src/authorization/authorization.ts @@ -1,4 +1,10 @@ import { WorkOS } from '../workos'; +import { + Role, + RoleList, + OrganizationRoleResponse, + ListOrganizationRolesResponse, +} from '../roles/interfaces'; import { EnvironmentRole, EnvironmentRoleResponse, @@ -8,9 +14,6 @@ import { UpdateEnvironmentRoleOptions, ListEnvironmentRolesOptions, OrganizationRole, - OrganizationRoleResponse, - OrganizationRoleList, - OrganizationRoleListResponse, CreateOrganizationRoleOptions, UpdateOrganizationRoleOptions, ListOrganizationRolesOptions, @@ -19,6 +22,7 @@ import { deserializeEnvironmentRole, serializeCreateEnvironmentRoleOptions, serializeUpdateEnvironmentRoleOptions, + deserializeRole, deserializeOrganizationRole, serializeCreateOrganizationRoleOptions, serializeUpdateOrganizationRoleOptions, @@ -95,9 +99,9 @@ export class Authorization { // === Organization Roles === async createOrganizationRole( + organizationId: string, options: CreateOrganizationRoleOptions, ): Promise { - const { organizationId, ...payload } = options; const { data } = await this.workos.post( `/authorization/organizations/${organizationId}/roles`, serializeCreateOrganizationRoleOptions(options), @@ -106,27 +110,27 @@ export class Authorization { } async listOrganizationRoles( - options: ListOrganizationRolesOptions, - ): Promise { - const { organizationId, ...query } = options; - const { data } = await this.workos.get( + organizationId: string, + options?: ListOrganizationRolesOptions, + ): Promise { + const { data } = await this.workos.get( `/authorization/organizations/${organizationId}/roles`, - { query }, + { query: options }, ); return { object: 'list', - data: data.data.map(deserializeOrganizationRole), + data: data.data.map(deserializeRole), }; } async getOrganizationRole( organizationId: string, slug: string, - ): Promise { + ): Promise { const { data } = await this.workos.get( `/authorization/organizations/${organizationId}/roles/${slug}`, ); - return deserializeOrganizationRole(data); + return deserializeRole(data); } async updateOrganizationRole( diff --git a/src/authorization/fixtures/list-organization-roles.json b/src/authorization/fixtures/list-organization-roles.json index 939259ea4..0533606d2 100644 --- a/src/authorization/fixtures/list-organization-roles.json +++ b/src/authorization/fixtures/list-organization-roles.json @@ -1,6 +1,17 @@ { "object": "list", "data": [ + { + "object": "role", + "id": "role_01HXYZ123ABC456DEF789ENV", + "name": "Admin", + "slug": "admin", + "description": "Environment-level admin role", + "permissions": ["users:read", "users:write"], + "type": "EnvironmentRole", + "created_at": "2024-01-15T08:00:00.000Z", + "updated_at": "2024-01-15T08:00:00.000Z" + }, { "object": "role", "id": "role_01HXYZ123ABC456DEF789ORG", diff --git a/src/authorization/interfaces/create-organization-role-options.interface.ts b/src/authorization/interfaces/create-organization-role-options.interface.ts index c938f3eff..09b397e69 100644 --- a/src/authorization/interfaces/create-organization-role-options.interface.ts +++ b/src/authorization/interfaces/create-organization-role-options.interface.ts @@ -1,5 +1,4 @@ export interface CreateOrganizationRoleOptions { - organizationId: string; slug: string; name: string; description?: string; diff --git a/src/authorization/interfaces/list-organization-roles-options.interface.ts b/src/authorization/interfaces/list-organization-roles-options.interface.ts index cf1d1f58a..6a6686c92 100644 --- a/src/authorization/interfaces/list-organization-roles-options.interface.ts +++ b/src/authorization/interfaces/list-organization-roles-options.interface.ts @@ -1,4 +1,3 @@ export interface ListOrganizationRolesOptions { - organizationId: string; expand?: 'permissions'; } diff --git a/src/authorization/interfaces/organization-role.interface.ts b/src/authorization/interfaces/organization-role.interface.ts index 56b52290e..71a37a331 100644 --- a/src/authorization/interfaces/organization-role.interface.ts +++ b/src/authorization/interfaces/organization-role.interface.ts @@ -1,3 +1,7 @@ +/** + * A role scoped to a specific organization. + * Distinct from EnvironmentRole which applies environment-wide. + */ export interface OrganizationRole { object: 'role'; id: string; @@ -9,25 +13,3 @@ export interface OrganizationRole { createdAt: string; updatedAt: string; } - -export interface OrganizationRoleResponse { - object: 'role'; - id: string; - name: string; - slug: string; - description: string | null; - permissions: string[]; - type: 'OrganizationRole'; - created_at: string; - updated_at: string; -} - -export interface OrganizationRoleList { - object: 'list'; - data: OrganizationRole[]; -} - -export interface OrganizationRoleListResponse { - object: 'list'; - data: OrganizationRoleResponse[]; -} diff --git a/src/authorization/serializers/organization-role.serializer.ts b/src/authorization/serializers/organization-role.serializer.ts index 061f8da49..3e20278d8 100644 --- a/src/authorization/serializers/organization-role.serializer.ts +++ b/src/authorization/serializers/organization-role.serializer.ts @@ -1,7 +1,17 @@ -import { - OrganizationRole, - OrganizationRoleResponse, -} from '../interfaces/organization-role.interface'; +import { Role, OrganizationRoleResponse } from '../../roles/interfaces'; +import { OrganizationRole } from '../interfaces'; + +export const deserializeRole = (role: OrganizationRoleResponse): Role => ({ + object: role.object, + id: role.id, + name: role.name, + slug: role.slug, + description: role.description, + permissions: role.permissions, + type: role.type, + createdAt: role.created_at, + updatedAt: role.updated_at, +}); export const deserializeOrganizationRole = ( role: OrganizationRoleResponse, @@ -12,7 +22,7 @@ export const deserializeOrganizationRole = ( slug: role.slug, description: role.description, permissions: role.permissions, - type: role.type, + type: 'OrganizationRole', createdAt: role.created_at, updatedAt: role.updated_at, }); From 3276b31aaffb36ce4cd19567cb7eb5810ccca15b Mon Sep 17 00:00:00 2001 From: Colin Barber Date: Fri, 30 Jan 2026 09:37:49 -0400 Subject: [PATCH 3/3] Remove comments --- src/authorization/authorization.spec.ts | 2 -- src/authorization/authorization.ts | 4 ---- src/authorization/interfaces/organization-role.interface.ts | 4 ---- 3 files changed, 10 deletions(-) diff --git a/src/authorization/authorization.spec.ts b/src/authorization/authorization.spec.ts index 62b48450b..f56044b09 100644 --- a/src/authorization/authorization.spec.ts +++ b/src/authorization/authorization.spec.ts @@ -240,8 +240,6 @@ describe('Authorization', () => { }); }); - // === Organization Roles === - describe('createOrganizationRole', () => { it('creates an organization role', async () => { fetchOnce(organizationRoleFixture, { status: 201 }); diff --git a/src/authorization/authorization.ts b/src/authorization/authorization.ts index 1a4551fb1..8324095ef 100644 --- a/src/authorization/authorization.ts +++ b/src/authorization/authorization.ts @@ -31,8 +31,6 @@ import { export class Authorization { constructor(private readonly workos: WorkOS) {} - // === Environment Roles === - async createEnvironmentRole( options: CreateEnvironmentRoleOptions, ): Promise { @@ -96,8 +94,6 @@ export class Authorization { return deserializeEnvironmentRole(data); } - // === Organization Roles === - async createOrganizationRole( organizationId: string, options: CreateOrganizationRoleOptions, diff --git a/src/authorization/interfaces/organization-role.interface.ts b/src/authorization/interfaces/organization-role.interface.ts index 71a37a331..d17f850f4 100644 --- a/src/authorization/interfaces/organization-role.interface.ts +++ b/src/authorization/interfaces/organization-role.interface.ts @@ -1,7 +1,3 @@ -/** - * A role scoped to a specific organization. - * Distinct from EnvironmentRole which applies environment-wide. - */ export interface OrganizationRole { object: 'role'; id: string;