Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
310eeb1
Authorization Resources endpoints for Internal ID
swaroopAkkineniWorkos Feb 9, 2026
685643c
lol
swaroopAkkineniWorkos Feb 9, 2026
107fc6c
Merge branch 'main' into ENT-4372-Internal-ID
swaroopAkkineniWorkos Feb 9, 2026
ea2628e
lol
swaroopAkkineniWorkos Feb 9, 2026
543b121
lol
swaroopAkkineniWorkos Feb 9, 2026
c2734e8
moar
swaroopAkkineniWorkos Feb 9, 2026
5037673
lol
swaroopAkkineniWorkos Feb 9, 2026
ca6f2d1
lol
swaroopAkkineniWorkos Feb 9, 2026
dfdd37d
lol
swaroopAkkineniWorkos Feb 9, 2026
43a0765
lol
swaroopAkkineniWorkos Feb 9, 2026
b61be8a
pretty
swaroopAkkineniWorkos Feb 9, 2026
0b65b75
moar
swaroopAkkineniWorkos Feb 9, 2026
9281d60
remove
swaroopAkkineniWorkos Feb 9, 2026
24f6758
moar
swaroopAkkineniWorkos Feb 10, 2026
ea41192
moar
swaroopAkkineniWorkos Feb 10, 2026
6fb444c
moar
swaroopAkkineniWorkos Feb 10, 2026
5689bee
moar
swaroopAkkineniWorkos Feb 10, 2026
1cb2d25
Merge branch 'main' into ENT-4372-Internal-ID
swaroopAkkineniWorkos Feb 10, 2026
f77627f
lol
swaroopAkkineniWorkos Feb 10, 2026
1ddca39
comments
swaroopAkkineniWorkos Feb 10, 2026
3e87446
moar
swaroopAkkineniWorkos Feb 10, 2026
7364e46
moar
swaroopAkkineniWorkos Feb 10, 2026
0dc5d30
moar
swaroopAkkineniWorkos Feb 10, 2026
be4b7d3
lol
swaroopAkkineniWorkos Feb 10, 2026
b38b24d
lol
swaroopAkkineniWorkos Feb 10, 2026
fc934f0
moar
swaroopAkkineniWorkos Feb 10, 2026
de58c56
Add missing `before` pagination parameter test for listResources
swaroopAkkineniWorkos Feb 10, 2026
1d6124d
lol
swaroopAkkineniWorkos Feb 10, 2026
64383ed
lol
swaroopAkkineniWorkos Feb 10, 2026
bb2fb27
lol
swaroopAkkineniWorkos Feb 10, 2026
6389419
merge conflicts
swaroopAkkineniWorkos Feb 11, 2026
53d03ba
union of parentResourceExternalId & parentResourceTypeSlug (#1480)
swaroopAkkineniWorkos Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
403 changes: 340 additions & 63 deletions src/authorization/authorization.spec.ts

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions src/authorization/authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ import {
ListPermissionsOptions,
AuthorizationResource,
AuthorizationResourceResponse,
AuthorizationResourceList,
AuthorizationResourceListResponse,
ListAuthorizationResourcesOptions,
GetAuthorizationResourceByExternalIdOptions,
UpdateAuthorizationResourceByExternalIdOptions,
DeleteAuthorizationResourceByExternalIdOptions,
CreateAuthorizationResourceOptions,
UpdateAuthorizationResourceOptions,
AuthorizationCheckOptions,
Expand All @@ -48,6 +54,8 @@ import {
deserializeAuthorizationResource,
serializeCreateResourceOptions,
serializeUpdateResourceOptions,
serializeUpdateResourceByExternalIdOptions,
serializeListAuthorizationResourcesOptions,
serializeAuthorizationCheckOptions,
} from './serializers';

Expand Down Expand Up @@ -280,6 +288,57 @@ export class Authorization {
await this.workos.delete(`/authorization/resources/${resourceId}`);
}

async listResources(
options?: ListAuthorizationResourcesOptions,
): Promise<AuthorizationResourceList> {
const { data } = await this.workos.get<AuthorizationResourceListResponse>(
'/authorization/resources',
{
query: options
? serializeListAuthorizationResourcesOptions(options)
: undefined,
},
);
return {
object: 'list',
data: data.data.map(deserializeAuthorizationResource),
listMetadata: {
before: data.list_metadata.before,
after: data.list_metadata.after,
},
};
}

async getResourceByExternalId(
options: GetAuthorizationResourceByExternalIdOptions,
): Promise<AuthorizationResource> {
const { organizationId, resourceTypeSlug, externalId } = options;
const { data } = await this.workos.get<AuthorizationResourceResponse>(
`/authorization/organizations/${organizationId}/resources/${resourceTypeSlug}/${externalId}`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: could externalId contain URL-significant characters? Not sure if this is gated elsewhere but could be good to wrap with encodeURIComponent.

);
return deserializeAuthorizationResource(data);
}

async updateResourceByExternalId(
options: UpdateAuthorizationResourceByExternalIdOptions,
): Promise<AuthorizationResource> {
const { organizationId, resourceTypeSlug, externalId } = options;
const { data } = await this.workos.patch<AuthorizationResourceResponse>(
`/authorization/organizations/${organizationId}/resources/${resourceTypeSlug}/${externalId}`,
serializeUpdateResourceByExternalIdOptions(options),
);
return deserializeAuthorizationResource(data);
}

async deleteResourceByExternalId(
options: DeleteAuthorizationResourceByExternalIdOptions,
): Promise<void> {
const { organizationId, resourceTypeSlug, externalId } = options;
await this.workos.delete(
`/authorization/organizations/${organizationId}/resources/${resourceTypeSlug}/${externalId}`,
);
}

async check(
options: AuthorizationCheckOptions,
): Promise<AuthorizationCheckResult> {
Expand Down
33 changes: 33 additions & 0 deletions src/authorization/fixtures/list-resources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"object": "list",
"data": [
{
"object": "authorization_resource",
"id": "authz_resource_01HXYZ123ABC456DEF789ABC",
"external_id": "doc-12345678",
"name": "Q5 Budget Report",
"description": "Financial report for Q5 2025",
"resource_type_slug": "document",
"organization_id": "org_01HXYZ123ABC456DEF789ABC",
"parent_resource_id": "authz_resource_01HXYZ123ABC456DEF789XYZ",
"created_at": "2024-01-15T09:30:00.000Z",
"updated_at": "2024-01-15T09:30:00.000Z"
},
{
"object": "authorization_resource",
"id": "authz_resource_01HXYZ123ABC456DEF789DEF",
"external_id": "folder-123",
"name": "Finance Folder",
"description": null,
"resource_type_slug": "folder",
"organization_id": "org_01HXYZ123ABC456DEF789ABC",
"parent_resource_id": null,
"created_at": "2024-01-14T08:00:00.000Z",
"updated_at": "2024-01-14T08:00:00.000Z"
}
],
"list_metadata": {
"before": null,
"after": "authz_resource_01HXYZ123ABC456DEF789DEF"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,27 @@ export interface AuthorizationResourceResponse {
updated_at: string;
}

export interface CreateAuthorizationResourceOptions {
interface BaseCreateAuthorizationResourceOptions {
externalId: string;
name: string;
description?: string | null;
resourceTypeSlug: string;
organizationId: string;
parentResourceId?: string | null;
parentResourceExternalId?: string | null;
parentResourceTypeSlug?: string | null;
}

export interface CreateOptionsWithParentResourceId extends BaseCreateAuthorizationResourceOptions {
parentResourceId: string;
}

export interface CreateOptionsWithParentExternalId extends BaseCreateAuthorizationResourceOptions {
parentResourceExternalId: string;
parentResourceTypeSlug: string;
}

export type CreateAuthorizationResourceOptions =
| CreateOptionsWithParentResourceId
| CreateOptionsWithParentExternalId;

export interface SerializedCreateAuthorizationResourceOptions {
external_id: string;
name: string;
Expand All @@ -56,3 +66,21 @@ export interface SerializedUpdateAuthorizationResourceOptions {
name?: string;
description?: string | null;
}

export interface AuthorizationResourceList {
object: 'list';
data: AuthorizationResource[];
listMetadata: {
before: string | null;
after: string | null;
};
}

export interface AuthorizationResourceListResponse {
object: 'list';
data: AuthorizationResourceResponse[];
list_metadata: {
before: string | null;
after: string | null;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface DeleteAuthorizationResourceByExternalIdOptions {
organizationId: string;
resourceTypeSlug: string;
externalId: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface GetAuthorizationResourceByExternalIdOptions {
organizationId: string;
resourceTypeSlug: string;
externalId: string;
}
4 changes: 4 additions & 0 deletions src/authorization/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ export * from './create-permission-options.interface';
export * from './update-permission-options.interface';
export * from './list-permissions-options.interface';
export * from './authorization-resource.interface';
export * from './list-authorization-resources-options.interface';
export * from './get-authorization-resource-by-external-id-options.interface';
export * from './update-authorization-resource-by-external-id-options.interface';
export * from './delete-authorization-resource-by-external-id-options.interface';
export * from './authorization-resource-check.interface';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { PaginationOptions } from '../../common/interfaces/pagination-options.interface';

export interface ListAuthorizationResourcesOptions extends PaginationOptions {
organizationIds?: string[];
resourceTypeSlugs?: string[];
parentResourceId?: string;
parentResourceTypeSlug?: string;
parentExternalId?: string;
search?: string;
}

export interface SerializedListAuthorizationResourcesOptions {
organization_ids?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a ticket to change this and slugs to singular organization_id, resource_type_slug

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update with a change once it is merged

resource_type_slugs?: string;
parent_resource_id?: string;
parent_resource_type_slug?: string;
parent_external_id?: string;
search?: string;
limit?: number;
after?: string;
before?: string;
order?: 'asc' | 'desc';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface UpdateAuthorizationResourceByExternalIdOptions {
organizationId: string;
resourceTypeSlug: string;
externalId: string;
name?: string;
description?: string | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ export const serializeCreateResourceOptions = (
...(options.description !== undefined && {
description: options.description,
}),
...(options.parentResourceId !== undefined && {
...('parentResourceId' in options && {
parent_resource_id: options.parentResourceId,
}),
...(options.parentResourceExternalId !== undefined && {
...('parentResourceExternalId' in options && {
parent_resource_external_id: options.parentResourceExternalId,
}),
...(options.parentResourceTypeSlug !== undefined && {
parent_resource_type_slug: options.parentResourceTypeSlug,
}),
});
2 changes: 2 additions & 0 deletions src/authorization/serializers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ export * from './update-permission-options.serializer';
export * from './authorization-resource.serializer';
export * from './create-authorization-resource-options.serializer';
export * from './update-authorization-resource-options.serializer';
export * from './update-authorization-resource-by-external-id-options.serializer';
export * from './list-authorization-resources-options.serializer';
export * from './authorization-check-options.serializer';
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
ListAuthorizationResourcesOptions,
SerializedListAuthorizationResourcesOptions,
} from '../interfaces/list-authorization-resources-options.interface';

export const serializeListAuthorizationResourcesOptions = (
options: ListAuthorizationResourcesOptions,
): SerializedListAuthorizationResourcesOptions => ({
...(options.organizationIds && {
organization_ids: options.organizationIds.join(','),
}),
...(options.resourceTypeSlugs && {
resource_type_slugs: options.resourceTypeSlugs.join(','),
}),
...(options.parentResourceId && {
parent_resource_id: options.parentResourceId,
}),
...(options.parentResourceTypeSlug && {
parent_resource_type_slug: options.parentResourceTypeSlug,
}),
...(options.parentExternalId && {
parent_external_id: options.parentExternalId,
}),
...(options.search && { search: options.search }),
...(options.limit !== undefined && { limit: options.limit }),
...(options.after && { after: options.after }),
...(options.before && { before: options.before }),
...(options.order && { order: options.order }),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { UpdateAuthorizationResourceByExternalIdOptions } from '../interfaces/update-authorization-resource-by-external-id-options.interface';
import { SerializedUpdateAuthorizationResourceOptions } from '../interfaces/authorization-resource.interface';

export const serializeUpdateResourceByExternalIdOptions = (
options: UpdateAuthorizationResourceByExternalIdOptions,
): SerializedUpdateAuthorizationResourceOptions => ({
...(options.name !== undefined && { name: options.name }),
...(options.description !== undefined && {
description: options.description,
}),
});