diff --git a/.changeset/tidy-tokens-activate.md b/.changeset/tidy-tokens-activate.md new file mode 100644 index 00000000000..27fb9354da7 --- /dev/null +++ b/.changeset/tidy-tokens-activate.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': minor +--- + +Add an optional `orgId` parameter to `createSignInToken()` for activating an Organization when the token is redeemed. diff --git a/packages/backend/src/api/__tests__/SignInTokenApi.test.ts b/packages/backend/src/api/__tests__/SignInTokenApi.test.ts new file mode 100644 index 00000000000..6d144fecbc9 --- /dev/null +++ b/packages/backend/src/api/__tests__/SignInTokenApi.test.ts @@ -0,0 +1,46 @@ +import { http, HttpResponse } from 'msw'; +import { describe, expect, it } from 'vitest'; + +import { server, validateHeaders } from '../../mock-server'; +import { createBackendApiClient } from '../factory'; + +describe('SignInTokenAPI', () => { + const apiClient = createBackendApiClient({ + apiUrl: 'https://api.clerk.test', + secretKey: 'deadbeef', + }); + + it('sends the organization ID as org_id', async () => { + server.use( + http.post( + 'https://api.clerk.test/v1/sign_in_tokens', + validateHeaders(async ({ request }) => { + const body = await request.json(); + expect(body).toEqual({ + user_id: 'user_123', + org_id: 'org_123', + expires_in_seconds: 3600, + }); + + return HttpResponse.json({ + id: 'sign_in_token_123', + user_id: 'user_123', + token: 'token_123', + status: 'pending', + url: 'https://accounts.example.com/tickets/token_123', + created_at: 1, + updated_at: 1, + }); + }), + ), + ); + + const response = await apiClient.signInTokens.createSignInToken({ + userId: 'user_123', + orgId: 'org_123', + expiresInSeconds: 3600, + }); + + expect(response.id).toBe('sign_in_token_123'); + }); +}); diff --git a/packages/backend/src/api/endpoints/SignInTokenApi.ts b/packages/backend/src/api/endpoints/SignInTokenApi.ts index 0635e97e635..45cb23efb32 100644 --- a/packages/backend/src/api/endpoints/SignInTokenApi.ts +++ b/packages/backend/src/api/endpoints/SignInTokenApi.ts @@ -6,6 +6,8 @@ import { AbstractAPI } from './AbstractApi'; export type CreateSignInTokensParams = { /** The ID of the user to create the sign-in token for. */ userId: string; + /** The ID of the organization to activate when the user signs in. Organizations must be enabled for the instance, and the user must be a member of the organization. */ + orgId?: string; /** The number of seconds until the sign-in token expires. By default, the duration is `2592000` (30 days). */ expiresInSeconds: number; };