Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
239 changes: 239 additions & 0 deletions src/authorization/authorization.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import fetch from 'jest-fetch-mock';
import {
fetchOnce,
fetchURL,
fetchSearchParams,
fetchBody,
} from '../common/utils/test-utils';
import { WorkOS } from '../workos';
import environmentRoleFixture from './fixtures/environment-role.json';
import listEnvironmentRolesFixture from './fixtures/list-environment-roles.json';

const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');

describe('Authorization', () => {
beforeEach(() => fetch.resetMocks());

describe('createEnvironmentRole', () => {
it('creates an environment role', async () => {
fetchOnce(environmentRoleFixture, { status: 201 });

const role = await workos.authorization.createEnvironmentRole({
slug: 'admin',
name: 'Admin',
description: 'Full administrative access',
});

expect(fetchURL()).toContain('/authorization/roles');
expect(fetchBody()).toEqual({
slug: 'admin',
name: 'Admin',
description: 'Full administrative access',
});
expect(role).toMatchObject({
object: 'role',
id: 'role_01HXYZ123ABC456DEF789GHI',
slug: 'admin',
name: 'Admin',
description: 'Full administrative access',
type: 'EnvironmentRole',
});
expect(role.permissions).toEqual(
expect.arrayContaining([
'users:read',
'users:write',
'settings:manage',
]),
);
});

it('creates an environment role without description', async () => {
fetchOnce(
{ ...environmentRoleFixture, description: null },
{ status: 201 },
);

const role = await workos.authorization.createEnvironmentRole({
slug: 'member',
name: 'Member',
});

expect(fetchBody()).toEqual({
slug: 'member',
name: 'Member',
});
expect(role.description).toBeNull();
});
});

describe('listEnvironmentRoles', () => {
it('returns environment roles', async () => {
fetchOnce(listEnvironmentRolesFixture);

const { data, object } =
await workos.authorization.listEnvironmentRoles();

expect(fetchURL()).toContain('/authorization/roles');
expect(object).toEqual('list');
expect(data).toHaveLength(2);
expect(data).toEqual(
expect.arrayContaining([
expect.objectContaining({
object: 'role',
id: 'role_01HXYZ123ABC456DEF789GHI',
slug: 'admin',
name: 'Admin',
type: 'EnvironmentRole',
}),
expect.objectContaining({
object: 'role',
id: 'role_01HXYZ123ABC456DEF789GHJ',
slug: 'member',
name: 'Member',
type: 'EnvironmentRole',
}),
]),
);
});

it('passes expand parameter', async () => {
fetchOnce(listEnvironmentRolesFixture);

await workos.authorization.listEnvironmentRoles({
expand: 'permissions',
});

expect(fetchSearchParams()).toEqual({
expand: 'permissions',
});
});
});

describe('getEnvironmentRole', () => {
it('gets an environment role by slug', async () => {
fetchOnce(environmentRoleFixture);

const role = await workos.authorization.getEnvironmentRole('admin');

expect(fetchURL()).toContain('/authorization/roles/admin');
expect(role).toMatchObject({
object: 'role',
id: 'role_01HXYZ123ABC456DEF789GHI',
slug: 'admin',
name: 'Admin',
description: 'Full administrative access',
type: 'EnvironmentRole',
});
});
});

describe('updateEnvironmentRole', () => {
it('updates an environment role', async () => {
const updatedRoleFixture = {
...environmentRoleFixture,
name: 'Super Admin',
description: 'Updated description',
};
fetchOnce(updatedRoleFixture);

const role = await workos.authorization.updateEnvironmentRole('admin', {
name: 'Super Admin',
description: 'Updated description',
});

expect(fetchURL()).toContain('/authorization/roles/admin');
expect(fetchBody()).toEqual({
name: 'Super Admin',
description: 'Updated description',
});
expect(role).toMatchObject({
name: 'Super Admin',
description: 'Updated description',
});
});

it('clears description when set to null', async () => {
const updatedRoleFixture = {
...environmentRoleFixture,
description: null,
};
fetchOnce(updatedRoleFixture);

const role = await workos.authorization.updateEnvironmentRole('admin', {
description: null,
});

expect(fetchBody()).toEqual({
description: null,
});
expect(role.description).toBeNull();
});
});

describe('setEnvironmentRolePermissions', () => {
it('sets permissions for an environment role', async () => {
const updatedRoleFixture = {
...environmentRoleFixture,
permissions: ['users:read', 'users:write'],
};
fetchOnce(updatedRoleFixture);

const role = await workos.authorization.setEnvironmentRolePermissions(
'admin',
{ permissions: ['users:read', 'users:write'] },
);

expect(fetchURL()).toContain('/authorization/roles/admin/permissions');
expect(fetchBody()).toEqual({
permissions: ['users:read', 'users:write'],
});
expect(role.permissions).toHaveLength(2);
expect(role.permissions).toEqual(
expect.arrayContaining(['users:read', 'users:write']),
);
});

it('clears all permissions when given empty array', async () => {
const updatedRoleFixture = { ...environmentRoleFixture, permissions: [] };
fetchOnce(updatedRoleFixture);

const role = await workos.authorization.setEnvironmentRolePermissions(
'admin',
{ permissions: [] },
);

expect(fetchBody()).toEqual({
permissions: [],
});
expect(role.permissions).toHaveLength(0);
});
});

describe('addEnvironmentRolePermission', () => {
it('adds a permission to an environment role', async () => {
const updatedRoleFixture = {
...environmentRoleFixture,
permissions: [
'users:read',
'users:write',
'settings:manage',
'billing:read',
],
};
fetchOnce(updatedRoleFixture);

const role = await workos.authorization.addEnvironmentRolePermission(
'admin',
{ permissionSlug: 'billing:read' },
);

expect(fetchURL()).toContain('/authorization/roles/admin/permissions');
expect(fetchBody()).toEqual({
slug: 'billing:read',
});
expect(role.permissions).toEqual(
expect.arrayContaining(['billing:read']),
);
});
});
});
84 changes: 84 additions & 0 deletions src/authorization/authorization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { WorkOS } from '../workos';
import {
EnvironmentRole,
EnvironmentRoleResponse,
EnvironmentRoleList,
EnvironmentRoleListResponse,
CreateEnvironmentRoleOptions,
UpdateEnvironmentRoleOptions,
ListEnvironmentRolesOptions,
SetEnvironmentRolePermissionsOptions,
AddEnvironmentRolePermissionOptions,
} from './interfaces';
import {
deserializeEnvironmentRole,
serializeCreateEnvironmentRoleOptions,
serializeUpdateEnvironmentRoleOptions,
} from './serializers';

export class Authorization {
constructor(private readonly workos: WorkOS) {}

async createEnvironmentRole(
options: CreateEnvironmentRoleOptions,
): Promise<EnvironmentRole> {
const { data } = await this.workos.post<EnvironmentRoleResponse>(
'/authorization/roles',
serializeCreateEnvironmentRoleOptions(options),
);
return deserializeEnvironmentRole(data);
}

async listEnvironmentRoles(
options?: ListEnvironmentRolesOptions,
): Promise<EnvironmentRoleList> {
const { data } = await this.workos.get<EnvironmentRoleListResponse>(
'/authorization/roles',
{ query: options },
);
return {
object: 'list',
data: data.data.map(deserializeEnvironmentRole),
};
}

async getEnvironmentRole(slug: string): Promise<EnvironmentRole> {
const { data } = await this.workos.get<EnvironmentRoleResponse>(
`/authorization/roles/${slug}`,
);
return deserializeEnvironmentRole(data);
}

async updateEnvironmentRole(
slug: string,
options: UpdateEnvironmentRoleOptions,
): Promise<EnvironmentRole> {
const { data } = await this.workos.patch<EnvironmentRoleResponse>(
`/authorization/roles/${slug}`,
serializeUpdateEnvironmentRoleOptions(options),
);
return deserializeEnvironmentRole(data);
}

async setEnvironmentRolePermissions(
slug: string,
options: SetEnvironmentRolePermissionsOptions,
): Promise<EnvironmentRole> {
const { data } = await this.workos.put<EnvironmentRoleResponse>(
`/authorization/roles/${slug}/permissions`,
{ permissions: options.permissions },
);
return deserializeEnvironmentRole(data);
}

async addEnvironmentRolePermission(
slug: string,
options: AddEnvironmentRolePermissionOptions,
): Promise<EnvironmentRole> {
const { data } = await this.workos.post<EnvironmentRoleResponse>(
`/authorization/roles/${slug}/permissions`,
{ slug: options.permissionSlug },
);
return deserializeEnvironmentRole(data);
}
}
11 changes: 11 additions & 0 deletions src/authorization/fixtures/environment-role-member.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"object": "role",
"id": "role_01HXYZ123ABC456DEF789GHJ",
"name": "Member",
"slug": "member",
"description": null,
"permissions": ["posts:read"],
"type": "EnvironmentRole",
"created_at": "2024-01-15T10:00:00.000Z",
"updated_at": "2024-01-15T10:00:00.000Z"
}
11 changes: 11 additions & 0 deletions src/authorization/fixtures/environment-role.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"object": "role",
"id": "role_01HXYZ123ABC456DEF789GHI",
"name": "Admin",
"slug": "admin",
"description": "Full administrative access",
"permissions": ["users:read", "users:write", "settings:manage"],
"type": "EnvironmentRole",
"created_at": "2024-01-15T09:30:00.000Z",
"updated_at": "2024-01-15T09:30:00.000Z"
}
27 changes: 27 additions & 0 deletions src/authorization/fixtures/list-environment-roles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"object": "list",
"data": [
{
"object": "role",
"id": "role_01HXYZ123ABC456DEF789GHI",
"name": "Admin",
"slug": "admin",
"description": "Full administrative access",
"permissions": ["users:read", "users:write", "settings:manage"],
"type": "EnvironmentRole",
"created_at": "2024-01-15T09:30:00.000Z",
"updated_at": "2024-01-15T09:30:00.000Z"
},
{
"object": "role",
"id": "role_01HXYZ123ABC456DEF789GHJ",
"name": "Member",
"slug": "member",
"description": null,
"permissions": ["posts:read"],
"type": "EnvironmentRole",
"created_at": "2024-01-15T10:00:00.000Z",
"updated_at": "2024-01-15T10:00:00.000Z"
}
]
}
2 changes: 2 additions & 0 deletions src/authorization/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './authorization';
export * from './interfaces';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface AddEnvironmentRolePermissionOptions {
permissionSlug: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface CreateEnvironmentRoleOptions {
slug: string;
name: string;
description?: string;
}

export interface SerializedCreateEnvironmentRoleOptions {
slug: string;
name: string;
description?: string;
}
Loading