@redacto.io/consent-sdk-react 3.5.0 → 4.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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Consent SDK Components
3
+ *
4
+ * Export reusable components for the consent flow.
5
+ */
6
+
7
+ export { DigiLockerCallback } from "./DigiLockerCallback";
@@ -133,6 +133,17 @@ export const injectCheckboxStyles = () => {
133
133
  outline: 3px solid #FFF9C4 !important;
134
134
  outline-offset: 2px !important;
135
135
  }
136
+
137
+ /* Spinner animation for verification screens */
138
+ @keyframes spin {
139
+ from { transform: rotate(0deg); }
140
+ to { transform: rotate(360deg); }
141
+ }
142
+
143
+ /* DigiLocker callback retry button hover */
144
+ .redacto-dl-retry-btn:hover {
145
+ background-color: #2563eb !important;
146
+ }
136
147
  `;
137
148
 
138
149
  document.head.appendChild(style);
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Session Storage Service
3
+ *
4
+ * Handles state persistence for consent flow during DigiLocker redirects.
5
+ * Uses sessionStorage to maintain state across page navigations.
6
+ */
7
+
8
+ import type { PersistedConsentState } from "../api/types";
9
+
10
+ const STORAGE_KEY = "redacto_consent_sdk_state";
11
+ const STATE_EXPIRY_MS = 30 * 60 * 1000; // 30 minutes
12
+
13
+ /**
14
+ * Check if code is running in browser environment
15
+ */
16
+ const isBrowser = (): boolean => {
17
+ return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
18
+ };
19
+
20
+ /**
21
+ * Save consent flow state to sessionStorage
22
+ */
23
+ export const saveConsentState = (state: PersistedConsentState): void => {
24
+ if (!isBrowser()) {
25
+ console.warn("SessionStorage not available - state not persisted");
26
+ return;
27
+ }
28
+
29
+ try {
30
+ const stateWithTimestamp = {
31
+ ...state,
32
+ timestamp: new Date().toISOString(),
33
+ };
34
+ sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
35
+ } catch (error) {
36
+ console.error("Failed to save consent state:", error);
37
+ }
38
+ };
39
+
40
+ /**
41
+ * Retrieve consent flow state from sessionStorage
42
+ * Returns null if state doesn't exist or is expired
43
+ */
44
+ export const getConsentState = (): PersistedConsentState | null => {
45
+ if (!isBrowser()) {
46
+ return null;
47
+ }
48
+
49
+ try {
50
+ const savedState = sessionStorage.getItem(STORAGE_KEY);
51
+ if (!savedState) {
52
+ return null;
53
+ }
54
+
55
+ const parsed: PersistedConsentState = JSON.parse(savedState);
56
+
57
+ // Check if state is expired
58
+ const stateAge = Date.now() - new Date(parsed.timestamp).getTime();
59
+ if (stateAge > STATE_EXPIRY_MS) {
60
+ clearConsentState();
61
+ return null;
62
+ }
63
+
64
+ return parsed;
65
+ } catch (error) {
66
+ console.error("Failed to get consent state:", error);
67
+ return null;
68
+ }
69
+ };
70
+
71
+ /**
72
+ * Clear consent flow state from sessionStorage
73
+ */
74
+ export const clearConsentState = (): void => {
75
+ if (!isBrowser()) {
76
+ return;
77
+ }
78
+
79
+ try {
80
+ sessionStorage.removeItem(STORAGE_KEY);
81
+ } catch (error) {
82
+ console.error("Failed to clear consent state:", error);
83
+ }
84
+ };
85
+
86
+ /**
87
+ * Update specific fields in the persisted consent state
88
+ */
89
+ export const updateConsentState = (updates: Partial<PersistedConsentState>): void => {
90
+ const currentState = getConsentState();
91
+ if (currentState) {
92
+ saveConsentState({
93
+ ...currentState,
94
+ ...updates,
95
+ timestamp: new Date().toISOString(),
96
+ });
97
+ }
98
+ };
99
+
100
+ /**
101
+ * Check if there's a pending verification to resume
102
+ */
103
+ export const hasPendingVerification = (): boolean => {
104
+ const state = getConsentState();
105
+ return state !== null && state.flowState === "digilocker-pending";
106
+ };
107
+
108
+ /**
109
+ * Get verification result from persisted state
110
+ */
111
+ export const getVerificationResult = (): "pending" | "verified" | "failed" | "in_progress" | "expired" | null => {
112
+ const state = getConsentState();
113
+ return state?.verificationResult ?? null;
114
+ };
115
+
116
+ /**
117
+ * Get verification reference from persisted state (after successful verification)
118
+ */
119
+ export const getVerificationReference = (): string | null => {
120
+ const state = getConsentState();
121
+ return state?.verificationReference ?? null;
122
+ };
@@ -13,6 +13,8 @@ export type Props = Readonly<{
13
13
  onError?: (error: Error) => void;
14
14
  applicationId?: string;
15
15
  validateAgainst?: "all" | "required";
16
+ digilockerMode?: "popup" | "redirect"; // Default: "redirect" (full page redirect - required for DigiLocker)
17
+ digilockerCallbackUrl?: string; // Default: "/digilocker-callback"
16
18
  includeFullyConsentedData?: boolean;
17
19
  reviewModeButtonText?: string;
18
20
  }>;
package/src/index.ts CHANGED
@@ -1,2 +1,12 @@
1
1
  export { default as RedactoNoticeConsent } from "./RedactoNoticeConsent";
2
2
  export { default as RedactoNoticeConsentInline } from "./RedactoNoticeConsentInline";
3
+
4
+ // Guardian Verification Components
5
+ export { DigiLockerCallback } from "./RedactoNoticeConsent/components/DigiLockerCallback";
6
+
7
+ // Types for Guardian Verification
8
+ export type {
9
+ DigiLockerCallbackProps,
10
+ ConsentFlowState,
11
+ GuardianVerificationErrorCode,
12
+ } from "./RedactoNoticeConsent/api/types";