@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.
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +49 -2
- package/dist/index.d.ts +49 -2
- package/dist/index.js +1785 -243
- package/dist/index.mjs +1784 -243
- package/package.json +1 -1
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +201 -118
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +1192 -93
- package/src/RedactoNoticeConsent/api/index.ts +333 -206
- package/src/RedactoNoticeConsent/api/types.ts +138 -16
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +536 -0
- package/src/RedactoNoticeConsent/components/index.ts +7 -0
- package/src/RedactoNoticeConsent/injectStyles.ts +11 -0
- package/src/RedactoNoticeConsent/services/storage.ts +122 -0
- package/src/RedactoNoticeConsent/types.ts +2 -0
- package/src/index.ts +10 -0
|
@@ -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";
|