@redacto.io/consent-sdk-react-native 5.0.0-beta.1 → 5.0.0-beta.11

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 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:
@@ -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
- accessToken: string;
32
- refreshToken: string;
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
- accessToken: string;
32
- refreshToken: string;
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;