From 20c9f756dd738e0381bf985dcf64e23b812698f5 Mon Sep 17 00:00:00 2001 From: Nick Hibberd Date: Fri, 1 Aug 2025 17:27:35 -0700 Subject: [PATCH 1/2] feat: add support for auth_tokens in boot and update methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users can now pass authentication tokens to Intercom for secure data operations. The authTokens property accepts an object with any string key-value pairs. Example usage: boot({ email: 'john.doe@example.com', userId: '9876', authTokens: { security_token: 'abc...' // JWT } }) 🤖 Generated with Claude Code Co-Authored-By: Claude --- .changeset/add-auth-tokens-support.md | 18 +++++ examples/auth-tokens-example.tsx | 37 +++++++++ packages/react-use-intercom/README.md | 17 +++++ packages/react-use-intercom/src/mappers.ts | 1 + packages/react-use-intercom/src/types.ts | 19 ++++- .../test/authTokens.test.tsx | 75 +++++++++++++++++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 .changeset/add-auth-tokens-support.md create mode 100644 examples/auth-tokens-example.tsx create mode 100644 packages/react-use-intercom/test/authTokens.test.tsx diff --git a/.changeset/add-auth-tokens-support.md b/.changeset/add-auth-tokens-support.md new file mode 100644 index 0000000..0219e1b --- /dev/null +++ b/.changeset/add-auth-tokens-support.md @@ -0,0 +1,18 @@ +--- +"react-use-intercom": minor +--- + +Add support for auth_tokens in boot and update methods + +Users can now pass authentication tokens to Intercom for secure data operations. The `authTokens` property accepts an object with any string key-value pairs. + +Example usage: +```js +boot({ + email: 'john.doe@example.com', + userId: '9876', + authTokens: { + security_token: 'abc...' // JWT + } +}) +``` \ No newline at end of file diff --git a/examples/auth-tokens-example.tsx b/examples/auth-tokens-example.tsx new file mode 100644 index 0000000..0f996f9 --- /dev/null +++ b/examples/auth-tokens-example.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { IntercomProvider, useIntercom } from 'react-use-intercom'; + +function MyApp() { + const { boot } = useIntercom(); + + const handleLogin = () => { + // After successful login, boot Intercom with auth tokens + boot({ + email: 'john.doe@example.com', + createdAt: 1234567890, + name: 'John Doe', + userId: '9876', + authTokens: { + security_token: 'abc...', // Your JWT token + // You can add any other tokens as key-value pairs + api_token: 'xyz...', + custom_token: '123...' + } + }); + }; + + return ( +
+

Intercom Auth Tokens Example

+ +
+ ); +} + +export default function App() { + return ( + + + + ); +} \ No newline at end of file diff --git a/packages/react-use-intercom/README.md b/packages/react-use-intercom/README.md index 1b32953..c8d82c3 100644 --- a/packages/react-use-intercom/README.md +++ b/packages/react-use-intercom/README.md @@ -255,6 +255,23 @@ All the Intercom default attributes/props are camel cased (`appId` instead of `a }) ``` + #### Authentication tokens + For secure data operations, you can pass authentication tokens to Intercom using the `authTokens` property. This accepts an object with any string key-value pairs. + + ```ts + const { boot } = useIntercom(); + + boot({ + email: 'john.doe@example.com', + userId: '9876', + authTokens: { + security_token: 'abc...', // JWT token + api_token: 'xyz...', + // Any other tokens as key-value pairs + } +}) + ``` + ## Playground Small playground to showcase the functionalities of `react-use-intercom`. diff --git a/packages/react-use-intercom/src/mappers.ts b/packages/react-use-intercom/src/mappers.ts index a704702..1aafbd1 100644 --- a/packages/react-use-intercom/src/mappers.ts +++ b/packages/react-use-intercom/src/mappers.ts @@ -75,6 +75,7 @@ export const mapDataAttributesToRawDataAttributes = ( mapDataAttributesCompanyToRawDataAttributesCompany, ), intercom_user_jwt: attributes.intercomUserJwt, + auth_tokens: attributes.authTokens, ...attributes.customAttributes, }); diff --git a/packages/react-use-intercom/src/types.ts b/packages/react-use-intercom/src/types.ts index 927d282..8e74654 100644 --- a/packages/react-use-intercom/src/types.ts +++ b/packages/react-use-intercom/src/types.ts @@ -117,6 +117,8 @@ export type DataAttributesAvatar = { imageUrl?: string; }; +export type AuthTokens = Record; + export type RawDataAttributes = { email?: string; user_id?: string; @@ -137,6 +139,7 @@ export type RawDataAttributes = { companies?: RawDataAttributesCompany[]; intercom_user_jwt?: string; customAttributes?: Record; + auth_tokens?: AuthTokens; }; export type DataAttributes = { @@ -236,9 +239,23 @@ export type DataAttributes = { * ``` * * @see {@link https://www.intercom.com/help/en/articles/179-send-custom-user-attributes-to-intercom} - * @remarks The key is the attribute name. The value is a placeholder for the data you’ll track + * @remarks The key is the attribute name. The value is a placeholder for the data you'll track */ customAttributes?: Record; + /** + * Authentication tokens for secure data operations + * Can contain any key-value pairs where both key and value are strings + * + * @example + * ``` + * authTokens: { + * security_token: 'abc...' // JWT + * } + * ``` + * + * @see {@link https://www.intercom.com/help/en/articles/6615543-setting-up-data-connectors-authentication#h_5343ec2d2c} + */ + authTokens?: AuthTokens; }; export type IntercomMethod = diff --git a/packages/react-use-intercom/test/authTokens.test.tsx b/packages/react-use-intercom/test/authTokens.test.tsx new file mode 100644 index 0000000..657fb00 --- /dev/null +++ b/packages/react-use-intercom/test/authTokens.test.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; +import { act, renderHook } from '@testing-library/react'; + +import { IntercomProvider, useIntercom } from '../src'; + +describe('auth_tokens', () => { + it('should pass auth_tokens during boot', () => { + const appId = 'app123'; + const mockIntercom = jest.fn(); + (window as any).Intercom = mockIntercom; + (window as any).intercomSettings = undefined; + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + {children} + ); + + const { result } = renderHook(() => useIntercom(), { wrapper }); + + act(() => { + result.current.boot({ + email: 'john.doe@example.com', + createdAt: 1234567890, + name: 'John Doe', + userId: '9876', + authTokens: { + security_token: 'abc123', + another_token: 'xyz789', + }, + }); + }); + + expect(mockIntercom).toHaveBeenCalledWith('boot', { + app_id: appId, + email: 'john.doe@example.com', + created_at: 1234567890, + name: 'John Doe', + user_id: '9876', + auth_tokens: { + security_token: 'abc123', + another_token: 'xyz789', + }, + }); + }); + + it('should pass auth_tokens during update', () => { + const appId = 'app123'; + const mockIntercom = jest.fn(); + (window as any).Intercom = mockIntercom; + (window as any).intercomSettings = { app_id: appId }; + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + {children} + ); + + const { result } = renderHook(() => useIntercom(), { wrapper }); + + act(() => { + result.current.update({ + authTokens: { + security_token: 'updated_token', + }, + }); + }); + + // Find the update call (not the boot or event handler calls) + const updateCalls = mockIntercom.mock.calls.filter(call => call[0] === 'update'); + const lastUpdateCall = updateCalls[updateCalls.length - 1]; + expect(lastUpdateCall).toBeDefined(); + expect(lastUpdateCall[1]).toMatchObject({ + auth_tokens: { + security_token: 'updated_token', + }, + }); + }); +}); \ No newline at end of file From 7ff5a4e28ae7b051e602e3aa3124d1927f471c93 Mon Sep 17 00:00:00 2001 From: Nick Hibberd Date: Fri, 1 Aug 2025 17:45:53 -0700 Subject: [PATCH 2/2] fix: sort imports in authTokens test file --- packages/react-use-intercom/test/authTokens.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-use-intercom/test/authTokens.test.tsx b/packages/react-use-intercom/test/authTokens.test.tsx index 657fb00..d19047d 100644 --- a/packages/react-use-intercom/test/authTokens.test.tsx +++ b/packages/react-use-intercom/test/authTokens.test.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { act, renderHook } from '@testing-library/react'; +import * as React from 'react'; import { IntercomProvider, useIntercom } from '../src';