@redacto.io/consent-sdk-react-native 5.0.1-beta.1 → 6.0.0

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.
@@ -1,10 +1,330 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
+ import { P as PrivacyCenterTheme } from './types-BYp89x8C.mjs';
3
4
  import * as _tanstack_react_query from '@tanstack/react-query';
4
5
  import * as react_native from 'react-native';
5
- import { StyleProp, ViewStyle, TextStyle, KeyboardTypeOptions, DimensionValue, Animated } from 'react-native';
6
+ import { ViewStyle, TextStyle, StyleProp, KeyboardTypeOptions, DimensionValue, Animated } from 'react-native';
6
7
  import * as lucide_react_native from 'lucide-react-native';
7
8
 
9
+ /** Menu sections, keyed by the `InternalPage` each one opens. */
10
+ type PrivacyCenterSectionKey = 'consent-manager' | 'form' | 'activity' | 'receipts' | 'notifications';
11
+ /** Request types, keyed by the lower-case value a case is created with. */
12
+ type PrivacyCenterRequestTypeKey = 'access' | 'correction' | 'erasure' | 'nomination' | 'grievance';
13
+ type PrivacyCenterGrievanceCategory = 'consent_violation' | 'unlawful_processing' | 'data_breach';
14
+ type PrivacyCenterSignInLayout = 'card' | 'split' | 'minimal';
15
+ type PrivacyCenterSignInAlign = 'center' | 'left';
16
+ type PrivacyCenterSignInBackground = 'gradient' | 'solid' | 'image';
17
+ type PrivacyCenterSignInChannels = 'both' | 'email' | 'sms';
18
+ type PrivacyCenterSection = Readonly<{
19
+ key: PrivacyCenterSectionKey;
20
+ /** `null` uses the built-in, translated label. */
21
+ label: string | null;
22
+ enabled: boolean;
23
+ }>;
24
+ type PrivacyCenterRequestType = Readonly<{
25
+ key: PrivacyCenterRequestTypeKey;
26
+ /** `null` uses the built-in, translated label. */
27
+ label: string | null;
28
+ enabled: boolean;
29
+ }>;
30
+ type PrivacyCenterFooterLink = Readonly<{
31
+ label: string;
32
+ url: string;
33
+ }>;
34
+ type PrivacyCenterBrandingSettings = Readonly<{
35
+ inherit_identity: boolean;
36
+ display_name: string | null;
37
+ logo_url: string | null;
38
+ /** 28–96 px; `null` keeps the built-in size. */
39
+ logo_height: number | null;
40
+ inherit_colors: boolean;
41
+ primary_color: string | null;
42
+ accent_color: string | null;
43
+ inherit_font: boolean;
44
+ font_family: string | null;
45
+ style: PrivacyCenterTheme;
46
+ /** 0–24 px; `null` keeps the built-in radii. */
47
+ corner_radius: number | null;
48
+ }>;
49
+ type PrivacyCenterSignInSettings = Readonly<{
50
+ layout: PrivacyCenterSignInLayout;
51
+ align: PrivacyCenterSignInAlign;
52
+ background_type: PrivacyCenterSignInBackground;
53
+ background_from: string;
54
+ background_to: string;
55
+ background_color: string;
56
+ background_image_url: string | null;
57
+ highlights: readonly string[];
58
+ show_logo: boolean;
59
+ title: string;
60
+ tagline: string | null;
61
+ heading: string;
62
+ description: string | null;
63
+ channels: PrivacyCenterSignInChannels;
64
+ default_country_code: string;
65
+ field_label: string | null;
66
+ placeholder: string | null;
67
+ help_text: string | null;
68
+ button_text: string;
69
+ show_notice_line: boolean;
70
+ notice_line: string | null;
71
+ show_support_link: boolean;
72
+ support_text: string;
73
+ support_link_text: string;
74
+ otp_heading: string;
75
+ otp_description: string | null;
76
+ otp_button_text: string;
77
+ otp_resend_text: string;
78
+ }>;
79
+ type PrivacyCenterPortalSettings = Readonly<{
80
+ sections: readonly PrivacyCenterSection[];
81
+ welcome_enabled: boolean;
82
+ welcome_title: string;
83
+ welcome_message: string;
84
+ request_types: readonly PrivacyCenterRequestType[];
85
+ grievance_categories: readonly PrivacyCenterGrievanceCategory[];
86
+ /** `null` asks the data principal, as today. */
87
+ revoke_consents_on_erasure: boolean | null;
88
+ /** `null` uses the built-in warning; a purpose's own message still wins. */
89
+ withdraw_warning: string | null;
90
+ /** `null` never signs out for inactivity. */
91
+ session_timeout_minutes: number | null;
92
+ }>;
93
+ type PrivacyCenterLanguageSettings = Readonly<{
94
+ enabled: readonly string[];
95
+ default: string;
96
+ auto_detect: boolean;
97
+ show_switcher: boolean;
98
+ }>;
99
+ type PrivacyCenterFooterSettings = Readonly<{
100
+ links: readonly PrivacyCenterFooterLink[];
101
+ show_privacy_policy: boolean;
102
+ show_contact: boolean;
103
+ copyright: string | null;
104
+ show_powered_by: boolean;
105
+ }>;
106
+ type PrivacyCenterSeoSettings = Readonly<{
107
+ page_title: string;
108
+ noindex: boolean;
109
+ }>;
110
+ type PrivacyCenterEmbedSettings = Readonly<{
111
+ allowed_origins: readonly string[];
112
+ }>;
113
+ /**
114
+ * The full Privacy Center settings, as published from the Redacto console and
115
+ * served by the public settings endpoint, with every field filled in. The
116
+ * published `custom_css` is web-only: React Native has no stylesheet to apply
117
+ * it to, so it is not read.
118
+ */
119
+ type ResolvedPrivacyCenterSettings = Readonly<{
120
+ schema_version: number;
121
+ branding: PrivacyCenterBrandingSettings;
122
+ sign_in: PrivacyCenterSignInSettings;
123
+ portal: PrivacyCenterPortalSettings;
124
+ languages: PrivacyCenterLanguageSettings;
125
+ footer: PrivacyCenterFooterSettings;
126
+ seo: PrivacyCenterSeoSettings;
127
+ embed: PrivacyCenterEmbedSettings;
128
+ }>;
129
+ /**
130
+ * Host overrides for `RedactoPrivacyCenter`'s `settings` prop. Each group is
131
+ * merged field by field over the published settings, so a host can change one
132
+ * value and keep the rest of what the console published.
133
+ */
134
+ type PrivacyCenterSettings = Readonly<{
135
+ /**
136
+ * Visual style, kept as an alias for `branding.style` so the same settings
137
+ * object works on the web SDK. The React Native Privacy Center has one look,
138
+ * so the style is read but changes nothing here.
139
+ */
140
+ theme?: PrivacyCenterTheme;
141
+ branding?: Partial<PrivacyCenterBrandingSettings>;
142
+ sign_in?: Partial<PrivacyCenterSignInSettings>;
143
+ portal?: Partial<PrivacyCenterPortalSettings>;
144
+ languages?: Partial<PrivacyCenterLanguageSettings>;
145
+ footer?: Partial<PrivacyCenterFooterSettings>;
146
+ seo?: Partial<PrivacyCenterSeoSettings>;
147
+ }>;
148
+ /**
149
+ * Brand Identity details the public settings carry only when the published
150
+ * settings use them (a `{legal}` placeholder, the footer's privacy policy or
151
+ * contact lines). Each is null otherwise.
152
+ */
153
+ type PrivacyCenterBrandContact = Readonly<{
154
+ legal_entity_name: string | null;
155
+ privacy_policy_url: string | null;
156
+ grievance_email: string | null;
157
+ grievance_url: string | null;
158
+ dp_board_url: string | null;
159
+ }>;
160
+ /** `detail` of `GET /public/organisations/{org}/privacy-center-settings/`. */
161
+ type PublicPrivacyCenterSettingsResponse = Readonly<{
162
+ settings: unknown;
163
+ version: number;
164
+ published_at: string | null;
165
+ language: string;
166
+ /** Absent on servers that predate it. */
167
+ brand_contact?: unknown;
168
+ }>;
169
+ /** Values the `{brand}`-style tokens in custom copy resolve to. */
170
+ type PlaceholderContext = Readonly<{
171
+ brand: string;
172
+ legal?: string | null;
173
+ year?: number;
174
+ contact?: string | null;
175
+ name?: string | null;
176
+ }>;
177
+
178
+ declare const spacing: {
179
+ readonly xs: 4;
180
+ readonly sm: 8;
181
+ readonly md: 12;
182
+ readonly lg: 16;
183
+ readonly xl: 24;
184
+ readonly xxl: 32;
185
+ readonly xxxl: 40;
186
+ readonly huge: 56;
187
+ };
188
+ declare const section: {
189
+ readonly sm: 24;
190
+ readonly md: 32;
191
+ readonly lg: 40;
192
+ readonly xl: 56;
193
+ };
194
+ declare const listGap: {
195
+ readonly item: 16;
196
+ readonly section: 24;
197
+ };
198
+ declare const divider: {
199
+ readonly hairline: number;
200
+ readonly inset: 16;
201
+ };
202
+ declare const radii: {
203
+ readonly xs: 4;
204
+ readonly sm: 6;
205
+ readonly md: 8;
206
+ readonly lg: 12;
207
+ readonly xl: 16;
208
+ readonly xxl: 20;
209
+ readonly pill: 9999;
210
+ };
211
+ declare const typography: {
212
+ /** iOS-style large screen title. Big, bold, tight tracking. */
213
+ readonly largeTitle: {
214
+ readonly fontSize: 30;
215
+ readonly fontWeight: "700";
216
+ readonly lineHeight: 36;
217
+ readonly letterSpacing: -0.6;
218
+ };
219
+ readonly display: {
220
+ readonly fontSize: 28;
221
+ readonly fontWeight: "700";
222
+ readonly lineHeight: 36;
223
+ readonly letterSpacing: -0.4;
224
+ };
225
+ readonly title: {
226
+ readonly fontSize: 20;
227
+ readonly fontWeight: "700";
228
+ readonly lineHeight: 27;
229
+ readonly letterSpacing: -0.3;
230
+ };
231
+ readonly heading: {
232
+ readonly fontSize: 16;
233
+ readonly fontWeight: "600";
234
+ readonly lineHeight: 22;
235
+ readonly letterSpacing: -0.2;
236
+ };
237
+ readonly subtitle: {
238
+ readonly fontSize: 14;
239
+ readonly fontWeight: "400";
240
+ readonly lineHeight: 20;
241
+ };
242
+ readonly body: {
243
+ readonly fontSize: 15;
244
+ readonly fontWeight: "400";
245
+ readonly lineHeight: 22;
246
+ };
247
+ readonly label: {
248
+ readonly fontSize: 13;
249
+ readonly fontWeight: "600";
250
+ readonly lineHeight: 18;
251
+ readonly letterSpacing: -0.1;
252
+ };
253
+ readonly caption: {
254
+ readonly fontSize: 13;
255
+ readonly fontWeight: "400";
256
+ readonly lineHeight: 18;
257
+ };
258
+ readonly micro: {
259
+ readonly fontSize: 11;
260
+ readonly fontWeight: "500";
261
+ readonly lineHeight: 14;
262
+ readonly letterSpacing: 0.2;
263
+ };
264
+ readonly tabLabel: {
265
+ readonly fontSize: 11;
266
+ readonly fontWeight: "600";
267
+ readonly lineHeight: 14;
268
+ readonly letterSpacing: 0.1;
269
+ };
270
+ /** Small uppercase eyebrow that replaces big page titles. */
271
+ readonly overline: {
272
+ readonly fontSize: 11;
273
+ readonly fontWeight: "700";
274
+ readonly lineHeight: 14;
275
+ readonly letterSpacing: 0.8;
276
+ readonly textTransform: "uppercase";
277
+ };
278
+ };
279
+ /** Tabular figures for stats/counts so numbers don't jitter. */
280
+ declare const numericText: {
281
+ fontVariant: TextStyle['fontVariant'];
282
+ };
283
+ declare const motion: {
284
+ readonly fast: 140;
285
+ readonly base: 220;
286
+ readonly slow: 320;
287
+ /** Shared easing curves (Material-ish). Use with Animated.timing({ easing }). */
288
+ readonly easing: {
289
+ readonly standard: react_native.EasingFunction;
290
+ readonly decelerate: react_native.EasingFunction;
291
+ readonly accelerate: react_native.EasingFunction;
292
+ readonly emphasized: react_native.EasingFunction;
293
+ };
294
+ /** Spring config for press/scale micro-interactions (Animated.spring). */
295
+ readonly spring: {
296
+ readonly friction: 7;
297
+ readonly tension: 120;
298
+ };
299
+ };
300
+ /** Standard icon sizes for the <Icon> component. */
301
+ declare const iconSizes: {
302
+ readonly xs: 14;
303
+ readonly sm: 16;
304
+ readonly md: 20;
305
+ readonly lg: 24;
306
+ readonly xl: 32;
307
+ };
308
+ /** Square sizes for tinted IconTile accents (the core Soft Neutral motif). */
309
+ declare const tile: {
310
+ readonly sm: 32;
311
+ readonly md: 40;
312
+ readonly lg: 48;
313
+ };
314
+ declare const MIN_TAP_TARGET = 44;
315
+ declare const DEFAULT_HIT_SLOP: {
316
+ readonly top: 8;
317
+ readonly bottom: 8;
318
+ readonly left: 8;
319
+ readonly right: 8;
320
+ };
321
+ /**
322
+ * Soft Neutral elevation. Regular content cards stay quiet (`card`) — a single
323
+ * subtle tier — while sheets/modals lift further. `sm/md/lg` are preserved for
324
+ * backward compatibility (exported tokens / existing consumers).
325
+ */
326
+ declare const elevation: Record<'sm' | 'md' | 'lg' | 'card' | 'raised' | 'sheet' | 'fab', ViewStyle>;
327
+
8
328
  interface ThemeColors {
9
329
  background: string;
10
330
  /** Page canvas. Flat mode keeps this equal to background. */
@@ -47,18 +367,37 @@ type BrandingMeta = {
47
367
  icon_url: string | null;
48
368
  brand_name: string;
49
369
  hide_platform_branding: boolean;
370
+ /** The DPO / grievance officer's public contact, when branding serves it. */
371
+ dpo_email?: string;
372
+ privacy_policy_url?: string | null;
373
+ legal_name?: string | null;
50
374
  };
375
+ type RadiusToken = Exclude<keyof typeof radii, 'pill'>;
51
376
  interface ThemeContextType {
52
377
  colors: ThemeColors;
53
378
  /** Org branding metadata (logo, brand name). Null until/unless it resolves. */
54
379
  branding: BrandingMeta | null;
55
380
  /** True while org branding is being fetched (used to gate first paint). */
56
381
  isLoading: boolean;
382
+ /**
383
+ * The organisation's font, resolved through the font catalogue the notice
384
+ * uses; undefined keeps the Privacy Center's own font.
385
+ */
386
+ fontFamily: string | undefined;
387
+ /**
388
+ * A corner radius from the design tokens, scaled to the published corner
389
+ * radius when the settings set one; the token itself otherwise.
390
+ */
391
+ radius: (token: RadiusToken) => number;
392
+ /** The published logo height (28–96), or null for each screen's own size. */
393
+ logoHeight: number | null;
57
394
  }
58
- declare function ThemeProvider({ children, slug, baseUrl, }: {
395
+ declare function ThemeProvider({ children, slug, baseUrl, organisationUuid: organisationUuidProp, }: {
59
396
  children: ReactNode;
397
+ /** @deprecated Ignored; will be removed in a future major release. Passing it logs a one-time warning. */
60
398
  slug?: string;
61
399
  baseUrl?: string;
400
+ organisationUuid?: string;
62
401
  }): React.JSX.Element;
63
402
  declare function useTheme(): ThemeContextType;
64
403
 
@@ -95,6 +434,8 @@ type OrgBrandingTheme = {
95
434
  success: string;
96
435
  warning: string;
97
436
  danger: string;
437
+ /** The organisation's font as chosen in the console; absent or blank when unset. */
438
+ font_family?: string | null;
98
439
  };
99
440
  type OrgBrandingDetail = {
100
441
  logo_url: string | null;
@@ -102,6 +443,12 @@ type OrgBrandingDetail = {
102
443
  brand_name: string;
103
444
  theme: OrgBrandingTheme;
104
445
  hide_platform_branding: boolean;
446
+ /** The DPO / grievance officer's public contact; empty when unset. */
447
+ dpo_email?: string;
448
+ /** Absent on a user service that does not serve it publicly. */
449
+ privacy_policy_url?: string | null;
450
+ /** Absent on a user service that does not serve it publicly. */
451
+ legal_name?: string | null;
105
452
  };
106
453
  type NotificationType = 'guardian_verification_request' | 'consent_expiry_warning' | 'new_consent_notice' | 'consent_withdrawal_confirmation' | 'data_request_status_update' | 'case_message' | 'grievance_status_update' | 'consent_regrant_prompt';
107
454
  type NotificationCategory = 'consent' | 'request' | 'system';
@@ -204,6 +551,7 @@ type FormData$1 = {
204
551
  purposes: RawPurposeWrapper[];
205
552
  direct_groups?: FormProductGroup[];
206
553
  nominated_groups?: FormProductGroup[];
554
+ enabled_request_types?: string[] | null;
207
555
  };
208
556
  declare enum RequestTypeEnum {
209
557
  ACCESS = "ACCESS",
@@ -511,6 +859,46 @@ type SelectPrincipalResponse = Readonly<{
511
859
  refresh_token: string;
512
860
  expires_at?: string;
513
861
  }>;
862
+ /** Passed to `onReady` once the first screen is on show. */
863
+ type PrivacyCenterReadyEvent = Readonly<{
864
+ /** False when the built-in sign-in screen is what the visitor sees. */
865
+ signedIn: boolean;
866
+ }>;
867
+ /** Passed to `onConsentChange` after a consent was changed successfully. */
868
+ type PrivacyCenterConsentChange = Readonly<{
869
+ /** `revoke` withdraws consent; `regrant` and `renew` give it again. */
870
+ action: ConsentAction;
871
+ purposeUuid: string;
872
+ productUuid: string | null;
873
+ /** The data elements the change covered; empty when it covered the whole purpose. */
874
+ dataElementUuids: readonly string[];
875
+ /** Set when the visitor acted on behalf of someone who nominated them. */
876
+ nominatorUuid: string | null;
877
+ }>;
878
+ /** Passed to `onRequestSubmit` after a data request (case) was created. */
879
+ type PrivacyCenterRequestSubmission = Readonly<{
880
+ /** The human-readable case id shown to the visitor. */
881
+ caseId: string;
882
+ caseUuid: string;
883
+ requestType: PrivacyCenterRequestTypeKey;
884
+ /** The product the request is about; null for nomination and grievance. */
885
+ productUuid: string | null;
886
+ }>;
887
+ /**
888
+ * Why the visitor was signed out: they chose to (`user`), they were idle for
889
+ * the configured session timeout (`timeout`), or their session could no longer
890
+ * be refreshed (`session-expired`).
891
+ */
892
+ type PrivacyCenterSignOutReason = 'user' | 'timeout' | 'session-expired';
893
+ type PrivacyCenterSignOutEvent = Readonly<{
894
+ reason: PrivacyCenterSignOutReason;
895
+ }>;
896
+ type PrivacyCenterEventHandlers = Readonly<{
897
+ onReady?: (event: PrivacyCenterReadyEvent) => void;
898
+ onConsentChange?: (change: PrivacyCenterConsentChange) => void;
899
+ onRequestSubmit?: (request: PrivacyCenterRequestSubmission) => void;
900
+ onSignOut?: (event: PrivacyCenterSignOutEvent) => void;
901
+ }>;
514
902
 
515
903
  type InternalPage = 'home' | 'consent-manager' | 'form' | 'activity' | 'receipts' | 'case-details' | 'notifications';
516
904
  interface NavigationContextType {
@@ -530,10 +918,26 @@ declare function NavigationProvider({ children, initialPage, initialPendingCaseU
530
918
  declare function useInternalNavigation(): NavigationContextType;
531
919
 
532
920
  interface RedactoPrivacyCenterProps {
921
+ /**
922
+ * API host, e.g. `https://api.redacto.io` (recommended). The SDK calls the
923
+ * consent server at `{host}/consent`, the ledger at `{host}/consent-ledger`
924
+ * and the user service at `{host}/user/api/0`. The consent server URL
925
+ * (`…/consent`) still works but is deprecated.
926
+ */
533
927
  baseUrl: string;
534
- /** Go ledger base URL — serves user-consents; omit to use the legacy Python privacy-center consent endpoints. */
928
+ /**
929
+ * @deprecated Read only when `baseUrl` is the consent server URL
930
+ * (`…/consent`), as in earlier releases: it is then the Go ledger base URL
931
+ * that serves user-consents, and leaving it out uses the legacy Python
932
+ * privacy-center consent endpoints. Ignored when `baseUrl` is the API host.
933
+ */
535
934
  ledgerBaseUrl?: string;
536
- slug: string;
935
+ /**
936
+ * @deprecated Ignored; will be removed in a future major release. Passing it
937
+ * logs a one-time warning. The organisation comes from the access token, or
938
+ * from `organisationUuid` and `workspaceUuid`.
939
+ */
940
+ slug?: string;
537
941
  /**
538
942
  * @deprecated The Privacy Center now themes itself from per-org branding.
539
943
  * Accepted for backwards compatibility but ignored.
@@ -569,8 +973,27 @@ interface RedactoPrivacyCenterProps {
569
973
  /** Optional deep-link: open a specific case (use with initialPage='case-details'). */
570
974
  initialCaseUuid?: string;
571
975
  onBack?: 'back' | 'signout';
976
+ /**
977
+ * Overrides for the settings published from the Redacto console, merged
978
+ * field by field over them per group; see `PrivacyCenterSettings`.
979
+ */
980
+ settings?: PrivacyCenterSettings;
981
+ /**
982
+ * With no token, show the built-in OTP sign-in screen. Off by default: with
983
+ * no token the Privacy Center keeps its loading state until the host passes
984
+ * one, so a token that arrives a moment late never flashes a sign-in.
985
+ */
986
+ builtInSignIn?: boolean;
987
+ /** Called once, when the first screen (sign-in or the Privacy Center) is on show. */
988
+ onReady?: (event: PrivacyCenterReadyEvent) => void;
989
+ /** Called after the visitor withdrew, re-granted or renewed a consent. */
990
+ onConsentChange?: (change: PrivacyCenterConsentChange) => void;
991
+ /** Called after the visitor submitted a data request. */
992
+ onRequestSubmit?: (request: PrivacyCenterRequestSubmission) => void;
993
+ /** Called when the visitor is signed out, with the reason. */
994
+ onSignOut?: (event: PrivacyCenterSignOutEvent) => void;
572
995
  }
573
- declare function RedactoPrivacyCenter({ baseUrl, ledgerBaseUrl, slug, theme: _theme, accessToken, refreshToken, token, email, mobile, ucic, organisationUuid, workspaceUuid, onError, initialPage, initialCaseUuid, onBack, }: RedactoPrivacyCenterProps): React.JSX.Element;
996
+ declare function RedactoPrivacyCenter({ baseUrl, ledgerBaseUrl, slug, theme: _theme, accessToken, refreshToken, token, email, mobile, ucic, organisationUuid, workspaceUuid, onError, initialPage, initialCaseUuid, onBack, settings, onReady, onConsentChange, onRequestSubmit, onSignOut, builtInSignIn, }: RedactoPrivacyCenterProps): React.JSX.Element;
574
997
 
575
998
  declare function ConsentManager(): React__default.JSX.Element;
576
999
 
@@ -627,9 +1050,9 @@ type FooterProps = {
627
1050
  inline?: boolean;
628
1051
  };
629
1052
  /**
630
- * "Powered by Redacto" platform attribution. Hidden when the org has opted out
631
- * via branding.hide_platform_branding. Renders the Redacto logo (raster) next to
632
- * the localized "Powered by" label, mirroring the web Privacy Center footer.
1053
+ * "Powered by Redacto" platform attribution, shown unless the org opted out
1054
+ * (branding.hide_platform_branding) or the settings turned it off, with the
1055
+ * links, contact lines and copyright the published settings add above it.
633
1056
  */
634
1057
  declare function Footer({ inline }: FooterProps): React__default.JSX.Element | null;
635
1058
 
@@ -667,12 +1090,15 @@ type BaseRequest = {
667
1090
  /**
668
1091
  * Consent service client factory.
669
1092
  * Creates a client instance with a specific base URL.
670
- * @param baseUrl - Consent server base URL (Python service, e.g. http://host/consent)
671
- * @param ledgerBaseUrl - Go ledger base URL (e.g. http://host:8090/consent-ledger).
672
- * Used for user-consents reads/writes served from the ledger's `/public/...` paths.
673
- * When omitted, those calls fall back to the legacy Python
674
- * `/dsar/privacy-center` endpoints and payloads (pre-ledger behavior), so
675
- * integrations without a deployed ledger keep working.
1093
+ * @param baseUrl - API host, e.g. `https://api.redacto.io` (recommended): the
1094
+ * consent server is `{host}/consent` and the ledger `{host}/consent-ledger`.
1095
+ * The consent server URL (`.../consent`) still works but is deprecated.
1096
+ * @param ledgerBaseUrl - Deprecated. Read only when `baseUrl` is the consent
1097
+ * server URL, as in earlier releases: it is then the Go ledger (e.g.
1098
+ * http://host:8090/consent-ledger), used for user-consents reads/writes
1099
+ * served from the ledger's `/public/...` paths; when omitted, those calls
1100
+ * fall back to the legacy Python `/dsar/privacy-center` endpoints and
1101
+ * payloads (pre-ledger behavior). Ignored when `baseUrl` is the API host.
676
1102
  */
677
1103
  declare function createConsentClient(baseUrl: string, ledgerBaseUrl?: string): {
678
1104
  /**
@@ -688,9 +1114,10 @@ declare function createConsentClient(baseUrl: string, ledgerBaseUrl?: string): {
688
1114
  useSessionAuth?: boolean;
689
1115
  }): Promise<unknown>;
690
1116
  /**
691
- * Create OTP (public)
1117
+ * Create OTP (public). `to` is an email, or an E.164 number with
1118
+ * `channel: "sms"`.
692
1119
  */
693
- createOtp(organisationId: string, workspaceId: string, email: string, options?: Omit<ApiFetchOptions, "getAuthToken">): Promise<unknown>;
1120
+ createOtp(organisationId: string, workspaceId: string, email: string, options?: Omit<ApiFetchOptions, "getAuthToken">, channel?: "email" | "sms"): Promise<unknown>;
694
1121
  /**
695
1122
  * Verify OTP (public)
696
1123
  *
@@ -750,13 +1177,20 @@ declare function createConsentClient(baseUrl: string, ledgerBaseUrl?: string): {
750
1177
  * The principal is resolved from the JWT, so no `contact`/identifiers are
751
1178
  * sent in the body.
752
1179
  *
1180
+ * A nominee acting on a nominator's consent sends `nominator_uuid`: the
1181
+ * ledger re-checks the nomination edge and records the consent against the
1182
+ * nominator. Without it the principal resolves to the caller, so a
1183
+ * nominee's revoke opened a declined consent of their own and left the
1184
+ * nominator's granted. The legacy Python endpoint expresses the same thing
1185
+ * as `nominator_contact`.
1186
+ *
753
1187
  * Without a ledger, the legacy Python `/manage-consent?status=` endpoint is
754
1188
  * used with its `{ purpose_uuid, contact, ... }` payload.
755
1189
  */
756
1190
  manageConsent(baseRequest: BaseRequest, purposeId: string, contact: string, status: "revoke" | "regrant" | "renew", authToken?: string, options?: Omit<ApiFetchOptions, "getAuthToken">, nominatorContact?: string, dataElementUuids?: string[], noticeUuid?: string, dataElements?: Array<{
757
1191
  uuid: string;
758
1192
  selected: boolean;
759
- }>, language?: string): Promise<unknown>;
1193
+ }>, language?: string, nominatorUuid?: string, productUuid?: string): Promise<unknown>;
760
1194
  /**
761
1195
  * Get activities (privacy center)
762
1196
  */
@@ -840,14 +1274,20 @@ declare function createConsentClient(baseUrl: string, ledgerBaseUrl?: string): {
840
1274
  };
841
1275
 
842
1276
  interface BaseUrlContextValue {
1277
+ /** The consent server URL: `{host}/consent` when the provider was given the API host. */
843
1278
  baseUrl: string;
844
- /** Go ledger base URL — serves user-consents; omit to use the legacy Python privacy-center consent endpoints. */
1279
+ /** Go ledger base URL — serves user-consents: `{host}/consent-ledger` when the provider was given the API host. Absent only for a legacy consent server URL with no ledger, which uses the legacy Python privacy-center consent endpoints. */
845
1280
  ledgerBaseUrl?: string;
846
1281
  consentClient: ReturnType<typeof createConsentClient>;
847
1282
  }
848
1283
  declare function BaseUrlProvider({ children, baseUrl, ledgerBaseUrl, }: {
849
1284
  children: ReactNode;
1285
+ /**
1286
+ * API host, e.g. `https://api.redacto.io` (recommended). The consent server
1287
+ * URL (`…/consent`) still works but is deprecated.
1288
+ */
850
1289
  baseUrl: string;
1290
+ /** @deprecated Read only when `baseUrl` is the consent server URL (`…/consent`), as in earlier releases. Ignored when `baseUrl` is the API host. */
851
1291
  ledgerBaseUrl?: string;
852
1292
  }): React.JSX.Element;
853
1293
  declare function useBaseUrl(): BaseUrlContextValue;
@@ -904,7 +1344,7 @@ type FetchUserConsentsParams = {
904
1344
  consentClient?: BaseUrlContextValue['consentClient'];
905
1345
  };
906
1346
  declare const fetchUserConsents: (params: FetchUserConsentsParams) => Promise<UserConsentDetail | null>;
907
- declare const manageConsent: ({ organizationId, workspaceId, purposeId, contact, action, authContext, consentClient, nominatorContact, dataElementUuids, noticeUuid, dataElements, language, }: {
1347
+ declare const manageConsent: ({ organizationId, workspaceId, purposeId, contact, action, authContext, consentClient, nominatorContact, nominatorUuid, dataElementUuids, noticeUuid, dataElements, language, productUuid, }: {
908
1348
  organizationId: string;
909
1349
  workspaceId: string;
910
1350
  purposeId: string;
@@ -913,6 +1353,7 @@ declare const manageConsent: ({ organizationId, workspaceId, purposeId, contact,
913
1353
  authContext?: AuthContext;
914
1354
  consentClient?: BaseUrlContextValue["consentClient"];
915
1355
  nominatorContact?: string;
1356
+ nominatorUuid?: string;
916
1357
  dataElementUuids?: string[];
917
1358
  noticeUuid?: string;
918
1359
  dataElements?: Array<{
@@ -920,6 +1361,7 @@ declare const manageConsent: ({ organizationId, workspaceId, purposeId, contact,
920
1361
  selected: boolean;
921
1362
  }>;
922
1363
  language?: string;
1364
+ productUuid?: string;
923
1365
  }) => Promise<boolean | null>;
924
1366
  declare const fetchActivities: (organizationId: string, workspaceId: string, offset?: number, limit?: number, authContext?: AuthContext, consentClient?: BaseUrlContextValue["consentClient"], language?: string) => Promise<ActivityDetail | null>;
925
1367
  declare const fetchCaseHistory: (organizationId: string, workspaceId: string, contact: string, offset?: number, limit?: number, authContext?: AuthContext, consentClient?: BaseUrlContextValue["consentClient"], language?: string) => Promise<CaseHistoryDetail | null>;
@@ -940,6 +1382,18 @@ interface AuthContextType {
940
1382
  organizationName: string | null;
941
1383
  updateTokens: (accessToken: string, refreshToken?: string) => void;
942
1384
  onError: (error: Error) => boolean;
1385
+ /**
1386
+ * True once the session ended: the refresh token is expired or invalid, or
1387
+ * the visitor was signed out for inactivity. Drives the session-expired
1388
+ * screen and gates further fetching.
1389
+ */
1390
+ sessionExpired: boolean;
1391
+ /** Records that the session can no longer be refreshed. */
1392
+ markSessionExpired: () => void;
1393
+ /** Signs the visitor out (e.g. after inactivity) and shows the session-expired screen. */
1394
+ expireSession: (reason: PrivacyCenterSignOutReason) => void;
1395
+ /** Drops the session so the built-in sign-in screen shows again. */
1396
+ restartSignIn: () => void;
943
1397
  }
944
1398
  interface AuthProviderProps {
945
1399
  children: ReactNode;
@@ -962,7 +1416,7 @@ interface AuthProviderProps {
962
1416
  organisationUuid?: string;
963
1417
  /** Sandbox workspace UUID (replaces the JWT-decoded workspace). */
964
1418
  workspaceUuid?: string;
965
- /** Organisation slug — used to seed the sandbox config. */
1419
+ /** @deprecated Ignored; will be removed in a future major release. */
966
1420
  slug?: string;
967
1421
  onError: (error: Error) => boolean;
968
1422
  }
@@ -1351,154 +1805,36 @@ type LayoutAnimationPreset = 'expandCollapse' | 'listReorder';
1351
1805
  */
1352
1806
  declare function animateNextLayout(preset?: LayoutAnimationPreset): void;
1353
1807
 
1354
- declare const spacing: {
1355
- readonly xs: 4;
1356
- readonly sm: 8;
1357
- readonly md: 12;
1358
- readonly lg: 16;
1359
- readonly xl: 24;
1360
- readonly xxl: 32;
1361
- readonly xxxl: 40;
1362
- readonly huge: 56;
1363
- };
1364
- declare const section: {
1365
- readonly sm: 24;
1366
- readonly md: 32;
1367
- readonly lg: 40;
1368
- readonly xl: 56;
1369
- };
1370
- declare const listGap: {
1371
- readonly item: 16;
1372
- readonly section: 24;
1373
- };
1374
- declare const divider: {
1375
- readonly hairline: number;
1376
- readonly inset: 16;
1377
- };
1378
- declare const radii: {
1379
- readonly xs: 4;
1380
- readonly sm: 6;
1381
- readonly md: 8;
1382
- readonly lg: 12;
1383
- readonly xl: 16;
1384
- readonly xxl: 20;
1385
- readonly pill: 9999;
1386
- };
1387
- declare const typography: {
1388
- /** iOS-style large screen title. Big, bold, tight tracking. */
1389
- readonly largeTitle: {
1390
- readonly fontSize: 30;
1391
- readonly fontWeight: "700";
1392
- readonly lineHeight: 36;
1393
- readonly letterSpacing: -0.6;
1394
- };
1395
- readonly display: {
1396
- readonly fontSize: 28;
1397
- readonly fontWeight: "700";
1398
- readonly lineHeight: 36;
1399
- readonly letterSpacing: -0.4;
1400
- };
1401
- readonly title: {
1402
- readonly fontSize: 20;
1403
- readonly fontWeight: "700";
1404
- readonly lineHeight: 27;
1405
- readonly letterSpacing: -0.3;
1406
- };
1407
- readonly heading: {
1408
- readonly fontSize: 16;
1409
- readonly fontWeight: "600";
1410
- readonly lineHeight: 22;
1411
- readonly letterSpacing: -0.2;
1412
- };
1413
- readonly subtitle: {
1414
- readonly fontSize: 14;
1415
- readonly fontWeight: "400";
1416
- readonly lineHeight: 20;
1417
- };
1418
- readonly body: {
1419
- readonly fontSize: 15;
1420
- readonly fontWeight: "400";
1421
- readonly lineHeight: 22;
1422
- };
1423
- readonly label: {
1424
- readonly fontSize: 13;
1425
- readonly fontWeight: "600";
1426
- readonly lineHeight: 18;
1427
- readonly letterSpacing: -0.1;
1428
- };
1429
- readonly caption: {
1430
- readonly fontSize: 13;
1431
- readonly fontWeight: "400";
1432
- readonly lineHeight: 18;
1433
- };
1434
- readonly micro: {
1435
- readonly fontSize: 11;
1436
- readonly fontWeight: "500";
1437
- readonly lineHeight: 14;
1438
- readonly letterSpacing: 0.2;
1439
- };
1440
- readonly tabLabel: {
1441
- readonly fontSize: 11;
1442
- readonly fontWeight: "600";
1443
- readonly lineHeight: 14;
1444
- readonly letterSpacing: 0.1;
1445
- };
1446
- /** Small uppercase eyebrow that replaces big page titles. */
1447
- readonly overline: {
1448
- readonly fontSize: 11;
1449
- readonly fontWeight: "700";
1450
- readonly lineHeight: 14;
1451
- readonly letterSpacing: 0.8;
1452
- readonly textTransform: "uppercase";
1453
- };
1454
- };
1455
- /** Tabular figures for stats/counts so numbers don't jitter. */
1456
- declare const numericText: {
1457
- fontVariant: TextStyle['fontVariant'];
1458
- };
1459
- declare const motion: {
1460
- readonly fast: 140;
1461
- readonly base: 220;
1462
- readonly slow: 320;
1463
- /** Shared easing curves (Material-ish). Use with Animated.timing({ easing }). */
1464
- readonly easing: {
1465
- readonly standard: react_native.EasingFunction;
1466
- readonly decelerate: react_native.EasingFunction;
1467
- readonly accelerate: react_native.EasingFunction;
1468
- readonly emphasized: react_native.EasingFunction;
1469
- };
1470
- /** Spring config for press/scale micro-interactions (Animated.spring). */
1471
- readonly spring: {
1472
- readonly friction: 7;
1473
- readonly tension: 120;
1474
- };
1475
- };
1476
- /** Standard icon sizes for the <Icon> component. */
1477
- declare const iconSizes: {
1478
- readonly xs: 14;
1479
- readonly sm: 16;
1480
- readonly md: 20;
1481
- readonly lg: 24;
1482
- readonly xl: 32;
1483
- };
1484
- /** Square sizes for tinted IconTile accents (the core Soft Neutral motif). */
1485
- declare const tile: {
1486
- readonly sm: 32;
1487
- readonly md: 40;
1488
- readonly lg: 48;
1489
- };
1490
- declare const MIN_TAP_TARGET = 44;
1491
- declare const DEFAULT_HIT_SLOP: {
1492
- readonly top: 8;
1493
- readonly bottom: 8;
1494
- readonly left: 8;
1495
- readonly right: 8;
1496
- };
1497
1808
  /**
1498
- * Soft Neutral elevation. Regular content cards stay quiet (`card`) — a single
1499
- * subtle tier — while sheets/modals lift further. `sm/md/lg` are preserved for
1500
- * backward compatibility (exported tokens / existing consumers).
1809
+ * Reproduces today's Privacy Center: with nothing published, every value here
1810
+ * renders exactly what the SDK rendered before settings existed.
1501
1811
  */
1502
- declare const elevation: Record<'sm' | 'md' | 'lg' | 'card' | 'raised' | 'sheet' | 'fab', ViewStyle>;
1812
+ declare const DEFAULT_PRIVACY_CENTER_SETTINGS: ResolvedPrivacyCenterSettings;
1813
+
1814
+ /**
1815
+ * The settings the Privacy Center renders with: the published payload (or
1816
+ * nothing, when none was fetched) validated field by field, with the host's
1817
+ * `settings` prop merged over each group. Anything missing or malformed takes
1818
+ * the default, so a bad payload can never break the page or change it from
1819
+ * today's look by accident.
1820
+ */
1821
+ declare const resolvePrivacyCenterSettings: (published: unknown, overrides?: PrivacyCenterSettings | null) => ResolvedPrivacyCenterSettings;
1822
+
1823
+ /**
1824
+ * Fills `{brand}`, `{legal}`, `{year}`, `{contact}` and `{name}` in custom
1825
+ * copy. `{legal}` falls back to the brand, and an empty value (no name known)
1826
+ * collapses cleanly: "Welcome back, {name}!" reads "Welcome back!".
1827
+ */
1828
+ declare const resolvePlaceholders: (text: string | null | undefined, context: PlaceholderContext) => string;
1829
+
1830
+ /**
1831
+ * The organisation's published Privacy Center settings, localised to
1832
+ * `language`. Public and unauthenticated. Resolves to `null` on any failure
1833
+ * (network, 4xx/5xx, an unexpected body) so callers keep today's defaults;
1834
+ * never rejects. One request per organisation and language is shared for
1835
+ * `SETTINGS_CACHE_TTL_MS`, so a later mount or language switch picks up a new
1836
+ * publish; a failed one is forgotten so the next mount retries.
1837
+ */
1838
+ declare const fetchPublicPrivacyCenterSettings: (baseUrl: string, organisationUuid: string, language: string) => Promise<PublicPrivacyCenterSettingsResponse | null>;
1503
1839
 
1504
- export { ActivitiesList, type Activity, type ActivityDetail, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, BottomSheet, BottomTabBar, CaseDetailsPage, type CaseDetailsTab, CaseHistory, type CaseHistoryDetail, type CaseMessage, type CaseRequest, type CaseStatusVariant, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentManager, ConsentStatusEnum, type CreateCaseResponse, DEFAULT_HIT_SLOP, DETAIL_PAGES, type DataElement, type DocumentRequestMetadata, type DocumentRequestStatus, type FilterTab, Footer, Form, type FormData$1 as FormData, FormPage, type GrievanceTypeElement, GrievanceTypeEnum, Icon, type IconName, type IconProps, IconTile, type IconTileSize, type IconTileTone, type InternalPage, MIN_TAP_TARGET, type ManageConsentParams, type MessageDocument, type MessageType, Navbar, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, type Notification, type NotificationCTA, type NotificationCategory, type NotificationListResponse, type NotificationSummary, type NotificationType, type OrgBrandingDetail, type OrgBrandingTheme, type OrganizationDetail, type OtpResponse, type OtpVerificationResponse, PCAvatar, PCBadge, PCButton, PCCheckbox, PCDivider, PCEmpty, PCInput, PCListRow, PCListSection, PCLoader, PCModal, PCPageTitle, PCSelect, type PageChromeMode, type Pagination, type PendingUpload, type ProductConsentHistoryGroup, type Purpose, RedactoPrivacyCenter, RequestTypeEnum, SectionHeader, SideMenu, Skeleton, SkeletonRow, StatPill, type TabId, ThemeProvider, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UploadDocumentResponse, type UserConsent, type UserConsentDetail, type UserDataRequest, type Workspace, animateNextLayout, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, divider, elevation, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCaseMessages, getFormData, getListBottomInset, getPageChromeMode, iconSizes, isJwtExpired, listGap, manageConsent, motion, numericText, radii, section, sendCaseMessage, signOutPrivacyCenter, spacing, submitDocumentForRequest, tile, typography, uploadCaseDocument, useAnimatedTabIndicator, useAuth, useBaseUrl, useCaseHistory, useCaseMessages, useFadeIn, useInternalNavigation, usePressScale, usePrivacyCenterInsets, useTheme, verifyOtpServer as verifyOtp };
1840
+ export { ActivitiesList, type Activity, type ActivityDetail, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, BottomSheet, BottomTabBar, CaseDetailsPage, type CaseDetailsTab, CaseHistory, type CaseHistoryDetail, type CaseMessage, type CaseRequest, type CaseStatusVariant, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentManager, ConsentStatusEnum, type CreateCaseResponse, DEFAULT_HIT_SLOP, DEFAULT_PRIVACY_CENTER_SETTINGS, DETAIL_PAGES, type DataElement, type DocumentRequestMetadata, type DocumentRequestStatus, type FilterTab, Footer, Form, type FormData$1 as FormData, FormPage, type GrievanceTypeElement, GrievanceTypeEnum, Icon, type IconName, type IconProps, IconTile, type IconTileSize, type IconTileTone, type InternalPage, MIN_TAP_TARGET, type ManageConsentParams, type MessageDocument, type MessageType, Navbar, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, type Notification, type NotificationCTA, type NotificationCategory, type NotificationListResponse, type NotificationSummary, type NotificationType, type OrgBrandingDetail, type OrgBrandingTheme, type OrganizationDetail, type OtpResponse, type OtpVerificationResponse, PCAvatar, PCBadge, PCButton, PCCheckbox, PCDivider, PCEmpty, PCInput, PCListRow, PCListSection, PCLoader, PCModal, PCPageTitle, PCSelect, type PageChromeMode, type Pagination, type PendingUpload, type PlaceholderContext, type PrivacyCenterBrandContact, type PrivacyCenterBrandingSettings, type PrivacyCenterConsentChange, type PrivacyCenterEmbedSettings, type PrivacyCenterEventHandlers, type PrivacyCenterFooterLink, type PrivacyCenterFooterSettings, type PrivacyCenterGrievanceCategory, type PrivacyCenterLanguageSettings, type PrivacyCenterPortalSettings, type PrivacyCenterReadyEvent, type PrivacyCenterRequestSubmission, type PrivacyCenterRequestType, type PrivacyCenterRequestTypeKey, type PrivacyCenterSection, type PrivacyCenterSectionKey, type PrivacyCenterSeoSettings, type PrivacyCenterSettings, type PrivacyCenterSignInChannels, type PrivacyCenterSignInLayout, type PrivacyCenterSignInSettings, type PrivacyCenterSignOutEvent, type PrivacyCenterSignOutReason, type ProductConsentHistoryGroup, type PublicPrivacyCenterSettingsResponse, type Purpose, RedactoPrivacyCenter, RequestTypeEnum, type ResolvedPrivacyCenterSettings, SectionHeader, SideMenu, Skeleton, SkeletonRow, StatPill, type TabId, ThemeProvider, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UploadDocumentResponse, type UserConsent, type UserConsentDetail, type UserDataRequest, type Workspace, animateNextLayout, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, divider, elevation, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchPublicPrivacyCenterSettings, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCaseMessages, getFormData, getListBottomInset, getPageChromeMode, iconSizes, isJwtExpired, listGap, manageConsent, motion, numericText, radii, resolvePlaceholders, resolvePrivacyCenterSettings, section, sendCaseMessage, signOutPrivacyCenter, spacing, submitDocumentForRequest, tile, typography, uploadCaseDocument, useAnimatedTabIndicator, useAuth, useBaseUrl, useCaseHistory, useCaseMessages, useFadeIn, useInternalNavigation, usePressScale, usePrivacyCenterInsets, useTheme, verifyOtpServer as verifyOtp };