diff --git a/content/docs/platform/inbox/meta.json b/content/docs/platform/inbox/meta.json index a09985d0a..7e146ee0c 100644 --- a/content/docs/platform/inbox/meta.json +++ b/content/docs/platform/inbox/meta.json @@ -4,10 +4,10 @@ "navigation-and-events", "configuration", "advanced-customization", - "prepare-for-production", "localization", "tenants", "headless", + "prepare-for-production", "migration-guide" ] } diff --git a/content/docs/platform/inbox/prepare-for-production.mdx b/content/docs/platform/inbox/prepare-for-production.mdx index 0371f18d4..e13537a3f 100644 --- a/content/docs/platform/inbox/prepare-for-production.mdx +++ b/content/docs/platform/inbox/prepare-for-production.mdx @@ -1,52 +1,84 @@ --- pageTitle: 'Prepare for Production' title: 'Prepare for Production' -description: 'Learn how to prepare your React notification inbox for production deployment including HMAC encryption and security best practices.' +description: "Learn how to prepare your Inbox for production by enabling HMAC encryption for security and managing Novu's branding." icon: 'ShieldCheck' --- -## HMAC Encryption +Before deploying the Inbox UI to production, you should secure your integration and configure the correct environment. You can also remove Novu's branding from your notifications. -When Novu's user adds the Inbox to their application they are required to pass a `subscriberId` which identifies the user's end-customer, and the application Identifier which is acted as a public key to communicate with the notification feed API. +This ensures that your end users receive notifications safely, without exposure to unnecessary risks, and in a way that aligns with your product branding. -A malicious actor can access the user feed by accessing the API and passing another `subscriberId` using the public application identifier. +## Set the correct environment -HMAC encryption will make sure that a `subscriberId` is encrypted using the secret API key, and those will prevent malicious actors from impersonating users. +Novu supports multiple environments, including development, production, and any custom environments you create. -## Using HMAC Encryption +When preparing for deployment, choose the environment that will serve as your production environment and update your configuration accordingly: -In order to use HMAC encryption in Inbox for enhanced security, follow these steps: +- Use the API keys for your selected production environment from the [API Keys](https://dashboard.novu.co/api-keys) page in your application. +- Store keys in `.env` file or your server’s environment variables. +- Confirm your `applicationIdentifier` and `subscriber` match the configuration for your chosen production environment. -### 1. Enable HMAC encryption in the In-App provider settings: +- Add these two props, if using the EU region: + - `apiUrl` with value **https://eu.api.novu.co** + - `socketUrl` with value **wss://eu.socket.novu.co** -- Go to [Novu Dashboard](https://dashboard.novu.co). -- Navigate to the [Integrations Store](https://dashboard.novu.co/integrations) page. -- Click on the Novu In-App provider. -- A side panel will open from the right side of the screen with the provider settings. -- Enable `Security HMAC encryption` toggle in **Integration Credentials** section. -- Save the changes and copy the secret key from [Api Keys](https://dashboard.novu.co/api-keys) page. +## Secure your Inbox with HMAC encryption -### 2. Generate HMAC hash on the server side: +When you add the Inbox to your application, you're required to pass: +- `subscriberId`: Identifies the current subscriber. +- `applicationIdentifier`: A public key to communicate with the notification feed API. -Use the `secret key` to generate an HMAC hash of the `subscriberId` on the server side. Keep `NOVU_SECRET_KEY` secure and never expose it to the client. +Without additional security, a malicious actor could potentially guess another subscriber's `subscriberId` and use your public `applicationIdentifier` to view that user's notifications. + +You can prevent this by enabling HMAC (Hash-based Message Authentication Code) encryption. This process uses a _secret key_ to create a secure signature (`subscriberHash`) for each `subscriberId`. Novu then verifies this hash to ensure that requests to view a notification feed are authentic and not from an impersonator. + +Follow these steps to enable HMAC encryption. + +### 1. Enable HMAC in the dashboard + +Activate the HMAC security feature within your Novu in-app provider settings. + +1. Go to [Novu Dashboard](https://dashboard.novu.co). +2. Navigate to the [Integrations Store](https://dashboard.novu.co/integrations) page. +3. Click on the **Novu In-App** for your chosen production environment +4. A side panel opens from the right side of the screen with the provider settings, enable `Security HMAC encryption` toggle in **Integration Credentials** section. + ![Enabling HMAC in the Novu dashboard](/images/inbox/hmac.png) + +### 2. Generate HMAC hash on the server side + +Next, use your secret key from the API Keys page on the Novu dashboard to generate an HMAC hash of the `subscriberId` on the server side. ```tsx import { createHmac } from 'crypto'; -export const hmacHash = createHmac('sha256', process.env.NOVU_SECRET_KEY) +// The subscriberId of the logged-in user +const subscriberId = 'REPLACE_WITH_SUBSCRIBER_ID'; + +// The secret key from your Novu API Keys page +const novuSecretKey = process.env.NOVU_SECRET_KEY; + +// Generate the HMAC hash +const hmacHash = createHmac('sha256', novuSecretKey) .update(subscriberId) .digest('hex'); ``` -### 3. Use the HMAC hash in the Inbox component: +Keep `NOVU_SECRET_KEY` secure and never expose it to the client. -Send the `hmacHash` generated in the previous step to the client side application via HTTP request or store it in the user's database record. Use it as the `subscriberHash` prop in the Inbox component. In below example, we are using `currentUser` hook to get the `hmacHash` from the user's database record. +### 3. Use the HMAC hash in the Inbox component + +Send the `hmacHash` generated in the previous step to the client side application. You can include it in the initial data payload when a subscriber or user logs in or fetch it from a dedicated API endpoint. + +Pass the hash to the `subscriberHash` prop in your Inbox component. ```tsx import { Inbox } from '@novu/react'; -const { user } = currentUser(); +// Example: The hmacHash is passed to the frontend +// as part of the user object after they authenticate. +const { user } = currentUser(); const hmacHash = user?.novuSubscriberHash; + +## Remove Novu branding + +Users on a paid plan can remove the "Inbox by Novu" branding from the Inbox UI. + +To remove the branding: + +1. Go to [Novu Dashboard](https://dashboard.novu.co). +2. Navigate to the **Settings** page. +3. Under the **Organization** tab, find the **Branding & Integrations** section. +4. Enable the **Remove Novu branding** toggle. + +![Removing Novu branding](/images/inbox/novu-branding.png) \ No newline at end of file diff --git a/content/docs/platform/inbox/setup-inbox.mdx b/content/docs/platform/inbox/setup-inbox.mdx index 81984980d..a3a6d22cd 100644 --- a/content/docs/platform/inbox/setup-inbox.mdx +++ b/content/docs/platform/inbox/setup-inbox.mdx @@ -135,7 +135,7 @@ If your Novu account is in the EU region, then include the `backendUrl` and `soc applicationIdentifier="APPLICATION_IDENTIFIER" subscriber="SUBSCRIBER_ID" backendUrl="https://eu.api.novu.co" - socketUrl="https://eu.ws.novu.co" + socketUrl="wss://eu.socket.novu.co" /> ); } @@ -151,7 +151,7 @@ If your Novu account is in the EU region, then include the `backendUrl` and `soc applicationIdentifier="APPLICATION_IDENTIFIER" subscriber="SUBSCRIBER_ID" backendUrl="https://eu.api.novu.co" - socketUrl="https://eu.ws.novu.co" + socketUrl="wss://eu.socket.novu.co" /> ); } diff --git a/content/docs/platform/sdks/javascript/index.mdx b/content/docs/platform/sdks/javascript/index.mdx index c6441fefc..8c640618a 100644 --- a/content/docs/platform/sdks/javascript/index.mdx +++ b/content/docs/platform/sdks/javascript/index.mdx @@ -69,7 +69,7 @@ The Novu client provides methods to interact with notifications, preferences, an subscriberId: "SUBSCRIBER_ID", applicationIdentifier: "APPLICATION_IDENTIFIER", apiUrl: "https://eu.api.novu.co", - socketUrl: "https://eu.ws.novu.co", + socketUrl: "wss://eu.socket.novu.co", }); ``` diff --git a/content/docs/platform/sdks/javascript/index.model.mdx b/content/docs/platform/sdks/javascript/index.model.mdx index 7a8b6efcd..fa722a691 100644 --- a/content/docs/platform/sdks/javascript/index.model.mdx +++ b/content/docs/platform/sdks/javascript/index.model.mdx @@ -38,7 +38,7 @@ The Novu client provides methods to interact with notifications, preferences, an subscriberId: "SUBSCRIBER_ID", applicationIdentifier: "APPLICATION_IDENTIFIER", apiUrl: "https://eu.api.novu.co", - socketUrl: "https://eu.ws.novu.co", + socketUrl: "wss://eu.socket.novu.co", }); ``` diff --git a/content/docs/platform/sdks/react-native/hooks/novu-provider.mdx b/content/docs/platform/sdks/react-native/hooks/novu-provider.mdx index c2d8f4034..802a8d300 100644 --- a/content/docs/platform/sdks/react-native/hooks/novu-provider.mdx +++ b/content/docs/platform/sdks/react-native/hooks/novu-provider.mdx @@ -49,7 +49,7 @@ Usually, it's placed somewhere in the root of your application, which makes the subscriber="SUBSCRIBER_ID" applicationIdentifier="APPLICATION_IDENTIFIER" backendUrl="https://eu.api.novu.co" - socketUrl="https://eu.ws.novu.co" + socketUrl="wss://eu.socket.novu.co" > {/* Your app components */} diff --git a/content/docs/platform/sdks/react/hooks/novu-provider.mdx b/content/docs/platform/sdks/react/hooks/novu-provider.mdx index d7e3fdc47..2b0c83033 100644 --- a/content/docs/platform/sdks/react/hooks/novu-provider.mdx +++ b/content/docs/platform/sdks/react/hooks/novu-provider.mdx @@ -71,7 +71,7 @@ Usually, it's placed somewhere in the root of your application, which makes the subscriber="SUBSCRIBER_ID" applicationIdentifier="APPLICATION_IDENTIFIER" backendUrl="https://eu.api.novu.co" - socketUrl="https://eu.ws.novu.co" + socketUrl="wss://eu.socket.novu.co" > {/* Your app components */} diff --git a/public/images/inbox/hmac.png b/public/images/inbox/hmac.png new file mode 100644 index 000000000..8c9f230ff Binary files /dev/null and b/public/images/inbox/hmac.png differ diff --git a/public/images/inbox/novu-branding.png b/public/images/inbox/novu-branding.png new file mode 100644 index 000000000..68738f23e Binary files /dev/null and b/public/images/inbox/novu-branding.png differ