@redacto.io/consent-sdk-react-native 5.0.0-beta.0 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/dist/chunk-B2TXWC2C.mjs +60 -0
- package/dist/index.d.mts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +196 -55
- package/dist/index.mjs +153 -56
- package/dist/privacy-center.d.mts +147 -63
- package/dist/privacy-center.d.ts +147 -63
- package/dist/privacy-center.js +1570 -647
- package/dist/privacy-center.mjs +1530 -644
- package/package.json +1 -1
- package/dist/chunk-Y6FXYEAI.mjs +0 -10
package/README.md
CHANGED
|
@@ -64,6 +64,81 @@ pnpm add @tanstack/react-query i18next react-i18next dayjs \
|
|
|
64
64
|
|
|
65
65
|
> **Note:** `react-native-svg` must be linked for native builds. Follow the [react-native-svg setup guide](https://github.com/software-mansion/react-native-svg#installation).
|
|
66
66
|
|
|
67
|
+
## Sandbox Mode (No Backend Required)
|
|
68
|
+
|
|
69
|
+
Sandbox mode lets you build and test a full consent PoC — **notice → Privacy Center → DSAR** — straight from your app, with **no backend and no token minting**. Instead of your server generating a JWT, you paste a **static sandbox token** into the SDK. Everything you create is recorded as test data, isolated from your live records.
|
|
70
|
+
|
|
71
|
+
Going live is a config swap, not a rewrite: drop the sandbox props and pass a real JWT (see [Backend Server Setup](#backend-server-setup)).
|
|
72
|
+
|
|
73
|
+
### 1. Get your sandbox credentials
|
|
74
|
+
|
|
75
|
+
In the **Redacto Dashboard → API Keys → Sandbox** tab, copy:
|
|
76
|
+
|
|
77
|
+
- your **Sandbox token** (a static string; it never expires and needs no refresh)
|
|
78
|
+
- your **Organization ID** and **Workspace ID** (shown under *Workspace identifiers* on the same page)
|
|
79
|
+
|
|
80
|
+
### 2. Collect consent
|
|
81
|
+
|
|
82
|
+
Pass the sandbox `token`, org/workspace, and a test identity (`email`, `mobile`, or `ucic`). No `accessToken` is needed:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react-native";
|
|
86
|
+
|
|
87
|
+
<RedactoNoticeConsent
|
|
88
|
+
noticeId={NOTICE_UUID}
|
|
89
|
+
token={SANDBOX_TOKEN}
|
|
90
|
+
organisationUuid={ORG_UUID}
|
|
91
|
+
workspaceUuid={WORKSPACE_UUID}
|
|
92
|
+
email="test.user@example.com" // or `mobile`, or `ucic`
|
|
93
|
+
onAccept={() => console.log("consent recorded (test)")}
|
|
94
|
+
onDecline={() => {}}
|
|
95
|
+
/>;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Manage consent & raise a DSAR
|
|
99
|
+
|
|
100
|
+
Point the Privacy Center at the same sandbox token and test identity. The same test user can now review the consent from step 2, withdraw it, and file a DSAR — end to end, all as test data:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react-native/privacy-center";
|
|
104
|
+
|
|
105
|
+
<RedactoPrivacyCenter
|
|
106
|
+
baseUrl={BASE_URL}
|
|
107
|
+
slug="acme-co"
|
|
108
|
+
token={SANDBOX_TOKEN}
|
|
109
|
+
organisationUuid={ORG_UUID}
|
|
110
|
+
workspaceUuid={WORKSPACE_UUID}
|
|
111
|
+
email="test.user@example.com" // or `mobile`, or `ucic`
|
|
112
|
+
onError={(error) => {
|
|
113
|
+
console.error(error);
|
|
114
|
+
return false;
|
|
115
|
+
}}
|
|
116
|
+
/>;
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Sandbox props
|
|
120
|
+
|
|
121
|
+
Both `RedactoNoticeConsent` and `RedactoPrivacyCenter` accept the same sandbox props:
|
|
122
|
+
|
|
123
|
+
| Prop | Required | Description |
|
|
124
|
+
| --------------------------- | ------------ | ----------------------------------------------------------------------------------- |
|
|
125
|
+
| `token` | Yes | Static sandbox token from the Dashboard. Its presence activates sandbox mode. |
|
|
126
|
+
| `organisationUuid` | Yes | Organization ID from the Dashboard. |
|
|
127
|
+
| `workspaceUuid` | Yes | Workspace ID from the Dashboard. |
|
|
128
|
+
| `email` / `mobile` / `ucic` | One required | The test subject. Precedence when more than one is set: `ucic` > `email` > `mobile`. |
|
|
129
|
+
|
|
130
|
+
### How it works
|
|
131
|
+
|
|
132
|
+
- The SDK sends the sandbox token as an `X-Consent-Token` header and the test identity inside each request (query params on reads, body on writes) — no JWT decode, no token refresh (a `401` fails fast).
|
|
133
|
+
- The server records everything under `environment=test`, namespaced so sandbox data never mixes with — or reads — your live records.
|
|
134
|
+
- Sandbox always talks to the consent server; it never routes to the Go ledger.
|
|
135
|
+
|
|
136
|
+
### Going live
|
|
137
|
+
|
|
138
|
+
Sandbox and production use the same components. To ship, remove the sandbox props and pass a real `accessToken` / `refreshToken` (JWT) minted by your backend — see [Backend Server Setup](#backend-server-setup) below. New records are then written as `environment=live`.
|
|
139
|
+
|
|
140
|
+
> Sandbox is available on `RedactoNoticeConsent` and `RedactoPrivacyCenter`. The inline widget (`RedactoNoticeConsentInline`) is JWT-only.
|
|
141
|
+
|
|
67
142
|
## Backend Server Setup
|
|
68
143
|
|
|
69
144
|
The SDK never talks to Redacto with your CMS API key directly — your backend acts as a token broker. Obtain your **CMS-API-Key** from the Redacto Dashboard, store it in your backend's environment, and expose two endpoints to your mobile app:
|
|
@@ -136,6 +211,7 @@ import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react-native";
|
|
|
136
211
|
| `accessToken` | `string` | ✓ | JWT access token |
|
|
137
212
|
| `refreshToken` | `string` | ✓ | JWT refresh token |
|
|
138
213
|
| `baseUrl` | `string` | | Override API base URL |
|
|
214
|
+
| `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and prior-consent checks route through the ledger (falls back: ledger → baseUrl → default). Omit to keep the legacy consent-server path. |
|
|
139
215
|
| `settings` | `Partial<Settings>` | | UI customisation (colours, border radius, fonts) |
|
|
140
216
|
| `language` | `string` | | Initial language code (e.g. `"en"`) |
|
|
141
217
|
| `blockUI` | `boolean` | | Block the modal from being dismissed |
|
|
@@ -173,6 +249,7 @@ import { RedactoNoticeConsentInline } from "@redacto.io/consent-sdk-react-native
|
|
|
173
249
|
| `notice_uuid` | `string` | ✓ | Notice UUID |
|
|
174
250
|
| `accessToken` | `string` | | JWT access token (triggers auto-submit when set) |
|
|
175
251
|
| `baseUrl` | `string` | | Override API base URL |
|
|
252
|
+
| `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and already-consented checks route through the ledger. Omit for legacy behavior. |
|
|
176
253
|
| `language` | `string` | | Language code |
|
|
177
254
|
| `settings` | `Partial<Settings>` | | UI customisation |
|
|
178
255
|
| `applicationId` | `string` | | Application-specific UUID |
|
|
@@ -217,6 +294,7 @@ import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react-native/priva
|
|
|
217
294
|
| Prop | Type | Required | Default | Description |
|
|
218
295
|
| -------------- | ----------------------------------------------------------------------------- | -------- | -------------------- | ---------------------------------------- |
|
|
219
296
|
| `baseUrl` | `string` | ✓ | - | Consent server base URL |
|
|
297
|
+
| `ledgerBaseUrl` | `string` | | - | Go ledger base URL. When set, user consents, group purposes, receipts, and manage-consent route through the ledger. Omit to use the legacy `/dsar/privacy-center/*` routes. See the note below on the DSAR form picker. |
|
|
220
298
|
| `slug` | `string` | ✓ | - | Workspace slug |
|
|
221
299
|
| `accessToken` | `string` | ✓ | - | JWT access token |
|
|
222
300
|
| `refreshToken` | `string` | ✓ | - | JWT refresh token |
|
|
@@ -274,6 +352,18 @@ For consumers who want fully custom UI, the headless core exposes the API client
|
|
|
274
352
|
- Keep API keys and server secrets on your backend only.
|
|
275
353
|
- In Expo apps, values read from `EXPO_PUBLIC_*` are bundled into the app and should only contain non-sensitive config like UUIDs and URLs.
|
|
276
354
|
- If you do not pass `baseUrl`, the SDK defaults to `https://api.redacto.io/consent` for both notice and Privacy Center surfaces.
|
|
355
|
+
- `ledgerBaseUrl` is optional and independent of `baseUrl` — pass both when routing consent through the Go ledger. Omitting it keeps the legacy consent-server behavior.
|
|
356
|
+
|
|
357
|
+
## Ledger mode
|
|
358
|
+
|
|
359
|
+
Passing `ledgerBaseUrl` routes consent-bearing reads and writes to the Go ledger:
|
|
360
|
+
|
|
361
|
+
- **Notice components** — `submit-consent` goes to the ledger, and the already-consented check uses the ledger's `check-consent` endpoint instead of the legacy HTTP 409 signal. Notice content, tokens, and TTS always stay on `baseUrl`.
|
|
362
|
+
- **Privacy Center** — user consents, group purposes, receipts (including the `/download` PDF path), and manage-consent (sent as a `partial: true` write) route to the ledger. DSAR form, cases, activities, OTP, and notifications stay on `baseUrl`.
|
|
363
|
+
|
|
364
|
+
Every ledger read degrades to the legacy path on failure, so a ledger outage does not break the consent flow.
|
|
365
|
+
|
|
366
|
+
> **Known limitation.** Unlike the React SDK, the DSAR form's product picker is **not** overlaid from ledger-served consents. Against a workspace cut over to the ledger — where the legacy `form/data` response carries no product groups — the picker renders empty. If your DSAR form depends on the product picker, stay on the legacy path until this is addressed.
|
|
277
367
|
|
|
278
368
|
## License
|
|
279
369
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/shared/languages.ts
|
|
9
|
+
var languageOptions = [
|
|
10
|
+
{ value: "en", label: "English" },
|
|
11
|
+
{ value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
|
|
12
|
+
{ value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
|
|
13
|
+
{ value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
|
|
14
|
+
{ value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
|
|
15
|
+
{ value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
|
|
16
|
+
{ value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
|
|
17
|
+
{ value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
|
|
18
|
+
{ value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
|
|
19
|
+
{ value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
|
|
20
|
+
{ value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
|
|
21
|
+
{ value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
|
|
22
|
+
{ value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
|
|
23
|
+
{ value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
|
|
24
|
+
{ value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
|
|
25
|
+
{ value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
|
|
26
|
+
{ value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
|
|
27
|
+
{ value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
|
|
28
|
+
{ value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
|
|
29
|
+
{ value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
|
|
30
|
+
{ value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
|
|
31
|
+
{ value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
|
|
32
|
+
{ value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
|
|
33
|
+
];
|
|
34
|
+
var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
|
|
35
|
+
var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
|
|
36
|
+
var englishName = (label) => {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
return (_b = (_a = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a[1]) != null ? _b : label;
|
|
39
|
+
};
|
|
40
|
+
var codeByName = new Map(
|
|
41
|
+
languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
|
|
42
|
+
);
|
|
43
|
+
function toLanguageCode(lang) {
|
|
44
|
+
var _a, _b, _c;
|
|
45
|
+
if (!lang) return void 0;
|
|
46
|
+
const trimmed = lang.trim();
|
|
47
|
+
if (!trimmed) return void 0;
|
|
48
|
+
const lower = trimmed.toLowerCase();
|
|
49
|
+
return (_c = (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByName.get(lower)) != null ? _b : codeByLower.get(lower)) != null ? _c : trimmed;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/shared/sandbox.ts
|
|
53
|
+
var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
__require,
|
|
57
|
+
SANDBOX_TOKEN_HEADER,
|
|
58
|
+
languageOptions,
|
|
59
|
+
toLanguageCode
|
|
60
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -28,8 +28,34 @@ type Settings$1 = {
|
|
|
28
28
|
|
|
29
29
|
type Props$1 = Readonly<{
|
|
30
30
|
noticeId: string;
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* JWT access token. Optional so sandbox integrations (see `token`) can
|
|
33
|
+
* omit it. Required in the normal JWT flow.
|
|
34
|
+
*/
|
|
35
|
+
accessToken?: string;
|
|
36
|
+
/** JWT refresh token. Optional; accepted for source-compat, currently unused. */
|
|
37
|
+
refreshToken?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Sandbox PoC: a pasted static token. When set, the SDK runs against the
|
|
40
|
+
* sandbox with no JWT — it sends the single `X-Consent-Token` header, carries
|
|
41
|
+
* the acting identity (`email` || `mobile` || `ucic`) in each request's own
|
|
42
|
+
* payload, takes org/workspace from `organisationUuid`/`workspaceUuid`, and
|
|
43
|
+
* does no token refresh.
|
|
44
|
+
*/
|
|
45
|
+
token?: string;
|
|
46
|
+
/** Sandbox test subject email (carried in the request payload when set). */
|
|
47
|
+
email?: string;
|
|
48
|
+
/** Sandbox test subject mobile (fallback subject when `email` is absent). */
|
|
49
|
+
mobile?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Sandbox UCIC: the client's own user id / org_user_id, e.g. a UUID or
|
|
52
|
+
* customer code; optional third identifier alongside email/mobile.
|
|
53
|
+
*/
|
|
54
|
+
ucic?: string;
|
|
55
|
+
/** Sandbox org UUID (replaces the JWT-decoded org in sandbox mode). */
|
|
56
|
+
organisationUuid?: string;
|
|
57
|
+
/** Sandbox workspace UUID (replaces the JWT-decoded workspace in sandbox mode). */
|
|
58
|
+
workspaceUuid?: string;
|
|
33
59
|
baseUrl?: string;
|
|
34
60
|
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
35
61
|
ledgerBaseUrl?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -28,8 +28,34 @@ type Settings$1 = {
|
|
|
28
28
|
|
|
29
29
|
type Props$1 = Readonly<{
|
|
30
30
|
noticeId: string;
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* JWT access token. Optional so sandbox integrations (see `token`) can
|
|
33
|
+
* omit it. Required in the normal JWT flow.
|
|
34
|
+
*/
|
|
35
|
+
accessToken?: string;
|
|
36
|
+
/** JWT refresh token. Optional; accepted for source-compat, currently unused. */
|
|
37
|
+
refreshToken?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Sandbox PoC: a pasted static token. When set, the SDK runs against the
|
|
40
|
+
* sandbox with no JWT — it sends the single `X-Consent-Token` header, carries
|
|
41
|
+
* the acting identity (`email` || `mobile` || `ucic`) in each request's own
|
|
42
|
+
* payload, takes org/workspace from `organisationUuid`/`workspaceUuid`, and
|
|
43
|
+
* does no token refresh.
|
|
44
|
+
*/
|
|
45
|
+
token?: string;
|
|
46
|
+
/** Sandbox test subject email (carried in the request payload when set). */
|
|
47
|
+
email?: string;
|
|
48
|
+
/** Sandbox test subject mobile (fallback subject when `email` is absent). */
|
|
49
|
+
mobile?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Sandbox UCIC: the client's own user id / org_user_id, e.g. a UUID or
|
|
52
|
+
* customer code; optional third identifier alongside email/mobile.
|
|
53
|
+
*/
|
|
54
|
+
ucic?: string;
|
|
55
|
+
/** Sandbox org UUID (replaces the JWT-decoded org in sandbox mode). */
|
|
56
|
+
organisationUuid?: string;
|
|
57
|
+
/** Sandbox workspace UUID (replaces the JWT-decoded workspace in sandbox mode). */
|
|
58
|
+
workspaceUuid?: string;
|
|
33
59
|
baseUrl?: string;
|
|
34
60
|
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
35
61
|
ledgerBaseUrl?: string;
|