From 045648d410064bf84b65aae677b54239a69e0257 Mon Sep 17 00:00:00 2001 From: Nicolas Lopes Date: Wed, 25 Sep 2024 17:23:58 -0300 Subject: [PATCH 1/2] feat(backend,types): create organizationDomain API --- .changeset/tame-forks-type.md | 6 ++ .../src/api/endpoints/OrganizationApi.ts | 79 ++++++++++++++++++- .../src/api/resources/OrganizationDomain.ts | 33 ++++++++ .../backend/src/api/resources/Verification.ts | 15 ++++ packages/backend/src/api/resources/index.ts | 2 + packages/types/src/json.ts | 2 +- 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 .changeset/tame-forks-type.md create mode 100644 packages/backend/src/api/resources/OrganizationDomain.ts diff --git a/.changeset/tame-forks-type.md b/.changeset/tame-forks-type.md new file mode 100644 index 00000000000..f3a28812a6a --- /dev/null +++ b/.changeset/tame-forks-type.md @@ -0,0 +1,6 @@ +--- +"@clerk/backend": patch +"@clerk/types": patch +--- + +Introduces the CRUD of organization domains under the `organizations` API. diff --git a/packages/backend/src/api/endpoints/OrganizationApi.ts b/packages/backend/src/api/endpoints/OrganizationApi.ts index b11b4d06576..23fd7ccb356 100644 --- a/packages/backend/src/api/endpoints/OrganizationApi.ts +++ b/packages/backend/src/api/endpoints/OrganizationApi.ts @@ -1,9 +1,10 @@ -import type { ClerkPaginationRequest } from '@clerk/types'; +import type { ClerkPaginationRequest, OrganizationEnrollmentMode } from '@clerk/types'; import runtime from '../../runtime'; import { joinPaths } from '../../util/path'; import type { Organization, + OrganizationDomain, OrganizationInvitation, OrganizationInvitationStatus, OrganizationMembership, @@ -99,6 +100,29 @@ type RevokeOrganizationInvitationParams = { requestingUserId: string; }; +type GetOrganizationDomainListParams = { + organizationId: string; + limit?: number; + offset?: number; +}; + +type CreateOrganizationDomainParams = { + organizationId: string; + name: string; + enrollmentMode: OrganizationEnrollmentMode; + verified?: boolean; +}; + +type UpdateOrganizationDomainParams = { + organizationId: string; + domainId: string; +} & Partial; + +type DeleteOrganizationDomainParams = { + organizationId: string; + domainId: string; +}; + export class OrganizationAPI extends AbstractAPI { public async getOrganizationList(params?: GetOrganizationListParams) { return this.request>({ @@ -285,4 +309,57 @@ export class OrganizationAPI extends AbstractAPI { }, }); } + + public async getOrganizationDomainList(params: GetOrganizationDomainListParams) { + const { organizationId, limit, offset } = params; + this.requireId(organizationId); + + return this.request>({ + method: 'GET', + path: joinPaths(basePath, organizationId, 'domains'), + queryParams: { limit, offset }, + }); + } + + public async createOrganizationDomain(params: CreateOrganizationDomainParams) { + const { organizationId, name, enrollmentMode, verified = true } = params; + this.requireId(organizationId); + + return this.request({ + method: 'POST', + path: joinPaths(basePath, organizationId, 'domains'), + bodyParams: { + name, + enrollmentMode, + verified, + }, + }); + } + + public async updateOrganizationDomain(params: UpdateOrganizationDomainParams) { + const { organizationId, domainId, enrollmentMode, name, verified } = params; + this.requireId(organizationId); + this.requireId(domainId); + + return this.request({ + method: 'PATCH', + path: joinPaths(basePath, organizationId, 'domains', domainId), + bodyParams: { + ...(enrollmentMode && { enrollment_mode: enrollmentMode }), + ...(name && { name }), + ...(verified !== undefined && { verified }), + }, + }); + } + + public async deleteOrganizationDomain(params: DeleteOrganizationDomainParams) { + const { organizationId, domainId } = params; + this.requireId(organizationId); + this.requireId(domainId); + + return this.request({ + method: 'DELETE', + path: joinPaths(basePath, organizationId, 'domains', domainId), + }); + } } diff --git a/packages/backend/src/api/resources/OrganizationDomain.ts b/packages/backend/src/api/resources/OrganizationDomain.ts new file mode 100644 index 00000000000..c9baddeee14 --- /dev/null +++ b/packages/backend/src/api/resources/OrganizationDomain.ts @@ -0,0 +1,33 @@ +import type { OrganizationDomainJSON, OrganizationEnrollmentMode } from '@clerk/types'; + +import { OrganizationDomainVerification } from './Verification'; + +export class OrganizationDomain { + constructor( + readonly id: string, + readonly organizationId: string, + readonly name: string, + readonly enrollmentMode: OrganizationEnrollmentMode, + readonly verification: OrganizationDomainVerification | null, + readonly totalPendingInvitations: number, + readonly totalPendingSuggestions: number, + readonly createdAt: number, + readonly updatedAt: number, + readonly affiliationEmailAddress: string | null, + ) {} + + static fromJSON(data: OrganizationDomainJSON) { + return new OrganizationDomain( + data.id, + data.organization_id, + data.name, + data.enrollment_mode, + data.verification && OrganizationDomainVerification.fromJSON(data.verification), + data.total_pending_invitations, + data.total_pending_suggestions, + data.created_at, + data.updated_at, + data.affiliation_email_address, + ); + } +} diff --git a/packages/backend/src/api/resources/Verification.ts b/packages/backend/src/api/resources/Verification.ts index c6015812dd9..35cbfb4d369 100644 --- a/packages/backend/src/api/resources/Verification.ts +++ b/packages/backend/src/api/resources/Verification.ts @@ -1,3 +1,5 @@ +import type { OrganizationDomainVerificationJSON } from '@clerk/types'; + import type { VerificationJSON } from './JSON'; export class Verification { @@ -21,3 +23,16 @@ export class Verification { ); } } + +export class OrganizationDomainVerification { + constructor( + readonly status: string, + readonly strategy: string, + readonly attempts: number | null = null, + readonly expireAt: number | null = null, + ) {} + + static fromJSON(data: OrganizationDomainVerificationJSON): OrganizationDomainVerification { + return new OrganizationDomainVerification(data.status, data.strategy, data.attempts, data.expires_at); + } +} diff --git a/packages/backend/src/api/resources/index.ts b/packages/backend/src/api/resources/index.ts index 4652a7e8b2a..9a0ec1a3766 100644 --- a/packages/backend/src/api/resources/index.ts +++ b/packages/backend/src/api/resources/index.ts @@ -44,3 +44,5 @@ export type { WebhookEvent, WebhookEventType, } from './Webhooks'; + +export * from './OrganizationDomain'; diff --git a/packages/types/src/json.ts b/packages/types/src/json.ts index 3d0f1424b60..88a07f00770 100644 --- a/packages/types/src/json.ts +++ b/packages/types/src/json.ts @@ -353,7 +353,7 @@ export interface OrganizationInvitationJSON extends ClerkResourceJSON { updated_at: number; } -interface OrganizationDomainVerificationJSON { +export interface OrganizationDomainVerificationJSON { status: OrganizationDomainVerificationStatus; strategy: 'email_code'; // only available value for now attempts: number; From df63bc11c82823bdc2449d743ba8f560130f3221 Mon Sep 17 00:00:00 2001 From: nicolas lopes <57234795+NicolasLopes7@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:39:47 -0300 Subject: [PATCH 2/2] Code review Co-authored-by: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> --- packages/backend/src/api/endpoints/OrganizationApi.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/api/endpoints/OrganizationApi.ts b/packages/backend/src/api/endpoints/OrganizationApi.ts index 23fd7ccb356..b86e2cb2380 100644 --- a/packages/backend/src/api/endpoints/OrganizationApi.ts +++ b/packages/backend/src/api/endpoints/OrganizationApi.ts @@ -337,18 +337,14 @@ export class OrganizationAPI extends AbstractAPI { } public async updateOrganizationDomain(params: UpdateOrganizationDomainParams) { - const { organizationId, domainId, enrollmentMode, name, verified } = params; + const { organizationId, domainId, ...bodyParams } = params; this.requireId(organizationId); this.requireId(domainId); return this.request({ method: 'PATCH', path: joinPaths(basePath, organizationId, 'domains', domainId), - bodyParams: { - ...(enrollmentMode && { enrollment_mode: enrollmentMode }), - ...(name && { name }), - ...(verified !== undefined && { verified }), - }, + bodyParams, }); }