Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions docs/auth-flow/_partial-auth-flow-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ function App() {

- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down Expand Up @@ -166,7 +167,8 @@ export default function Home() {

- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down Expand Up @@ -247,7 +249,8 @@ const openModal = () => {
- **If you're using TypeScript**, extend your type declarations with our types. Download the <a href="https://github.com/codatio/sdk-link/blob/main/snippets/types.d.ts" target="_blank"> `types.d.ts`</a> file, then copy and paste its contents into a new or existing `.d.ts` file.
- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down Expand Up @@ -326,7 +329,8 @@ In the example below, we use webpack's [magic comments](https://webpack.js.org/a
- **If you're using TypeScript**, extend your type declarations with our types. Download the <a href="https://github.com/codatio/sdk-link/blob/main/snippets/types.d.ts" target="_blank"> `types.d.ts`</a> file, then copy and paste its contents into a new or existing `.d.ts` file.
- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down Expand Up @@ -392,7 +396,8 @@ For an example of the component in action, [see our demo app](https://github.com
- **If you're using TypeScript**, extend your type declarations with our types. Download the <a href="https://github.com/codatio/sdk-link/blob/main/snippets/types.d.ts" target="_blank"> `types.d.ts`</a> file, then copy and paste its contents into a new or existing `.d.ts` file.
- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down Expand Up @@ -458,7 +463,8 @@ For an example of the component in action, [see our demo app](https://github.com
- **If you're using TypeScript**, extend your type declarations with our types. Download the <a href="https://github.com/codatio/sdk-link/blob/main/snippets/types.d.ts" target="_blank"> `types.d.ts`</a> file, then copy and paste its contents into a new or existing `.d.ts` file.
- **If you're using content security policy (CSP) headers**, edit these headers:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src`, `style-src`, `font-src`, `connect-src`, `img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

</TabItem>

Expand Down
83 changes: 73 additions & 10 deletions docs/auth-flow/customize/sdk-customize-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function AuthFlow() {
//text: {...},
enableAdditionalConsent: true,
enableMultiEntityLinking: true,
//nonce: "server-generated-nonce-value",
},
};

Expand Down Expand Up @@ -71,22 +72,24 @@ As the `options` object overrides the Link settings set in the Portal, this may
text: {...},
enableAdditionalConsent: true,
enableMultiEntityLinking: true,
nonce: "server-generated-nonce-value",
}}
/>
```

The `options` prop is optional and accepts an object containing the following optional properties:

| Property | Description |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `nonModal` | Determines whether Link is initialized with non-modal styling (no border and no close button). |
| `showLandingPage` | Determines whether an extra landing page is displayed to the user at the start of Link. |
| `showSandboxIntegrations` | Controls whether integrations that only connect Sandbox data are displayed for selection. |
| `theme` | Contains options that control the visual appearance of the Link flow. |
| `sourceTypes` | Controls the data source types (Accounting, Commerce, Banking, and Business Documents) the user can connect or upload files for. |
| `text` | Contains options that control what text is displayed to the user. Markdown is supported. |
| `enableAdditionalConsent` | Determines whether an additional consent journey for further use cases is displayed to the user. |
| `enableMultiEntityLinking` | Allows users to authorize to multiple companies within a single accounting platform in one go for compatible integrations. |
| Property | Description |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nonModal` | Determines whether Link uses non-modal styling, removing the border and close button. |
| `showLandingPage` | Determines whether the user sees an extra landing page at the start of Link. |
| `showSandboxIntegrations` | Controls whether integrations that only connect Sandbox data appear for selection. |
| `theme` | Contains options that control the visual appearance of the Link flow. |
| `sourceTypes` | Controls the data source types the user can connect or upload files for: Accounting, Commerce, Banking, and Business Documents. |
| `text` | Contains options that control what text the user sees. Supports Markdown. |
| `enableAdditionalConsent` | Determines whether the user sees an additional consent journey for further use cases. |
| `enableMultiEntityLinking` | Allows users to authorize to multiple companies within a single accounting platform in one go for compatible integrations. |
| `nonce` | A CSP nonce to apply to all `<style>` tags injected by the SDK so that styles aren't blocked by a strict Content Security Policy. See [CSP nonce](#csp-nonce) below. |

The object is applied **as the `CodatLink` component is mounted**, so doesn't support hot reloading. Modify the options and refresh the page to see the options reflected.

Expand Down Expand Up @@ -216,6 +219,66 @@ You may want to enable your customers to authorize access to multiple companies

To provide your customers with this option, set the `enableMultiEntityLinking` option to `true`. This will display additional subsidiary selection steps in the auth flow for the integrations that provide multi-entity support. By default, this option is set to `false`.

## CSP nonce

If your app sets [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) headers, you can pass a `nonce` through the `options` prop so that every `<style>` tag the SDK injects carries that nonce. This lets you use a strict `style-src` directive instead of `'unsafe-inline'`.

### Usage example

Your server should generate a unique nonce for every request and expose it to the browser, for example via a `<meta>` tag:

```html
<!-- Rendered by the server on each request -->
<meta name="csp-nonce" content="abc123servervalue" />
```

Read the nonce in your frontend code and pass it to the SDK:

```js
const nonce =
document.querySelector('meta[name="csp-nonce"]')?.getAttribute("content") ??
undefined;

<CodatLink
companyId={companyId}
onConnection={onConnection}
onError={onError}
onClose={onClose}
onFinish={onFinish}
options={{ nonce }}
/>;
```

Then set your CSP header to allow styles carrying that nonce:

```
Content-Security-Policy:
default-src 'self' *.codat.io;
script-src 'self' *.codat.io;
style-src 'self' 'nonce-abc123servervalue' *.codat.io;
font-src 'self' *.codat.io;
connect-src 'self' *.codat.io;
img-src 'self' *.codat.io;
```

### Migrating from `unsafe-inline`

If you currently allow `style-src 'unsafe-inline'` for the SDK, follow these steps to move to nonce-based CSP:

1. Configure your server to generate a cryptographically random nonce for each request.
2. Expose the nonce to the frontend, for example via a `<meta>` tag or a server-rendered variable.
3. Pass the nonce to the SDK through `options.nonce`.
4. Update your CSP header: replace `style-src 'unsafe-inline'` with `style-src 'nonce-<value>'`.
5. Verify that the SDK renders correctly and no CSP violations appear in the browser console.

### Backwards compatibility

Omitting the `nonce` option continues to work exactly as before. Consumers who don't set CSP headers, or who are happy with `'unsafe-inline'`, don't need to change anything. This isn't a breaking change.

### Mount-time behavior

The SDK reads the `nonce` value once when the component mounts. If your app rotates nonces—for example, on single-page app navigation—you must unmount and remount the SDK component with the new nonce value.

---

## Read next
Expand Down
26 changes: 17 additions & 9 deletions docs/auth-flow/optimize/connection-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ export const ConnectionManagement = ({

3. **If you're using content security policy (CSP) headers:**
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Don't use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

4. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand Down Expand Up @@ -303,7 +304,8 @@ export default function Home() {

3. **If you're using content security policy (CSP) headers:**
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

4. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand Down Expand Up @@ -373,7 +375,8 @@ const openModal = () => {

4. **If you're using content security policy (CSP) headers**:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

5. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand Down Expand Up @@ -443,7 +446,8 @@ onError(error) {

4. **If you're using content security policy (CSP) headers**:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

5. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand Down Expand Up @@ -496,7 +500,8 @@ We suggest wrapping the `CodatConnections` component in a modal so that you can

4. **If you're using content security policy (CSP) headers**:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

5. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand Down Expand Up @@ -561,7 +566,8 @@ We suggest wrapping the `CodatConnections` component in a modal so that you can

4. **If you're using content security policy (CSP) headers**:
- Allowlist Codat by adding `*.codat.io` to `default-src` (or each of `script-src, style-src, font-src, connect-src, img-src`).
- Add `unsafe-inline` to `style-src`. Do _not_ use a hash because this can change at any time without warning.
- **Recommended:** pass a [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce) via `options.nonce` and add `'nonce-<value>'` to `style-src`.
- Alternatively, add `'unsafe-inline'` to `style-src` if you aren't using nonces. Do _not_ use a hash because this can change at any time without warning.

5. **If you are using TypeScript**, extend your type declarations with our types by installing the package using `npm install --save-dev @codat/sdk-link-types`. Otherwise, delete the type-related code in the snippets.

Expand All @@ -585,15 +591,17 @@ onReconnect: (args: {connectionId: string}) => void = () => {};
onDisconnect: (args: {connectionId: string}) => void = () => {};
options={{
text: {...},
nonce: "server-generated-nonce-value",
}}
/>
```

The `options` prop is optional and accepts an object containing the following optional properties:

| Property | Description |
| -------- | ----------------------------------------------------------------- |
| `text` | Contains options that control what text is displayed to the user. |
| Property | Description |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | Contains options that control what text the user sees. |
| `nonce` | A CSP nonce to apply to all `<style>` tags injected by the SDK so that styles aren't blocked by a strict Content Security Policy. See [CSP nonce](/auth-flow/customize/sdk-customize-code#csp-nonce). |

The object is applied as the SDK component is mounted and doesn't support reloading. Make sure to modify the options before mounting the component.

Expand Down
Loading
Loading