@tantainnovative/ndpr-toolkit 1.0.10 → 2.1.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/README.md +289 -136
- package/dist/breach-BpSBPrdk.d.mts +185 -0
- package/dist/breach-BpSBPrdk.d.ts +185 -0
- package/dist/breach-D5zJYNph.d.mts +17 -0
- package/dist/breach-D7NgrdMX.d.ts +17 -0
- package/dist/breach.d.mts +275 -0
- package/dist/breach.d.ts +275 -0
- package/dist/breach.js +2 -0
- package/dist/breach.js.map +1 -0
- package/dist/breach.mjs +2 -0
- package/dist/breach.mjs.map +1 -0
- package/dist/chunk-2SYNHRP6.mjs +2 -0
- package/dist/chunk-2SYNHRP6.mjs.map +1 -0
- package/dist/chunk-2XHD22J7.mjs +7 -0
- package/dist/chunk-2XHD22J7.mjs.map +1 -0
- package/dist/chunk-4A354HL3.js +2 -0
- package/dist/chunk-4A354HL3.js.map +1 -0
- package/dist/chunk-4DKT6IB6.js +94 -0
- package/dist/chunk-4DKT6IB6.js.map +1 -0
- package/dist/chunk-5ZBO2UPH.js +2 -0
- package/dist/chunk-5ZBO2UPH.js.map +1 -0
- package/dist/chunk-6JFTAYXV.mjs +2 -0
- package/dist/chunk-6JFTAYXV.mjs.map +1 -0
- package/dist/chunk-6JVYYLS7.js +2 -0
- package/dist/chunk-6JVYYLS7.js.map +1 -0
- package/dist/chunk-6SGG6WPA.mjs +2 -0
- package/dist/chunk-6SGG6WPA.mjs.map +1 -0
- package/dist/chunk-AQEGDEQM.js +7 -0
- package/dist/chunk-AQEGDEQM.js.map +1 -0
- package/dist/chunk-C2IJWCZQ.mjs +2 -0
- package/dist/chunk-C2IJWCZQ.mjs.map +1 -0
- package/dist/chunk-CMZTI7SG.js +2 -0
- package/dist/chunk-CMZTI7SG.js.map +1 -0
- package/dist/chunk-DB3JH4DS.mjs +2 -0
- package/dist/chunk-DB3JH4DS.mjs.map +1 -0
- package/dist/chunk-EWOZKYLY.mjs +2 -0
- package/dist/chunk-EWOZKYLY.mjs.map +1 -0
- package/dist/chunk-FFW7RUAG.mjs +94 -0
- package/dist/chunk-FFW7RUAG.mjs.map +1 -0
- package/dist/chunk-FK3CSFLJ.js +2 -0
- package/dist/chunk-FK3CSFLJ.js.map +1 -0
- package/dist/chunk-GIV2OHE6.mjs +2 -0
- package/dist/chunk-GIV2OHE6.mjs.map +1 -0
- package/dist/chunk-GMLNWS2N.mjs +2 -0
- package/dist/chunk-GMLNWS2N.mjs.map +1 -0
- package/dist/chunk-IQF726GS.js +2 -0
- package/dist/chunk-IQF726GS.js.map +1 -0
- package/dist/chunk-IWUUVRLJ.js +2 -0
- package/dist/chunk-IWUUVRLJ.js.map +1 -0
- package/dist/chunk-JUN6YPLL.mjs +72 -0
- package/dist/chunk-JUN6YPLL.mjs.map +1 -0
- package/dist/chunk-L3FKTBGV.js +72 -0
- package/dist/chunk-L3FKTBGV.js.map +1 -0
- package/dist/chunk-L52PDW6O.mjs +2 -0
- package/dist/chunk-L52PDW6O.mjs.map +1 -0
- package/dist/chunk-LI6WJ3LZ.js +2 -0
- package/dist/chunk-LI6WJ3LZ.js.map +1 -0
- package/dist/chunk-LXRXDTPI.js +2 -0
- package/dist/chunk-LXRXDTPI.js.map +1 -0
- package/dist/chunk-MQFZHA2D.js +2 -0
- package/dist/chunk-MQFZHA2D.js.map +1 -0
- package/dist/chunk-OITITR6K.mjs +2 -0
- package/dist/chunk-OITITR6K.mjs.map +1 -0
- package/dist/chunk-PDJGTQMY.mjs +2 -0
- package/dist/chunk-PDJGTQMY.mjs.map +1 -0
- package/dist/chunk-PGSA2O5P.mjs +2 -0
- package/dist/chunk-PGSA2O5P.mjs.map +1 -0
- package/dist/chunk-PM7CMTMB.js +4 -0
- package/dist/chunk-PM7CMTMB.js.map +1 -0
- package/dist/chunk-PYEX7DFR.mjs +4 -0
- package/dist/chunk-PYEX7DFR.mjs.map +1 -0
- package/dist/chunk-QKK5S54L.mjs +2 -0
- package/dist/chunk-QKK5S54L.mjs.map +1 -0
- package/dist/chunk-RB26MIRI.js +2 -0
- package/dist/chunk-RB26MIRI.js.map +1 -0
- package/dist/chunk-RGYK4VAY.mjs +2 -0
- package/dist/chunk-RGYK4VAY.mjs.map +1 -0
- package/dist/chunk-RHWW5FDP.js +16 -0
- package/dist/chunk-RHWW5FDP.js.map +1 -0
- package/dist/chunk-RYZEIDNR.js +2 -0
- package/dist/chunk-RYZEIDNR.js.map +1 -0
- package/dist/chunk-SLNMKGQ2.mjs +2 -0
- package/dist/chunk-SLNMKGQ2.mjs.map +1 -0
- package/dist/chunk-SSGJREE3.js +2 -0
- package/dist/chunk-SSGJREE3.js.map +1 -0
- package/dist/chunk-SWF3YVE5.js +4 -0
- package/dist/chunk-SWF3YVE5.js.map +1 -0
- package/dist/chunk-T44JQT2O.mjs +2 -0
- package/dist/chunk-T44JQT2O.mjs.map +1 -0
- package/dist/chunk-TDDAYVKK.js +2 -0
- package/dist/chunk-TDDAYVKK.js.map +1 -0
- package/dist/chunk-TXBZPCGF.mjs +2 -0
- package/dist/chunk-TXBZPCGF.mjs.map +1 -0
- package/dist/chunk-U2CGMEWB.js +2 -0
- package/dist/chunk-U2CGMEWB.js.map +1 -0
- package/dist/chunk-UUWVBENC.js +2 -0
- package/dist/chunk-UUWVBENC.js.map +1 -0
- package/dist/chunk-UYP64PV7.mjs +4 -0
- package/dist/chunk-UYP64PV7.mjs.map +1 -0
- package/dist/chunk-VMJBW3EF.mjs +2 -0
- package/dist/chunk-VMJBW3EF.mjs.map +1 -0
- package/dist/chunk-WW3X3ELF.js +2 -0
- package/dist/chunk-WW3X3ELF.js.map +1 -0
- package/dist/chunk-WWT2ZSNU.mjs +2 -0
- package/dist/chunk-WWT2ZSNU.mjs.map +1 -0
- package/dist/chunk-XMKA6GVK.mjs +16 -0
- package/dist/chunk-XMKA6GVK.mjs.map +1 -0
- package/dist/chunk-Y34DQYS7.js +2 -0
- package/dist/chunk-Y34DQYS7.js.map +1 -0
- package/dist/chunk-ZU73VG3X.js +2 -0
- package/dist/chunk-ZU73VG3X.js.map +1 -0
- package/dist/consent-CmVzqZUk.d.mts +99 -0
- package/dist/consent-CmVzqZUk.d.ts +99 -0
- package/dist/consent-DCc5zjXI.d.mts +24 -0
- package/dist/consent-DLWb5ota.d.ts +24 -0
- package/dist/consent.d.mts +197 -0
- package/dist/consent.d.ts +197 -0
- package/dist/consent.js +2 -0
- package/dist/consent.js.map +1 -0
- package/dist/consent.mjs +2 -0
- package/dist/consent.mjs.map +1 -0
- package/dist/core.d.mts +14 -0
- package/dist/core.d.ts +14 -0
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +2 -0
- package/dist/core.mjs.map +1 -0
- package/dist/cross-border-BrIy1ieh.d.mts +192 -0
- package/dist/cross-border-BrIy1ieh.d.ts +192 -0
- package/dist/cross-border.d.mts +58 -0
- package/dist/cross-border.d.ts +58 -0
- package/dist/cross-border.js +2 -0
- package/dist/cross-border.js.map +1 -0
- package/dist/cross-border.mjs +2 -0
- package/dist/cross-border.mjs.map +1 -0
- package/dist/dpia-B9ZZJG5a.d.mts +15 -0
- package/dist/dpia-fdtTd2DI.d.ts +15 -0
- package/dist/dpia-vWfE_9bO.d.mts +137 -0
- package/dist/dpia-vWfE_9bO.d.ts +137 -0
- package/dist/dpia.d.mts +179 -0
- package/dist/dpia.d.ts +179 -0
- package/dist/dpia.js +2 -0
- package/dist/dpia.js.map +1 -0
- package/dist/dpia.mjs +2 -0
- package/dist/dpia.mjs.map +1 -0
- package/dist/dsr-jq5NUEdz.d.ts +14 -0
- package/dist/dsr-pQzQ3H1O.d.mts +128 -0
- package/dist/dsr-pQzQ3H1O.d.ts +128 -0
- package/dist/dsr-whPkiI0_.d.mts +14 -0
- package/dist/dsr.d.mts +192 -0
- package/dist/dsr.d.ts +192 -0
- package/dist/dsr.js +2 -0
- package/dist/dsr.js.map +1 -0
- package/dist/dsr.mjs +2 -0
- package/dist/dsr.mjs.map +1 -0
- package/dist/hooks.d.mts +17 -0
- package/dist/hooks.d.ts +17 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.mjs +2 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/index.d.mts +31 -448
- package/dist/index.d.ts +31 -448
- package/dist/index.js +1 -190
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -190
- package/dist/index.mjs.map +1 -1
- package/dist/lawful-basis-CWtvDG1x.d.mts +112 -0
- package/dist/lawful-basis-CWtvDG1x.d.ts +112 -0
- package/dist/lawful-basis-D-oXFizg.d.mts +57 -0
- package/dist/lawful-basis-v04AhbK2.d.ts +57 -0
- package/dist/lawful-basis.d.mts +55 -0
- package/dist/lawful-basis.d.ts +55 -0
- package/dist/lawful-basis.js +2 -0
- package/dist/lawful-basis.js.map +1 -0
- package/dist/lawful-basis.mjs +2 -0
- package/dist/lawful-basis.mjs.map +1 -0
- package/dist/policy.d.mts +195 -0
- package/dist/policy.d.ts +195 -0
- package/dist/policy.js +2 -0
- package/dist/policy.js.map +1 -0
- package/dist/policy.mjs +2 -0
- package/dist/policy.mjs.map +1 -0
- package/dist/privacy-9FcJceMr.d.mts +15 -0
- package/dist/privacy-BXz7O2ej.d.ts +15 -0
- package/dist/privacy-Ca6te9Ir.d.mts +138 -0
- package/dist/privacy-Ca6te9Ir.d.ts +138 -0
- package/dist/ropa-BebGfqKQ.d.ts +200 -0
- package/dist/ropa-Rb4dsFSz.d.mts +200 -0
- package/dist/ropa.d.mts +45 -0
- package/dist/ropa.d.ts +45 -0
- package/dist/ropa.js +2 -0
- package/dist/ropa.js.map +1 -0
- package/dist/ropa.mjs +2 -0
- package/dist/ropa.mjs.map +1 -0
- package/dist/unstyled.d.mts +4 -4
- package/dist/unstyled.d.ts +4 -4
- package/dist/unstyled.js +1 -1
- package/dist/unstyled.js.map +1 -1
- package/dist/unstyled.mjs +1 -1
- package/dist/unstyled.mjs.map +1 -1
- package/dist/useBreach-DRKnexsk.d.mts +99 -0
- package/dist/useBreach-DuT0N0K1.d.ts +99 -0
- package/dist/useConsent-D0pAfTlb.d.ts +65 -0
- package/dist/useConsent-DOt2Njst.d.mts +65 -0
- package/dist/useCrossBorderTransfer-D4FQYfFt.d.ts +66 -0
- package/dist/useCrossBorderTransfer-TVnY8_UX.d.mts +66 -0
- package/dist/useDPIA-DFDHBLSa.d.ts +94 -0
- package/dist/useDPIA-FqPofFaV.d.mts +94 -0
- package/dist/useDSR-DAqqOBXb.d.ts +74 -0
- package/dist/useDSR-OXM5Q9rf.d.mts +74 -0
- package/dist/useLawfulBasis-DNQ8YszQ.d.mts +68 -0
- package/dist/useLawfulBasis-RILM_xsx.d.ts +68 -0
- package/dist/usePrivacyPolicy-CfySfBLS.d.ts +89 -0
- package/dist/usePrivacyPolicy-Dit2sFuV.d.mts +89 -0
- package/dist/useROPA-Bcs6cRdi.d.ts +64 -0
- package/dist/useROPA-nmcSiUYv.d.mts +64 -0
- package/package.json +144 -20
package/README.md
CHANGED
|
@@ -1,196 +1,349 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @tantainnovative/ndpr-toolkit
|
|
2
|
+
|
|
3
|
+
**Compliance infrastructure for the Nigeria Data Protection Act (NDPA) 2023**
|
|
2
4
|
|
|
3
5
|
[](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://bundlephobia.com/package/@tantainnovative/ndpr-toolkit)
|
|
9
|
+
|
|
10
|
+
Eight production-ready modules covering consent, data subject rights, DPIA, breach notification, privacy policies, lawful basis tracking, cross-border transfers, and ROPA -- everything a data controller or processor needs under the NDPA.
|
|
11
|
+
|
|
12
|
+
**[Documentation](https://ndprtoolkit.com.ng)** | **[Live Demos](https://ndprtoolkit.com.ng/ndpr-demos)** | **[npm](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)**
|
|
5
13
|
|
|
6
|
-
|
|
14
|
+
---
|
|
7
15
|
|
|
8
|
-
##
|
|
16
|
+
## Install
|
|
9
17
|
|
|
10
18
|
```bash
|
|
11
|
-
npm install @tantainnovative/ndpr-toolkit
|
|
12
|
-
# or
|
|
13
|
-
yarn add @tantainnovative/ndpr-toolkit
|
|
14
|
-
# or
|
|
15
19
|
pnpm add @tantainnovative/ndpr-toolkit
|
|
16
20
|
```
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
---
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
## Choose Your Import Style
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
v2.0 ships modular entry points. Pick the layer you need -- the rest stays out of your bundle.
|
|
23
27
|
|
|
24
|
-
###
|
|
28
|
+
### Lightweight (zero UI dependencies)
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
Types, validators, and utility functions. Works in any JS/TS environment -- Node, Deno, edge functions, or the browser.
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **Event-Driven**: Subscribe to consent changes with event listeners
|
|
32
|
-
- **TypeScript Support**: Fully typed with generic support for custom categories
|
|
33
|
-
- **Granular Consent**: Analytics, marketing, functional, and custom categories
|
|
34
|
-
- **Audit Trail**: Time-stamped consent history tracking
|
|
32
|
+
```typescript
|
|
33
|
+
import { validateConsent, getLawfulBasisDescription } from '@tantainnovative/ndpr-toolkit/core';
|
|
34
|
+
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
### React Hooks
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
import { ConsentManager } from '@tantainnovative/ndpr-toolkit';
|
|
38
|
+
Stateful hooks for every module. Requires `react` only -- no Radix, no Tailwind.
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<ConsentManager>
|
|
45
|
-
{/* Your app content */}
|
|
46
|
-
</ConsentManager>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
40
|
+
```typescript
|
|
41
|
+
import { useConsent, useLawfulBasis } from '@tantainnovative/ndpr-toolkit/hooks';
|
|
42
|
+
```
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
</ConsentManager>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
44
|
+
### Full UI Components
|
|
45
|
+
|
|
46
|
+
Pre-built, styled components. Requires Tailwind CSS plus a handful of Radix primitives.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { ConsentBanner, LawfulBasisTracker } from '@tantainnovative/ndpr-toolkit';
|
|
59
50
|
```
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- Version history tracking
|
|
78
|
-
|
|
79
|
-
### 4. Data Protection Impact Assessment (DPIA) Tool
|
|
80
|
-
- Questionnaire-based tool to help organizations assess data processing risks
|
|
81
|
-
- Risk scoring matrix
|
|
82
|
-
- Mitigation recommendation engine
|
|
83
|
-
- Exportable reports for compliance documentation
|
|
84
|
-
|
|
85
|
-
### 5. Breach Notification Module
|
|
86
|
-
- Templates for mandatory breach notifications
|
|
87
|
-
- Workflow for documenting breach details
|
|
88
|
-
- Timeline tracking to ensure 72-hour notification compliance
|
|
89
|
-
- Notification delivery to authorities via API (if available)
|
|
90
|
-
### 6. Data Subject Request Service
|
|
91
|
-
- Lightweight requestService storing requests in browser localStorage for demos
|
|
92
|
-
- Helper methods to update request status and retrieve history
|
|
52
|
+
Install the UI peer dependencies:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm add @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-label @radix-ui/react-slot lucide-react tailwind-merge clsx class-variance-authority
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Per-Module Imports
|
|
59
|
+
|
|
60
|
+
Need just one module? Import it directly to keep your bundle minimal.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { ConsentBanner, useConsent } from '@tantainnovative/ndpr-toolkit/consent';
|
|
64
|
+
import { BreachReportForm, useBreach } from '@tantainnovative/ndpr-toolkit/breach';
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
93
68
|
|
|
94
69
|
## Quick Start
|
|
95
70
|
|
|
96
|
-
|
|
71
|
+
A consent banner in under 10 lines:
|
|
97
72
|
|
|
98
73
|
```tsx
|
|
99
|
-
import {
|
|
74
|
+
import { useConsent } from '@tantainnovative/ndpr-toolkit/hooks';
|
|
100
75
|
|
|
101
76
|
function App() {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
77
|
+
const { hasConsent, acceptAll, rejectAll, shouldShowBanner } = useConsent({
|
|
78
|
+
options: [
|
|
79
|
+
{ id: 'essential', label: 'Essential', description: 'Required for the site to function', required: true, purpose: 'Site operation' },
|
|
80
|
+
{ id: 'analytics', label: 'Analytics', description: 'Help us improve', required: false, purpose: 'Usage analytics' },
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (shouldShowBanner) {
|
|
85
|
+
return (
|
|
86
|
+
<div>
|
|
87
|
+
<p>We use cookies to improve your experience.</p>
|
|
88
|
+
<button onClick={acceptAll}>Accept All</button>
|
|
89
|
+
<button onClick={rejectAll}>Reject Optional</button>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return <main>{hasConsent('analytics') && <AnalyticsScript />}</main>;
|
|
107
95
|
}
|
|
96
|
+
```
|
|
108
97
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Modules
|
|
101
|
+
|
|
102
|
+
### 1. Consent Management
|
|
103
|
+
|
|
104
|
+
**NDPA Sections 25-26** -- Freely given, specific, informed, and unambiguous consent.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { ConsentBanner, ConsentManager, useConsent, validateConsent } from '@tantainnovative/ndpr-toolkit/consent';
|
|
119
108
|
```
|
|
120
109
|
|
|
121
|
-
|
|
110
|
+
```tsx
|
|
111
|
+
<ConsentManager
|
|
112
|
+
position="bottom"
|
|
113
|
+
animation="slide"
|
|
114
|
+
onConsentChange={(consent) => {
|
|
115
|
+
if (consent.analytics) loadAnalytics();
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
<App />
|
|
119
|
+
</ConsentManager>
|
|
120
|
+
```
|
|
122
121
|
|
|
123
|
-
|
|
122
|
+
**Key exports:** `ConsentBanner`, `ConsentManager`, `ConsentStorage`, `useConsent`, `validateConsent`, `validateConsentOptions`
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
cd ndpr-toolkit
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### 2. Data Subject Rights (DSR)
|
|
129
127
|
|
|
130
|
-
|
|
131
|
-
pnpm install
|
|
128
|
+
**NDPA Part IV, Sections 29-36** -- All 8 rights: information, access, rectification, erasure, restriction, portability, objection, and automated decision-making.
|
|
132
129
|
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
```typescript
|
|
131
|
+
import { DSRRequestForm, DSRDashboard, useDSR, formatDSRRequest } from '@tantainnovative/ndpr-toolkit/dsr';
|
|
135
132
|
```
|
|
136
133
|
|
|
137
|
-
|
|
134
|
+
```tsx
|
|
135
|
+
const { submitRequest, requests } = useDSR({
|
|
136
|
+
requestTypes: [
|
|
137
|
+
{ id: 'access', name: 'Access Request', description: 'Right of access (Section 30)', estimatedCompletionTime: 30, requiresAdditionalInfo: false },
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
```
|
|
138
141
|
|
|
139
|
-
|
|
142
|
+
**Key exports:** `DSRRequestForm`, `DSRDashboard`, `DSRTracker`, `useDSR`, `formatDSRRequest`
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
---
|
|
142
145
|
|
|
143
|
-
|
|
146
|
+
### 3. Data Protection Impact Assessment (DPIA)
|
|
144
147
|
|
|
145
|
-
|
|
146
|
-
2. The built files will be deployed to GitHub Pages
|
|
147
|
-
3. Your site will be available at `https://[your-username].github.io/ndpr-toolkit/`
|
|
148
|
+
**NDPA Section 38-39** -- Mandatory risk assessment for high-risk processing activities.
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
```typescript
|
|
151
|
+
import { DPIAQuestionnaire, DPIAReport, useDPIA, assessDPIARisk } from '@tantainnovative/ndpr-toolkit/dpia';
|
|
152
|
+
```
|
|
150
153
|
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
```tsx
|
|
155
|
+
const { currentSection, answers, goToNextSection, getResult } = useDPIA({
|
|
156
|
+
sections: dpiaSections,
|
|
157
|
+
onComplete: (result) => saveAssessment(result),
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Key exports:** `DPIAQuestionnaire`, `DPIAReport`, `StepIndicator`, `useDPIA`, `assessDPIARisk`
|
|
162
|
+
|
|
163
|
+
---
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
### 4. Breach Notification
|
|
166
|
+
|
|
167
|
+
**NDPA Section 40** -- 72-hour notification to the NDPC, plus data subject notification.
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { BreachReportForm, BreachNotificationManager, useBreach, calculateBreachSeverity } from '@tantainnovative/ndpr-toolkit/breach';
|
|
157
171
|
```
|
|
158
172
|
|
|
159
|
-
|
|
173
|
+
```tsx
|
|
174
|
+
const { createReport, reports, assessRisk } = useBreach({
|
|
175
|
+
categories: breachCategories,
|
|
176
|
+
onReport: (report) => notifyNDPC(report),
|
|
177
|
+
});
|
|
178
|
+
```
|
|
160
179
|
|
|
161
|
-
|
|
162
|
-
- `next.config.ts` - Contains the Next.js configuration for static export
|
|
163
|
-
- `.github/workflows/deploy.yml` - Contains the GitHub Actions workflow for automated deployment
|
|
180
|
+
**Key exports:** `BreachReportForm`, `BreachRiskAssessment`, `BreachNotificationManager`, `RegulatoryReportGenerator`, `useBreach`, `calculateBreachSeverity`
|
|
164
181
|
|
|
165
|
-
|
|
182
|
+
---
|
|
166
183
|
|
|
167
|
-
|
|
168
|
-
- TypeScript
|
|
169
|
-
- Tailwind CSS
|
|
170
|
-
- React
|
|
184
|
+
### 5. Privacy Policy Generator
|
|
171
185
|
|
|
172
|
-
|
|
186
|
+
**NDPA Sections 27-28** -- Multi-step wizard producing NDPA-compliant privacy policies with PDF/DOCX export.
|
|
173
187
|
|
|
174
|
-
|
|
188
|
+
```typescript
|
|
189
|
+
import { PolicyGenerator, PolicyPreview, usePrivacyPolicy, generatePolicyText } from '@tantainnovative/ndpr-toolkit/policy';
|
|
190
|
+
```
|
|
175
191
|
|
|
176
|
-
|
|
192
|
+
```tsx
|
|
193
|
+
<PolicyGenerator />
|
|
194
|
+
```
|
|
177
195
|
|
|
178
|
-
|
|
196
|
+
The wizard covers organization info, data collection practices, data sharing, custom sections, and a preview with export.
|
|
179
197
|
|
|
180
|
-
|
|
198
|
+
**Key exports:** `PolicyGenerator`, `PolicyPreview`, `PolicyExporter`, `usePrivacyPolicy`, `generatePolicyText`
|
|
181
199
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### 6. Lawful Basis Tracker
|
|
203
|
+
|
|
204
|
+
**NDPA Section 25** -- Document and manage the lawful basis for every processing activity. Covers all six bases: consent, contract, legal obligation, vital interests, public interest, and legitimate interests.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { LawfulBasisTracker, useLawfulBasis, validateProcessingActivity, getLawfulBasisDescription } from '@tantainnovative/ndpr-toolkit/lawful-basis';
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
const { activities, addActivity, getSummary } = useLawfulBasis();
|
|
212
|
+
|
|
213
|
+
addActivity({
|
|
214
|
+
name: 'Email marketing',
|
|
215
|
+
description: 'Send promotional emails',
|
|
216
|
+
lawfulBasis: 'consent',
|
|
217
|
+
lawfulBasisJustification: 'Explicit opt-in at signup',
|
|
218
|
+
dataCategories: ['email', 'name'],
|
|
219
|
+
involvesSensitiveData: false,
|
|
220
|
+
dataSubjectCategories: ['customers'],
|
|
221
|
+
purposes: ['marketing'],
|
|
222
|
+
retentionPeriod: '2 years',
|
|
223
|
+
crossBorderTransfer: false,
|
|
224
|
+
status: 'active',
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Key exports:** `LawfulBasisTracker`, `useLawfulBasis`, `validateProcessingActivity`, `getLawfulBasisDescription`, `assessComplianceGaps`, `generateLawfulBasisSummary`
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### 7. Cross-Border Transfer Assessment
|
|
233
|
+
|
|
234
|
+
**NDPA Part VI, Sections 41-45** -- Evaluate adequacy decisions, standard contractual clauses, binding corporate rules, and derogations for international data transfers.
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
import { CrossBorderTransferManager, useCrossBorderTransfer, validateTransfer, assessTransferRisk } from '@tantainnovative/ndpr-toolkit/cross-border';
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
const { transfers, addTransfer, getSummary } = useCrossBorderTransfer({
|
|
242
|
+
onAdd: (transfer) => logTransfer(transfer),
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Key exports:** `CrossBorderTransferManager`, `useCrossBorderTransfer`, `validateTransfer`, `getTransferMechanismDescription`, `assessTransferRisk`, `isNDPCApprovalRequired`
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### 8. Record of Processing Activities (ROPA)
|
|
251
|
+
|
|
252
|
+
**NDPC Regulatory Guidance** -- Maintain comprehensive records of all processing activities for audit readiness.
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { ROPAManager, useROPA, generateROPASummary, exportROPAToCSV } from '@tantainnovative/ndpr-toolkit/ropa';
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
const { ropa, addRecord, getSummary } = useROPA({
|
|
260
|
+
initialData: { id: 'ropa-1', organizationName: 'Acme Ltd', organizationContact: 'dpo@acme.ng', organizationAddress: 'Lagos, Nigeria', records: [], lastUpdated: Date.now(), version: '1.0' },
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Key exports:** `ROPAManager`, `useROPA`, `validateProcessingRecord`, `generateROPASummary`, `exportROPAToCSV`, `identifyComplianceGaps`
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Available Import Paths
|
|
269
|
+
|
|
270
|
+
| Path | What you get | Dependencies |
|
|
271
|
+
|------|-------------|--------------|
|
|
272
|
+
| `/core` | Types + utility functions | `tslib`, `uuid` |
|
|
273
|
+
| `/hooks` | React hooks for all 8 modules | `react` |
|
|
274
|
+
| `/consent` | Consent components + hook + utils | `react`, Radix, Tailwind |
|
|
275
|
+
| `/dsr` | DSR components + hook + utils | `react`, Radix, Tailwind |
|
|
276
|
+
| `/dpia` | DPIA components + hook + utils | `react`, Radix, Tailwind |
|
|
277
|
+
| `/breach` | Breach components + hook + utils | `react`, Radix, Tailwind |
|
|
278
|
+
| `/policy` | Policy components + hook + utils | `react`, Radix, Tailwind, `jspdf` |
|
|
279
|
+
| `/lawful-basis` | Lawful basis component + hook + utils | `react`, Radix, Tailwind |
|
|
280
|
+
| `/cross-border` | Cross-border component + hook + utils | `react`, Radix, Tailwind |
|
|
281
|
+
| `/ropa` | ROPA component + hook + utils | `react`, Radix, Tailwind |
|
|
282
|
+
| `/unstyled` | Unstyled consent primitives | `react` |
|
|
283
|
+
| `.` (default) | Everything | All peer deps |
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## NDPA 2023 Overview
|
|
288
|
+
|
|
289
|
+
The **Nigeria Data Protection Act (NDPA) 2023** replaced the NDPR 2019 and established the **Nigeria Data Protection Commission (NDPC)** as the independent regulatory body.
|
|
290
|
+
|
|
291
|
+
| Aspect | NDPR (2019) | NDPA (2023) |
|
|
292
|
+
|--------|-------------|-------------|
|
|
293
|
+
| Legal status | NITDA regulation | Act of the National Assembly |
|
|
294
|
+
| Regulator | NITDA | NDPC (independent commission) |
|
|
295
|
+
| Scope | Organizations processing data in Nigeria | Broader territorial + extraterritorial application |
|
|
296
|
+
| Enforcement | Limited | Independent investigation and penalty powers |
|
|
297
|
+
| Data subject rights | 6 rights | 8 rights (added information + automated decision-making) |
|
|
298
|
+
| Cross-border transfers | Basic provisions | Comprehensive framework with adequacy decisions |
|
|
299
|
+
| Breach notification | 72 hours to NITDA | 72 hours to NDPC (Section 40) |
|
|
300
|
+
| DPIA | Recommended | Required for high-risk processing (Section 38) |
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## TypeScript
|
|
305
|
+
|
|
306
|
+
The toolkit is written in TypeScript and exports all types:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import type {
|
|
310
|
+
// Consent
|
|
311
|
+
ConsentOption, ConsentSettings, LawfulBasisType,
|
|
312
|
+
// DSR
|
|
313
|
+
DSRRequest, DSRType, DSRStatus, RequestType,
|
|
314
|
+
// DPIA
|
|
315
|
+
DPIAQuestion, DPIASection, DPIAResult, DPIARisk,
|
|
316
|
+
// Breach
|
|
317
|
+
BreachReport, BreachCategory, RiskAssessment,
|
|
318
|
+
// Policy
|
|
319
|
+
PolicySection, PolicyTemplate, OrganizationInfo, PrivacyPolicy,
|
|
320
|
+
// Lawful Basis
|
|
321
|
+
LawfulBasis, ProcessingActivity, LawfulBasisSummary,
|
|
322
|
+
// Cross-Border
|
|
323
|
+
CrossBorderTransfer, TransferMechanism, AdequacyStatus,
|
|
324
|
+
// ROPA
|
|
325
|
+
ProcessingRecord, RecordOfProcessingActivities, ROPASummary,
|
|
326
|
+
} from '@tantainnovative/ndpr-toolkit/core';
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
185
330
|
|
|
186
331
|
## Contributing
|
|
187
332
|
|
|
188
|
-
Contributions are welcome
|
|
333
|
+
Contributions are welcome. Please read the [Contributing Guide](./CONTRIBUTING.md) before submitting a pull request.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT
|
|
340
|
+
|
|
341
|
+
---
|
|
189
342
|
|
|
190
|
-
##
|
|
343
|
+
## Author
|
|
191
344
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
345
|
+
**Abraham Esandayinze Tanta** — Software Engineer & Data Protection Compliance Specialist
|
|
346
|
+
|
|
347
|
+
- GitHub: [@mr-tanta](https://github.com/mr-tanta)
|
|
348
|
+
- LinkedIn: [mr-tanta](https://linkedin.com/in/mr-tanta)
|
|
349
|
+
- Organization: [Tanta Innovative](https://github.com/tantainnovative)
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breach notification types aligned with NDPA 2023 Section 40
|
|
3
|
+
* Data controllers must notify the NDPC within 72 hours of becoming aware of a breach
|
|
4
|
+
* Data subjects must be notified without undue delay when breach is likely to result in high risk
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Represents a data breach category
|
|
8
|
+
*/
|
|
9
|
+
interface BreachCategory {
|
|
10
|
+
/** Unique identifier for the category */
|
|
11
|
+
id: string;
|
|
12
|
+
/** Display name for the category */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Description of this breach category */
|
|
15
|
+
description: string;
|
|
16
|
+
/** Default severity level for this category */
|
|
17
|
+
defaultSeverity: 'low' | 'medium' | 'high' | 'critical';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents a data breach report
|
|
21
|
+
*/
|
|
22
|
+
interface BreachReport {
|
|
23
|
+
/** Unique identifier for the breach report */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Title/summary of the breach */
|
|
26
|
+
title: string;
|
|
27
|
+
/** Detailed description of the breach */
|
|
28
|
+
description: string;
|
|
29
|
+
/** Category of the breach */
|
|
30
|
+
category: string;
|
|
31
|
+
/** Timestamp when the breach was discovered */
|
|
32
|
+
discoveredAt: number;
|
|
33
|
+
/** Timestamp when the breach occurred (if known) */
|
|
34
|
+
occurredAt?: number;
|
|
35
|
+
/** Timestamp when the breach was reported internally */
|
|
36
|
+
reportedAt: number;
|
|
37
|
+
/** Person who reported the breach */
|
|
38
|
+
reporter: {
|
|
39
|
+
name: string;
|
|
40
|
+
email: string;
|
|
41
|
+
department: string;
|
|
42
|
+
phone?: string;
|
|
43
|
+
};
|
|
44
|
+
/** Systems or data affected by the breach */
|
|
45
|
+
affectedSystems: string[];
|
|
46
|
+
/** Types of data involved in the breach */
|
|
47
|
+
dataTypes: string[];
|
|
48
|
+
/** Whether sensitive personal data is involved (NDPA Section 30) */
|
|
49
|
+
involvesSensitiveData?: boolean;
|
|
50
|
+
/** Estimated number of data subjects affected */
|
|
51
|
+
estimatedAffectedSubjects?: number;
|
|
52
|
+
/** Whether the breach is ongoing or contained */
|
|
53
|
+
status: 'ongoing' | 'contained' | 'resolved';
|
|
54
|
+
/** Initial actions taken to address the breach */
|
|
55
|
+
initialActions?: string;
|
|
56
|
+
/** Attachments related to the breach */
|
|
57
|
+
attachments?: Array<{
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
type: string;
|
|
61
|
+
url: string;
|
|
62
|
+
addedAt: number;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Represents a risk assessment for a data breach
|
|
67
|
+
*/
|
|
68
|
+
interface RiskAssessment {
|
|
69
|
+
/** Unique identifier for the risk assessment */
|
|
70
|
+
id: string;
|
|
71
|
+
/** ID of the breach this assessment is for */
|
|
72
|
+
breachId: string;
|
|
73
|
+
/** Timestamp when the assessment was conducted */
|
|
74
|
+
assessedAt: number;
|
|
75
|
+
/** Person who conducted the assessment */
|
|
76
|
+
assessor: {
|
|
77
|
+
name: string;
|
|
78
|
+
role: string;
|
|
79
|
+
email: string;
|
|
80
|
+
};
|
|
81
|
+
/** Confidentiality impact (1-5) */
|
|
82
|
+
confidentialityImpact: number;
|
|
83
|
+
/** Integrity impact (1-5) */
|
|
84
|
+
integrityImpact: number;
|
|
85
|
+
/** Availability impact (1-5) */
|
|
86
|
+
availabilityImpact: number;
|
|
87
|
+
/** Likelihood of harm to data subjects (1-5) */
|
|
88
|
+
harmLikelihood: number;
|
|
89
|
+
/** Severity of potential harm to data subjects (1-5) */
|
|
90
|
+
harmSeverity: number;
|
|
91
|
+
/** Overall risk score */
|
|
92
|
+
overallRiskScore: number;
|
|
93
|
+
/** Risk level based on the overall score */
|
|
94
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
95
|
+
/** Whether the breach is likely to result in a risk to rights and freedoms */
|
|
96
|
+
risksToRightsAndFreedoms: boolean;
|
|
97
|
+
/** Whether the breach is likely to result in a high risk to rights and freedoms */
|
|
98
|
+
highRisksToRightsAndFreedoms: boolean;
|
|
99
|
+
/** Justification for the risk assessment */
|
|
100
|
+
justification: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Represents notification requirements for a data breach per NDPA Section 40
|
|
104
|
+
*/
|
|
105
|
+
interface NotificationRequirement {
|
|
106
|
+
/**
|
|
107
|
+
* Whether NDPC notification is required
|
|
108
|
+
* Per NDPA Section 40, notification to NDPC is required for all breaches
|
|
109
|
+
* that pose a risk to data subjects' rights and freedoms
|
|
110
|
+
*/
|
|
111
|
+
ndpcNotificationRequired: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Deadline for NDPC notification (72 hours from discovery)
|
|
114
|
+
* NDPA Section 40(1)
|
|
115
|
+
*/
|
|
116
|
+
ndpcNotificationDeadline: number;
|
|
117
|
+
/**
|
|
118
|
+
* Whether data subject notification is required
|
|
119
|
+
* Per NDPA Section 40(4), required when breach is likely to result in
|
|
120
|
+
* high risk to rights and freedoms of data subjects
|
|
121
|
+
*/
|
|
122
|
+
dataSubjectNotificationRequired: boolean;
|
|
123
|
+
/** Justification for the notification decision */
|
|
124
|
+
justification: string;
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated Use ndpcNotificationRequired instead. Kept for backward compatibility.
|
|
127
|
+
*/
|
|
128
|
+
nitdaNotificationRequired?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use ndpcNotificationDeadline instead. Kept for backward compatibility.
|
|
131
|
+
*/
|
|
132
|
+
nitdaNotificationDeadline?: number;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Represents a notification sent to the NDPC (Nigeria Data Protection Commission)
|
|
136
|
+
*/
|
|
137
|
+
interface RegulatoryNotification {
|
|
138
|
+
/** Unique identifier for the notification */
|
|
139
|
+
id: string;
|
|
140
|
+
/** ID of the breach this notification is for */
|
|
141
|
+
breachId: string;
|
|
142
|
+
/** Timestamp when the notification was sent */
|
|
143
|
+
sentAt: number;
|
|
144
|
+
/** Method used to send the notification */
|
|
145
|
+
method: 'email' | 'portal' | 'letter' | 'other';
|
|
146
|
+
/** Reference number assigned by the NDPC (if available) */
|
|
147
|
+
referenceNumber?: string;
|
|
148
|
+
/** Contact person at the NDPC */
|
|
149
|
+
ndpcContact?: {
|
|
150
|
+
name: string;
|
|
151
|
+
email: string;
|
|
152
|
+
phone?: string;
|
|
153
|
+
};
|
|
154
|
+
/** Content of the notification */
|
|
155
|
+
content: string;
|
|
156
|
+
/** Attachments included with the notification */
|
|
157
|
+
attachments?: Array<{
|
|
158
|
+
id: string;
|
|
159
|
+
name: string;
|
|
160
|
+
type: string;
|
|
161
|
+
url: string;
|
|
162
|
+
}>;
|
|
163
|
+
/** Follow-up communications with the NDPC */
|
|
164
|
+
followUps?: Array<{
|
|
165
|
+
timestamp: number;
|
|
166
|
+
direction: 'sent' | 'received';
|
|
167
|
+
content: string;
|
|
168
|
+
attachments?: Array<{
|
|
169
|
+
id: string;
|
|
170
|
+
name: string;
|
|
171
|
+
type: string;
|
|
172
|
+
url: string;
|
|
173
|
+
}>;
|
|
174
|
+
}>;
|
|
175
|
+
/**
|
|
176
|
+
* @deprecated Use ndpcContact instead. Kept for backward compatibility.
|
|
177
|
+
*/
|
|
178
|
+
nitdaContact?: {
|
|
179
|
+
name: string;
|
|
180
|
+
email: string;
|
|
181
|
+
phone?: string;
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export type { BreachReport as B, NotificationRequirement as N, RiskAssessment as R, BreachCategory as a, RegulatoryNotification as b };
|