@dtect/security-sdk-react 0.0.1
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 +20 -0
- package/CHANGELOG.md +5 -0
- package/README.md +225 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/eslint.config.js +4 -0
- package/package.json +35 -0
- package/src/context/index.tsx +1 -0
- package/src/context/securityCheckContext.tsx +76 -0
- package/src/index.ts +19 -0
- package/src/provider/index.tsx +51 -0
- package/src/types/context.ts +19 -0
- package/src/types/error.ts +51 -0
- package/src/types/index.ts +4 -0
- package/src/types/input.ts +19 -0
- package/src/types/response.ts +20 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +18 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
[2K[1G[1myarn run v1.22.22[22m
|
|
3
|
+
[2K[1G[2m$ tsup src/index.ts --format esm,cjs --dts[22m
|
|
4
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
5
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
6
|
+
[34mCLI[39m tsup v8.3.5
|
|
7
|
+
[34mCLI[39m Using tsup config: /Users/dajungha/Projects/security-sdk-react/packages/sdk-react/tsup.config.ts
|
|
8
|
+
[34mCLI[39m Target: es2022
|
|
9
|
+
[34mCLI[39m Cleaning output folder
|
|
10
|
+
[34mESM[39m Build start
|
|
11
|
+
[34mCJS[39m Build start
|
|
12
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m1.97 KB[39m
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 11ms
|
|
14
|
+
[32mCJS[39m [1mdist/index.js [22m[32m2.65 KB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 11ms
|
|
16
|
+
DTS Build start
|
|
17
|
+
DTS ⚡️ Build success in 779ms
|
|
18
|
+
DTS dist/index.d.mts 1.55 KB
|
|
19
|
+
DTS dist/index.d.ts 1.55 KB
|
|
20
|
+
[2K[1G✨ Done in 1.35s.
|
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Security SDK React
|
|
2
|
+
|
|
3
|
+
Security API SDK for React by dtect.
|
|
4
|
+
|
|
5
|
+
<!-- TABLE OF CONTENTS -->
|
|
6
|
+
<details>
|
|
7
|
+
<summary>Table of Contents</summary>
|
|
8
|
+
<ol>
|
|
9
|
+
<li>
|
|
10
|
+
<a href="#about-the-project">About The Project</a>
|
|
11
|
+
</li>
|
|
12
|
+
<li>
|
|
13
|
+
<a href="#getting-started">Getting Started</a>
|
|
14
|
+
<ul>
|
|
15
|
+
<li><a href="#prerequisites">Prerequisites</a></li>
|
|
16
|
+
<li><a href="#installation">Installation</a></li>
|
|
17
|
+
</ul>
|
|
18
|
+
</li>
|
|
19
|
+
<li>
|
|
20
|
+
<a href="#implementation">Implementation</a>
|
|
21
|
+
</li>
|
|
22
|
+
<li><a href="#license">License</a></li>
|
|
23
|
+
<li><a href="#contact">Contact</a></li>
|
|
24
|
+
</ol>
|
|
25
|
+
</details>
|
|
26
|
+
|
|
27
|
+
<!-- ABOUT THE PROJECT -->
|
|
28
|
+
|
|
29
|
+
## About The Project
|
|
30
|
+
|
|
31
|
+
Security API SDK for React.
|
|
32
|
+
|
|
33
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
34
|
+
|
|
35
|
+
<!-- GETTING STARTED -->
|
|
36
|
+
|
|
37
|
+
## Getting Started
|
|
38
|
+
|
|
39
|
+
The dtect Security API helps you gather valuable insights about your visitors, enhancing the quality of your survey data.
|
|
40
|
+
This library is responsible for collecting data about the visitor's browser and behavior, send everything to our API and return a Security Result or a Security Token.
|
|
41
|
+
|
|
42
|
+
### Prerequisites
|
|
43
|
+
|
|
44
|
+
Get required Public Keys at [https://dtect.security.dashboard.com](https://dtect.security.dashboard.com)
|
|
45
|
+
|
|
46
|
+
### Installation
|
|
47
|
+
|
|
48
|
+
Install package
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install @dtect/security-sdk-react
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
or
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
yarn add @dtect/security-sdk-react
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
61
|
+
|
|
62
|
+
<!-- USAGE EXAMPLES -->
|
|
63
|
+
|
|
64
|
+
## Implementation
|
|
65
|
+
|
|
66
|
+
### 1. Wrap your application (or component) with `<SecurityAPIProvider>`.
|
|
67
|
+
|
|
68
|
+
- Set `clientId` from your [dtect dashboard](https://dtect.security.dashboard.com/keys)
|
|
69
|
+
- Set `apiKey` from your [dtect dashboard](https://dtect.security.dashboard.com/keys)
|
|
70
|
+
|
|
71
|
+
```jsx
|
|
72
|
+
// index.ts or app.tsx
|
|
73
|
+
import React from "react";
|
|
74
|
+
import { SecurityAPIProvider } from "@dtect/security-sdk-react";
|
|
75
|
+
import App from "./App";
|
|
76
|
+
import Form from "./src/form";
|
|
77
|
+
|
|
78
|
+
function MyPage() {
|
|
79
|
+
return (
|
|
80
|
+
<SecurityAPIProvider
|
|
81
|
+
clientId={"your-public-client-id-from-dashboard"} // required
|
|
82
|
+
apiKey={"your-public-api-key-from-dashboard"} // required
|
|
83
|
+
>
|
|
84
|
+
<Form />
|
|
85
|
+
</SecurityAPIProvider>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Prop | Type | Description |
|
|
91
|
+
| :--------- | :------- | :----------------------------- |
|
|
92
|
+
| `clientId` | `string` | **Required**. public client id |
|
|
93
|
+
| `apiKey` | `string` | **Required**. public api key |
|
|
94
|
+
|
|
95
|
+
### 2. Use `useSecurityApi` hook inside your component to check for visitor data
|
|
96
|
+
|
|
97
|
+
`useSecurityApi` has `getSecurityToken` and `getSecurityResult` functions to validate visitor.
|
|
98
|
+
We recommend you to get `securityToken` from `getSecurityToken` then consult `securityResult`.
|
|
99
|
+
|
|
100
|
+
```jsx
|
|
101
|
+
// src/form.ts
|
|
102
|
+
import React from "react";
|
|
103
|
+
import { useSecurityApi } from "@dtect/security-sdk-react";
|
|
104
|
+
import App from "./App";
|
|
105
|
+
|
|
106
|
+
function Form() {
|
|
107
|
+
const { getSecurityToken } = useSecurityApi();
|
|
108
|
+
|
|
109
|
+
const handleSubmit = async () => {
|
|
110
|
+
const response = await getSecurityToken({
|
|
111
|
+
projectId: "your-project-id-for-deduplication", // required
|
|
112
|
+
visitorId: "your-visitor-id",
|
|
113
|
+
securitySettings: {
|
|
114
|
+
countriesAllowed: ["usa", "can"],
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
if (response?.securityToken) {
|
|
119
|
+
// send securityToken to your backend server then consult dtect's securityResult API to get result with security
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<form>
|
|
125
|
+
{/* ...some inputs */}
|
|
126
|
+
<button type="submit" onClick={handleSubmit}>
|
|
127
|
+
Submit
|
|
128
|
+
</button>
|
|
129
|
+
</form>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default Form;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
| Prop | Type | Description |
|
|
137
|
+
| :----------------- | :--------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
|
|
138
|
+
| `projectId` | `string` | **Required**. A unique identifier for your project, study or survey. It allows our system to group visitor data and identify duplicates |
|
|
139
|
+
| `visitorId` | `string` | Id to identify the visitor that is being evaluated |
|
|
140
|
+
| `metaData` | `object` | Any additional information you want to add to each request |
|
|
141
|
+
| `securitySettings` | `object` | Configures security settings. Includes `countriesAllowed` |
|
|
142
|
+
| `countriesAllowed` | `string[]` | List of countries allowed for your project, survey, or study. |
|
|
143
|
+
|
|
144
|
+
## Errors
|
|
145
|
+
|
|
146
|
+
Access the list of error enums from `SecurityAPIError`
|
|
147
|
+
|
|
148
|
+
### SecurityAPIProvider
|
|
149
|
+
|
|
150
|
+
You will see these errors on console
|
|
151
|
+
|
|
152
|
+
| Enum | Message | Description |
|
|
153
|
+
| :------------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------- |
|
|
154
|
+
| `MISSING_CREDENTIALS` | Missing Public Client ID or Public API Key | Please provide valid Public Client ID and Public API Key when initializing our package. |
|
|
155
|
+
| `INVALID_CREDENTIALS` | Invalid Public Client ID or Public API Key | Ensure you are using valid Public Client ID and Public API Key. |
|
|
156
|
+
| `SDK_INIT_ERROR` | Internal Server Error during SDK Initialization | An unexpected error occurred on our servers during SDK initialization. |
|
|
157
|
+
| `DUPLICATE_INITIALIZATION` | Multiple SDK Initializations Detected | You should initialize our package only once. |
|
|
158
|
+
|
|
159
|
+
### getSecurityToken()/getSecurityResult()
|
|
160
|
+
|
|
161
|
+
| Error | Message | Description |
|
|
162
|
+
| :------------------------------ | :--------------------------------------- | :------------------------------------------------------------------------------------------------- |
|
|
163
|
+
| `NOT_INITIALIZED` | SDK Not Initialized | The SDK must be initialized before calling this function. |
|
|
164
|
+
| `INTERNAL_SERVER_ERROR` | Internal Server Error during API Request | An unexpected error occurred on our servers during the API request. Check server logs for details. |
|
|
165
|
+
| `FAILED_TO_GET_SECURITY_TOKEN` | Failed to Generate Security Token | An error occurred while generating the Security Token. |
|
|
166
|
+
| `FAILED_TO_GET_SECURITY_RESULT` | Failed to Retrieve Security Result | An error occurred while retrieving the Security Result. |
|
|
167
|
+
|
|
168
|
+
```jsx
|
|
169
|
+
// src/form.ts
|
|
170
|
+
import React from "react";
|
|
171
|
+
import { useSecurityApi, SecurityAPIError } from "@dtect/security-sdk-react";
|
|
172
|
+
import App from "./App";
|
|
173
|
+
|
|
174
|
+
function Form() {
|
|
175
|
+
const { getSecurityToken } = useSecurityApi();
|
|
176
|
+
|
|
177
|
+
const handleSubmit = async () => {
|
|
178
|
+
try {
|
|
179
|
+
const response = await getSecurityToken({
|
|
180
|
+
projectId: "your-project-id-for-deduplication", // required
|
|
181
|
+
visitorId: "your-visitor-id",
|
|
182
|
+
securitySettings: {
|
|
183
|
+
countriesAllowed: ["usa", "can"],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (response?.securityToken) {
|
|
188
|
+
// send securityToken to your backend server then consult dtect's securityResult API to get result with security
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
switch (error.message) {
|
|
192
|
+
case SecurityAPIError.FAILED_TO_GET_SECURITY_TOKEN:
|
|
193
|
+
// log internally
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<form>
|
|
200
|
+
{/* ...some inputs */}
|
|
201
|
+
<button type="submit" onClick={handleSubmit}>
|
|
202
|
+
Submit
|
|
203
|
+
</button>
|
|
204
|
+
</form>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export default Form;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
_To see full documentation, please refer to the [Documentation](https://dtect.apidog.com)_
|
|
212
|
+
|
|
213
|
+
<!-- LICENSE -->
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
218
|
+
|
|
219
|
+
<!-- CONTACT -->
|
|
220
|
+
|
|
221
|
+
## Contact
|
|
222
|
+
|
|
223
|
+
dtect - [Contact us](https://dtect.io/contact) - support@dtect.io
|
|
224
|
+
|
|
225
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { PropsWithChildren } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ISecurityCheckInput {
|
|
5
|
+
projectId: string;
|
|
6
|
+
visitorId?: string;
|
|
7
|
+
securitySettings?: {
|
|
8
|
+
countriesAllowed?: string[];
|
|
9
|
+
};
|
|
10
|
+
metaData?: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ISecurityResultResponse {
|
|
14
|
+
results: {
|
|
15
|
+
dtectScore: string;
|
|
16
|
+
isDuplicateDevice: boolean;
|
|
17
|
+
isDuplicateIp: boolean;
|
|
18
|
+
isDuplicateId: boolean;
|
|
19
|
+
isLocationBlocked: boolean;
|
|
20
|
+
isLocationInvalid: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface ISecurityTokenResponse {
|
|
24
|
+
token: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface SecurityAPIProviderProps extends PropsWithChildren {
|
|
28
|
+
clientId: string;
|
|
29
|
+
apiKey: string;
|
|
30
|
+
endpoint?: string;
|
|
31
|
+
}
|
|
32
|
+
declare const SecurityAPIProvider: ({ clientId, apiKey, children, endpoint, }: SecurityAPIProviderProps) => react_jsx_runtime.JSX.Element;
|
|
33
|
+
|
|
34
|
+
declare const useSecurityApi: () => {
|
|
35
|
+
getSecurityResult: (props: ISecurityCheckInput) => Promise<ISecurityResultResponse | Error>;
|
|
36
|
+
getSecurityToken: (props: ISecurityCheckInput) => Promise<ISecurityTokenResponse | Error>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
declare const SecurityAPIError: {
|
|
40
|
+
FAILED_TO_GET_SECURITY_TOKEN: string;
|
|
41
|
+
FAILED_TO_GET_SECURITY_RESULT: string;
|
|
42
|
+
INVALID_CREDENTIALS: "Invalid Public Client ID or Public API Key";
|
|
43
|
+
SDK_INIT_ERROR: string;
|
|
44
|
+
DUPLICATE_INITIALIZATION: string;
|
|
45
|
+
NOT_INITIALIZED: string;
|
|
46
|
+
INTERNAL_SERVER_ERROR: "Internal Server Error during API Request";
|
|
47
|
+
MISSING_CREDENTIALS: "Missing Public Client ID or Public API Key";
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { SecurityAPIError, SecurityAPIProvider, useSecurityApi };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { PropsWithChildren } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ISecurityCheckInput {
|
|
5
|
+
projectId: string;
|
|
6
|
+
visitorId?: string;
|
|
7
|
+
securitySettings?: {
|
|
8
|
+
countriesAllowed?: string[];
|
|
9
|
+
};
|
|
10
|
+
metaData?: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ISecurityResultResponse {
|
|
14
|
+
results: {
|
|
15
|
+
dtectScore: string;
|
|
16
|
+
isDuplicateDevice: boolean;
|
|
17
|
+
isDuplicateIp: boolean;
|
|
18
|
+
isDuplicateId: boolean;
|
|
19
|
+
isLocationBlocked: boolean;
|
|
20
|
+
isLocationInvalid: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface ISecurityTokenResponse {
|
|
24
|
+
token: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface SecurityAPIProviderProps extends PropsWithChildren {
|
|
28
|
+
clientId: string;
|
|
29
|
+
apiKey: string;
|
|
30
|
+
endpoint?: string;
|
|
31
|
+
}
|
|
32
|
+
declare const SecurityAPIProvider: ({ clientId, apiKey, children, endpoint, }: SecurityAPIProviderProps) => react_jsx_runtime.JSX.Element;
|
|
33
|
+
|
|
34
|
+
declare const useSecurityApi: () => {
|
|
35
|
+
getSecurityResult: (props: ISecurityCheckInput) => Promise<ISecurityResultResponse | Error>;
|
|
36
|
+
getSecurityToken: (props: ISecurityCheckInput) => Promise<ISecurityTokenResponse | Error>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
declare const SecurityAPIError: {
|
|
40
|
+
FAILED_TO_GET_SECURITY_TOKEN: string;
|
|
41
|
+
FAILED_TO_GET_SECURITY_RESULT: string;
|
|
42
|
+
INVALID_CREDENTIALS: "Invalid Public Client ID or Public API Key";
|
|
43
|
+
SDK_INIT_ERROR: string;
|
|
44
|
+
DUPLICATE_INITIALIZATION: string;
|
|
45
|
+
NOT_INITIALIZED: string;
|
|
46
|
+
INTERNAL_SERVER_ERROR: "Internal Server Error during API Request";
|
|
47
|
+
MISSING_CREDENTIALS: "Missing Public Client ID or Public API Key";
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { SecurityAPIError, SecurityAPIProvider, useSecurityApi };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var k=Object.create;var u=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var v=(r,e)=>{for(var t in e)u(r,t,{get:e[t],enumerable:!0})},y=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of N(e))!O.call(r,o)&&o!==t&&u(r,o,{get:()=>e[o],enumerable:!(n=D(e,o))||n.enumerable});return r};var a=(r,e,t)=>(t=r!=null?k(w(r)):{},y(e||!r||!r.__esModule?u(t,"default",{value:r,enumerable:!0}):t,r)),L=r=>y(u({},"__esModule",{value:!0}),r);var F={};v(F,{SecurityAPIError:()=>M,SecurityAPIProvider:()=>x,useSecurityApi:()=>U});module.exports=L(F);var E=require("react");var G={UNAUTHORIZED:"Unauthorized"},p={INTERNAL_SERVER_ERROR:"Internal Server Error during API Request",MISSING_CREDENTIALS:"Missing Public Client ID or Public API Key"},C={SDK_INIT_ERROR:"Internal Server Error during SDK Initialization",DUPLICATE_INITIALIZATION:"Multiple SDK Initializations Detected",NOT_INITIALIZED:"SDK Not Initialized"},R={INVALID_CREDENTIALS:"Invalid Public Client ID or Public API Key"},T={FAILED_TO_GET_SECURITY_RESULT:"Failed to Retrieve Security Result"},m={FAILED_TO_GET_SECURITY_TOKEN:" Failed to Generate Security Token"},c={...G,...p,...C,...R,...T,...m},f={...p,...C,...R,...T,...m};var S=a(require("@dtect/security-sdk-js")),A=require("react/jsx-runtime"),l=(0,E.createContext)({}),P=({children:r})=>{let e=async({projectId:n,visitorId:o,securitySettings:s,metaData:I})=>{try{return await S.default.getSecurityResult({projectId:n,visitorId:o,securitySettings:s,metaData:I})}catch(i){throw i instanceof Error?new Error(i.message):new Error(c.FAILED_TO_GET_SECURITY_RESULT)}},t=async({projectId:n,visitorId:o,securitySettings:s,metaData:I})=>{try{return await S.default.getSecurityToken({projectId:n,visitorId:o,securitySettings:s,metaData:I})}catch(i){throw i instanceof Error?new Error(i.message):new Error(c.FAILED_TO_GET_SECURITY_TOKEN)}};return(0,A.jsx)(l.Provider,{value:{getSecurityResult:e,getSecurityToken:t},children:r})},h=()=>(0,E.useContext)(l);var _=require("react"),d=a(require("@dtect/security-sdk-js"));var g=require("react/jsx-runtime"),K=({clientId:r,apiKey:e,children:t,endpoint:n})=>{let o=async()=>{try{await d.default.init({apiKey:e,clientId:r,endpoint:n})}catch(s){throw s instanceof Error?new Error(s.message):new Error(c.SDK_INIT_ERROR)}};if((0,_.useEffect)(()=>{r&&e&&o()},[]),!r||!e)throw new Error(c.MISSING_CREDENTIALS);return(0,g.jsx)(P,{children:t})},x=K;var U=()=>{let{getSecurityResult:r,getSecurityToken:e}=h();return{getSecurityResult:r,getSecurityToken:e}},M=f;0&&(module.exports={SecurityAPIError,SecurityAPIProvider,useSecurityApi});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{createContext as l,useContext as P}from"react";var f={UNAUTHORIZED:"Unauthorized"},E={INTERNAL_SERVER_ERROR:"Internal Server Error during API Request",MISSING_CREDENTIALS:"Missing Public Client ID or Public API Key"},I={SDK_INIT_ERROR:"Internal Server Error during SDK Initialization",DUPLICATE_INITIALIZATION:"Multiple SDK Initializations Detected",NOT_INITIALIZED:"SDK Not Initialized"},S={INVALID_CREDENTIALS:"Invalid Public Client ID or Public API Key"},y={FAILED_TO_GET_SECURITY_RESULT:"Failed to Retrieve Security Result"},a={FAILED_TO_GET_SECURITY_TOKEN:" Failed to Generate Security Token"},n={...f,...E,...I,...S,...y,...a},p={...E,...I,...S,...y,...a};import C from"@dtect/security-sdk-js";import{jsx as h}from"react/jsx-runtime";var R=l({}),T=({children:r})=>{let e=async({projectId:i,visitorId:s,securitySettings:o,metaData:u})=>{try{return await C.getSecurityResult({projectId:i,visitorId:s,securitySettings:o,metaData:u})}catch(t){throw t instanceof Error?new Error(t.message):new Error(n.FAILED_TO_GET_SECURITY_RESULT)}},c=async({projectId:i,visitorId:s,securitySettings:o,metaData:u})=>{try{return await C.getSecurityToken({projectId:i,visitorId:s,securitySettings:o,metaData:u})}catch(t){throw t instanceof Error?new Error(t.message):new Error(n.FAILED_TO_GET_SECURITY_TOKEN)}};return h(R.Provider,{value:{getSecurityResult:e,getSecurityToken:c},children:r})},m=()=>P(R);import{useEffect as A}from"react";import _ from"@dtect/security-sdk-js";import{jsx as g}from"react/jsx-runtime";var d=({clientId:r,apiKey:e,children:c,endpoint:i})=>{let s=async()=>{try{await _.init({apiKey:e,clientId:r,endpoint:i})}catch(o){throw o instanceof Error?new Error(o.message):new Error(n.SDK_INIT_ERROR)}};if(A(()=>{r&&e&&s()},[]),!r||!e)throw new Error(n.MISSING_CREDENTIALS);return g(T,{children:c})},x=d;var er=()=>{let{getSecurityResult:r,getSecurityToken:e}=m();return{getSecurityResult:r,getSecurityToken:e}},tr=p;export{tr as SecurityAPIError,x as SecurityAPIProvider,er as useSecurityApi};
|
package/eslint.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dtect/security-sdk-react",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"module": "dist/index.mjs",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
9
|
+
"ts:check": "tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@dtect/security-sdk-js": "*",
|
|
13
|
+
"@tanstack/react-query": "^5.64.1",
|
|
14
|
+
"react": "^19.0.0",
|
|
15
|
+
"react-dom": "^19.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@eslint/js": "^9.17.0",
|
|
19
|
+
"@types/react": "^19.0.2",
|
|
20
|
+
"eslint": "^9.17.0",
|
|
21
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
22
|
+
"tsup": "^8.3.5",
|
|
23
|
+
"typescript": "^5.7.2",
|
|
24
|
+
"typescript-eslint": "^8.19.0"
|
|
25
|
+
},
|
|
26
|
+
"author": "dtect",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"description": "",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./src/index.ts"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./securityCheckContext";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { createContext, useContext } from "react";
|
|
2
|
+
import {
|
|
3
|
+
ErrorMessageEnum,
|
|
4
|
+
ISecurityCheckContext,
|
|
5
|
+
ISecurityCheckInput,
|
|
6
|
+
ISecurityResultResponse,
|
|
7
|
+
ISecurityTokenResponse,
|
|
8
|
+
} from "../types";
|
|
9
|
+
import dtect from "@dtect/security-sdk-js";
|
|
10
|
+
|
|
11
|
+
const SecurityCheckContext = createContext<ISecurityCheckContext>(
|
|
12
|
+
{} as ISecurityCheckContext
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export const SecurityCheckContextProvider = ({
|
|
16
|
+
children,
|
|
17
|
+
}: React.PropsWithChildren) => {
|
|
18
|
+
const getSecurityResult = async ({
|
|
19
|
+
projectId,
|
|
20
|
+
visitorId,
|
|
21
|
+
securitySettings,
|
|
22
|
+
metaData,
|
|
23
|
+
}: ISecurityCheckInput): Promise<ISecurityResultResponse | Error> => {
|
|
24
|
+
try {
|
|
25
|
+
const response = await dtect.getSecurityResult({
|
|
26
|
+
projectId,
|
|
27
|
+
visitorId,
|
|
28
|
+
securitySettings,
|
|
29
|
+
metaData,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return response;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (error instanceof Error) {
|
|
35
|
+
throw new Error(error.message);
|
|
36
|
+
}
|
|
37
|
+
throw new Error(ErrorMessageEnum.FAILED_TO_GET_SECURITY_RESULT);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getSecurityToken = async ({
|
|
42
|
+
projectId,
|
|
43
|
+
visitorId,
|
|
44
|
+
securitySettings,
|
|
45
|
+
metaData,
|
|
46
|
+
}: ISecurityCheckInput): Promise<ISecurityTokenResponse | Error> => {
|
|
47
|
+
try {
|
|
48
|
+
const response = await dtect.getSecurityToken({
|
|
49
|
+
projectId,
|
|
50
|
+
visitorId,
|
|
51
|
+
securitySettings,
|
|
52
|
+
metaData,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return response;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (error instanceof Error) {
|
|
58
|
+
throw new Error(error.message);
|
|
59
|
+
}
|
|
60
|
+
throw new Error(ErrorMessageEnum.FAILED_TO_GET_SECURITY_TOKEN);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<SecurityCheckContext.Provider
|
|
66
|
+
value={{
|
|
67
|
+
getSecurityResult,
|
|
68
|
+
getSecurityToken,
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
{children}
|
|
72
|
+
</SecurityCheckContext.Provider>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const useSecurityCheckContext = () => useContext(SecurityCheckContext);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { useSecurityCheckContext } from "./context";
|
|
4
|
+
import { SecurityAPIErrorsEnum } from "./types"
|
|
5
|
+
|
|
6
|
+
export const useSecurityApi = () => {
|
|
7
|
+
const { getSecurityResult, getSecurityToken } = useSecurityCheckContext();
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
getSecurityResult,
|
|
12
|
+
getSecurityToken
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { default as SecurityAPIProvider } from "./provider";
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export const SecurityAPIError = SecurityAPIErrorsEnum
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, PropsWithChildren } from "react";
|
|
4
|
+
import dtect from "@dtect/security-sdk-js";
|
|
5
|
+
import { SecurityCheckContextProvider } from "../context";
|
|
6
|
+
import { ErrorMessageEnum } from "../types";
|
|
7
|
+
|
|
8
|
+
interface SecurityAPIProviderProps extends PropsWithChildren {
|
|
9
|
+
clientId: string;
|
|
10
|
+
apiKey: string;
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SecurityAPIProvider = ({
|
|
15
|
+
clientId,
|
|
16
|
+
apiKey,
|
|
17
|
+
children,
|
|
18
|
+
endpoint,
|
|
19
|
+
}: SecurityAPIProviderProps) => {
|
|
20
|
+
|
|
21
|
+
const getKeysHandler = async () => {
|
|
22
|
+
try {
|
|
23
|
+
await dtect.init({ apiKey, clientId, endpoint });
|
|
24
|
+
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
console.error(error.message);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.error(ErrorMessageEnum.SDK_INIT_ERROR)
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (clientId && apiKey) {
|
|
37
|
+
getKeysHandler();
|
|
38
|
+
}
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
if (!clientId || !apiKey) {
|
|
42
|
+
throw new Error(ErrorMessageEnum.MISSING_CREDENTIALS);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<SecurityCheckContextProvider>{children}</SecurityCheckContextProvider>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default SecurityAPIProvider;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ISecurityCheckInput, ISecurityResultResponse, ISecurityTokenResponse } from ".";
|
|
2
|
+
|
|
3
|
+
export interface ISecurityCheckContext {
|
|
4
|
+
getSecurityResult: (
|
|
5
|
+
props: ISecurityCheckInput
|
|
6
|
+
) => Promise<ISecurityResultResponse | Error>;
|
|
7
|
+
getSecurityToken: (
|
|
8
|
+
props: ISecurityCheckInput
|
|
9
|
+
) => Promise<ISecurityTokenResponse | Error>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export interface ISecurityAppContext {
|
|
14
|
+
isReady: boolean;
|
|
15
|
+
isHcaptchaReady: boolean;
|
|
16
|
+
isKeysReady: boolean;
|
|
17
|
+
setIsHcaptchaReady: (isHcaptchaReady: boolean) => void;
|
|
18
|
+
setIsKeysReady:(isKeysReady: boolean) => void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
const InternalError = {
|
|
3
|
+
UNAUTHORIZED: "Unauthorized",
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const GeneralError = {
|
|
7
|
+
INTERNAL_SERVER_ERROR: "Internal Server Error during API Request",
|
|
8
|
+
MISSING_CREDENTIALS: "Missing Public Client ID or Public API Key",
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
const InitError = {
|
|
12
|
+
SDK_INIT_ERROR: "Internal Server Error during SDK Initialization",
|
|
13
|
+
DUPLICATE_INITIALIZATION:
|
|
14
|
+
"Multiple SDK Initializations Detected",
|
|
15
|
+
NOT_INITIALIZED: "SDK Not Initialized"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const GetKeysError = {
|
|
19
|
+
INVALID_CREDENTIALS: "Invalid Public Client ID or Public API Key",
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
const GetSecurityResultError = {
|
|
23
|
+
FAILED_TO_GET_SECURITY_RESULT: "Failed to Retrieve Security Result",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const GetSecurityTokenError = {
|
|
27
|
+
FAILED_TO_GET_SECURITY_TOKEN: " Failed to Generate Security Token",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const ErrorMessageEnum = {
|
|
31
|
+
...InternalError,
|
|
32
|
+
...GeneralError,
|
|
33
|
+
...InitError,
|
|
34
|
+
...GetKeysError,
|
|
35
|
+
...GetSecurityResultError,
|
|
36
|
+
...GetSecurityTokenError,
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
39
|
+
export const SecurityAPIErrorsEnum = {
|
|
40
|
+
...GeneralError,
|
|
41
|
+
...InitError,
|
|
42
|
+
...GetKeysError,
|
|
43
|
+
...GetSecurityResultError,
|
|
44
|
+
...GetSecurityTokenError,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type ValueOf<T> = T[keyof T];
|
|
48
|
+
|
|
49
|
+
export type IErrorMessage = ValueOf<typeof ErrorMessageEnum>;
|
|
50
|
+
|
|
51
|
+
export type SecurityAPIErrors = ValueOf<typeof SecurityAPIErrorsEnum>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ISecurityCheckInput {
|
|
2
|
+
projectId: string;
|
|
3
|
+
visitorId?: string;
|
|
4
|
+
securitySettings?: {
|
|
5
|
+
countriesAllowed?: string[];
|
|
6
|
+
};
|
|
7
|
+
metaData?: any;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ISecurityCheckVisitorDataInput {
|
|
11
|
+
visitorData: {
|
|
12
|
+
behaviorToken: string;
|
|
13
|
+
automationToken: string;
|
|
14
|
+
behaviorRequestId: string;
|
|
15
|
+
browserLocale: string;
|
|
16
|
+
entryLink: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ISecurityResultResponse {
|
|
2
|
+
results: {
|
|
3
|
+
dtectScore: string;
|
|
4
|
+
isDuplicateDevice: boolean;
|
|
5
|
+
isDuplicateIp: boolean;
|
|
6
|
+
isDuplicateId: boolean;
|
|
7
|
+
isLocationBlocked: boolean;
|
|
8
|
+
isLocationInvalid: boolean;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ISecurityTokenResponse {
|
|
13
|
+
token: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IGetKeysResponse {
|
|
17
|
+
behaviorKey: string;
|
|
18
|
+
automationKey: string;
|
|
19
|
+
}
|
|
20
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es6",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"moduleResolution": "node",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"allowSyntheticDefaultImports": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"strict": true,
|
|
16
|
+
"skipLibCheck": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src"],
|
|
19
|
+
"exclude": ["node_modules"]
|
|
20
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ["src/index.ts", "src/**/*.ts", "src/**/*.tsx"],
|
|
5
|
+
target: "es2022",
|
|
6
|
+
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
7
|
+
sourcemap: false,
|
|
8
|
+
clean: true,
|
|
9
|
+
minify: true,
|
|
10
|
+
dts: true,
|
|
11
|
+
tsconfig: "tsconfig.json",
|
|
12
|
+
banner: {
|
|
13
|
+
js: `"use client";`
|
|
14
|
+
},
|
|
15
|
+
outDir: "dist",
|
|
16
|
+
format: ["cjs", "esm"],
|
|
17
|
+
minifyIdentifiers: true
|
|
18
|
+
})
|