Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(backend): Introduce OrganizationPermissionAPI #2178

Merged
merged 1 commit into from
Nov 22, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/swift-rocks-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@clerk/clerk-sdk-node': patch
'@clerk/backend': patch
'@clerk/nextjs': patch
---

Add OrganizationPermissionAPI for CRUD operations regarding instance level organization permissions.
69 changes: 69 additions & 0 deletions packages/backend/src/api/endpoints/OrganizationPermissionApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { joinPaths } from '../../util/path';
import type { DeletedObject, Permission } from '../resources';
import { AbstractAPI } from './AbstractApi';

const basePath = '/organizations_permissions';

type GetOrganizationPermissionListParams = {
limit?: number;
offset?: number;
query?: string;
orderBy?: string;
};

type CreateParams = {
name: string;
key: string;
description: string;
};

type GetOrganizationPermissionParams = { permissionId: string };

type UpdateParams = {
name?: string;
key?: string;
description?: string;
};

export class OrganizationPermissionAPI extends AbstractAPI {
public async getOrganizationPermissionList(params?: GetOrganizationPermissionListParams) {
return this.request<Permission[]>({
method: 'GET',
path: basePath,
queryParams: params,
});
}

public async createOrganizationPermission(params: CreateParams) {
return this.request<Permission>({
method: 'POST',
path: basePath,
bodyParams: params,
});
}

public async getOrganizationPermission(params: GetOrganizationPermissionParams) {
this.requireId(params.permissionId);

return this.request<Permission>({
method: 'GET',
path: joinPaths(basePath, params.permissionId),
});
}

public async updateOrganizationPermission(permissionId: string, params: UpdateParams) {
this.requireId(permissionId);
return this.request<Permission>({
method: 'PATCH',
path: joinPaths(basePath, permissionId),
bodyParams: params,
});
}

public async deleteOrganizationPermission(permissionId: string) {
return this.request<DeletedObject>({
method: 'DELETE',
path: joinPaths(basePath, permissionId),
});
}
}
1 change: 1 addition & 0 deletions packages/backend/src/api/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './EmailApi';
export * from './InterstitialApi';
export * from './InvitationApi';
export * from './OrganizationApi';
export * from './OrganizationPermissionApi';
export * from './PhoneNumberApi';
export * from './RedirectUrlApi';
export * from './SessionApi';
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/api/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
InterstitialAPI,
InvitationAPI,
OrganizationAPI,
OrganizationPermissionAPI,
PhoneNumberAPI,
RedirectUrlAPI,
SessionAPI,
Expand All @@ -22,7 +23,6 @@ export type ApiClient = ReturnType<typeof createBackendApiClient>;

export function createBackendApiClient(options: CreateBackendApiOptions) {
const request = buildRequest(options);

return {
allowlistIdentifiers: new AllowlistIdentifierAPI(request),
clients: new ClientAPI(request),
Expand All @@ -31,6 +31,7 @@ export function createBackendApiClient(options: CreateBackendApiOptions) {
interstitial: new InterstitialAPI(request),
invitations: new InvitationAPI(request),
organizations: new OrganizationAPI(request),
organizationPermissions: new OrganizationPermissionAPI(request),
phoneNumbers: new PhoneNumberAPI(request),
redirectUrls: new RedirectUrlAPI(request),
sessions: new SessionAPI(request),
Expand Down
5 changes: 5 additions & 0 deletions packages/backend/src/api/resources/Enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export type OAuthStrategy = `oauth_${OAuthProvider}`;

export type OrganizationInvitationStatus = 'pending' | 'accepted' | 'revoked';

export type PermissionType = 'system' | 'user';

/**
* @deprecated In the next major release this type will change to string
Copy link
Member

Choose a reason for hiding this comment

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

馃敡 If we have added the OrganizationMembershipRole in v4 (release/v4), we could add the deprecation in the v4 version and replace it with the new API in v5 version (main branch)

Copy link
Member Author

Choose a reason for hiding this comment

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

Here's what i was thinking, I merge this and backport it and then create another PR to address this that will not be backported

*/
export type OrganizationMembershipRole = 'basic_member' | 'guest_member' | 'admin';

export type SignInStatus = 'needs_identifier' | 'needs_factor_one' | 'needs_factor_two' | 'complete';
Expand Down
13 changes: 13 additions & 0 deletions packages/backend/src/api/resources/JSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
InvitationStatus,
OrganizationInvitationStatus,
OrganizationMembershipRole,
PermissionType,
SignInStatus,
SignUpAttributeRequirements,
SignUpStatus,
Expand All @@ -20,6 +21,7 @@ export enum ObjectType {
Organization = 'organization',
OrganizationInvitation = 'organization_invitation',
OrganizationMembership = 'organization_membership',
Permission = 'permission',
PhoneNumber = 'phone_number',
RedirectUrl = 'redirect_url',
Session = 'session',
Expand Down Expand Up @@ -172,6 +174,17 @@ export interface OrganizationMembershipPublicUserDataJSON {
user_id: string;
}

export interface PermissionJSON extends ClerkResourceJSON {
object: ObjectType.Permission;
id: string;
name: string;
key: string;
description: string;
type: PermissionType;
created_at: number;
updated_at: number;
}

export interface PhoneNumberJSON extends ClerkResourceJSON {
object: ObjectType.PhoneNumber;
phone_number: string;
Expand Down
18 changes: 18 additions & 0 deletions packages/backend/src/api/resources/Permission.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { PermissionType } from './Enums';
import type { PermissionJSON } from './JSON';

export class Permission {
constructor(
readonly id: string,
readonly name: string,
readonly key: string,
readonly description: string,
readonly type: PermissionType,
readonly createdAt: number,
readonly updatedAt: number,
) {}

static fromJSON(data: PermissionJSON) {
return new Permission(data.id, data.name, data.key, data.description, data.type, data.created_at, data.updated_at);
}
}
1 change: 1 addition & 0 deletions packages/backend/src/api/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './Invitation';
export * from './JSON';
export * from './OauthAccessToken';
export * from './Organization';
export * from './Permission';
export * from './OrganizationInvitation';
export * from './OrganizationMembership';
export * from './PhoneNumber';
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/exports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default (QUnit: QUnit) => {
'OrganizationInvitation',
'OrganizationMembership',
'OrganizationMembershipPublicUserData',
'Permission',
'PhoneNumber',
'RedirectUrl',
'SMSMessage',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exports[`/server public exports should not include a breaking change 1`] = `
"OrganizationInvitation",
"OrganizationMembership",
"OrganizationMembershipPublicUserData",
"Permission",
"PhoneNumber",
"RedirectUrl",
"SMSMessage",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ exports[`module exports should not change unless explicitly set 1`] = `
"OrganizationInvitation",
"OrganizationMembership",
"OrganizationMembershipPublicUserData",
"Permission",
"PhoneNumber",
"RedirectUrl",
"SMSMessage",
Expand Down Expand Up @@ -52,6 +53,7 @@ exports[`module exports should not change unless explicitly set 1`] = `
"invitations",
"loadInterstitialFromLocal",
"makeAuthObjectSerializable",
"organizationPermissions",
"organizations",
"phoneNumbers",
"prunePrivateMetadata",
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk-node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const {
emails,
invitations,
organizations,
organizationPermissions,
clients,
allowlistIdentifiers,
domains,
Expand All @@ -40,6 +41,7 @@ export {
emails,
invitations,
organizations,
organizationPermissions,
phoneNumbers,
sessions,
smsMessages,
Expand Down