@danetix/sentinel 1.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/LICENSE +7 -0
- package/README.md +217 -0
- package/dist/stl.cjs.min.js +1 -0
- package/dist/stl.esm.min.js +1 -0
- package/dist/stl.min.js +1 -0
- package/dist/stl.umd.min.js +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 Danetix. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary and confidential. Unauthorized copying,
|
|
4
|
+
modification, distribution, or use of this software, in whole or in part,
|
|
5
|
+
is strictly prohibited without the express written permission of Danetix.
|
|
6
|
+
|
|
7
|
+
For licensing inquiries, contact: info@danetix.com
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# @danetix/sentinel
|
|
2
|
+
|
|
3
|
+
Device intelligence SDK by [Danetix](https://danetix.com). Collects 155+ browser signals for device identification, bot detection, and anti-tamper analysis.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **155+ browser signals** — canvas, audio, WebGL, WebGPU, fonts, and more
|
|
8
|
+
- **Bot detection** — headless browsers, automation tools, CDP, Playwright, Puppeteer
|
|
9
|
+
- **Anti-tamper** — proxy detection, descriptor integrity, prototype chain validation
|
|
10
|
+
- **Anti-detect browser detection** — Multilogin, GoLogin, AdsPower
|
|
11
|
+
- **Self-contained** — zero runtime dependencies, ~60KB gzipped
|
|
12
|
+
- **All formats** — IIFE, ESM, CJS, UMD
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<script type="module">
|
|
18
|
+
const sentinel = import('https://your-domain.com/stl.esm.min.js')
|
|
19
|
+
.then(S => S.start({
|
|
20
|
+
apiKey: 'YOUR_API_KEY',
|
|
21
|
+
endpoint: 'https://your-domain.com/ingest'
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
sentinel
|
|
25
|
+
.then(s => s.get())
|
|
26
|
+
.then(result => {
|
|
27
|
+
console.log(result.requestId)
|
|
28
|
+
console.log(result.deviceId)
|
|
29
|
+
})
|
|
30
|
+
</script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @danetix/sentinel
|
|
37
|
+
# or
|
|
38
|
+
pnpm add @danetix/sentinel
|
|
39
|
+
# or
|
|
40
|
+
yarn add @danetix/sentinel
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
### ESM (recommended)
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { start } from '@danetix/sentinel'
|
|
49
|
+
|
|
50
|
+
const sentinel = start({
|
|
51
|
+
apiKey: 'YOUR_API_KEY',
|
|
52
|
+
endpoint: 'https://your-domain.com/ingest',
|
|
53
|
+
cache: { ttl: 300 } // optional: cache results for 5 minutes
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const result = await sentinel.get()
|
|
57
|
+
console.log(result.deviceId)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Script Tag
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<script src="https://your-domain.com/stl.min.js"></script>
|
|
64
|
+
<script>
|
|
65
|
+
var sentinel = Sentinel.start({
|
|
66
|
+
apiKey: 'YOUR_API_KEY',
|
|
67
|
+
endpoint: '/ingest'
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
sentinel.get().then(function(result) {
|
|
71
|
+
console.log(result.deviceId)
|
|
72
|
+
})
|
|
73
|
+
</script>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### SPA (Single Page Application)
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
const sentinel = start({
|
|
80
|
+
apiKey: 'YOUR_API_KEY',
|
|
81
|
+
endpoint: '/ingest',
|
|
82
|
+
cache: { ttl: 300, location: 'sessionStorage' }
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Call on each route change
|
|
86
|
+
router.afterEach(() => {
|
|
87
|
+
sentinel.get()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// Force fresh request
|
|
91
|
+
sentinel.get({ ignoreCache: true })
|
|
92
|
+
|
|
93
|
+
// Clear cache manually
|
|
94
|
+
sentinel.clearCache()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## API
|
|
98
|
+
|
|
99
|
+
### `start(options): SentinelInstance`
|
|
100
|
+
|
|
101
|
+
Initialize the SDK. Starts signal collection immediately.
|
|
102
|
+
|
|
103
|
+
| Option | Type | Default | Description |
|
|
104
|
+
|--------|------|---------|-------------|
|
|
105
|
+
| `apiKey` | `string` | *required* | Workspace API key |
|
|
106
|
+
| `endpoint` | `string` | *required* | Ingest endpoint URL |
|
|
107
|
+
| `cache` | `CacheOptions` | — | Enable result caching |
|
|
108
|
+
| `cache.ttl` | `number` | `0` | Cache TTL in seconds |
|
|
109
|
+
| `cache.location` | `'memory' \| 'localStorage' \| 'sessionStorage'` | `'memory'` | Cache storage |
|
|
110
|
+
| `debug` | `boolean` | `false` | Enable debug logging |
|
|
111
|
+
| `proxyDetection` | `'light' \| 'high'` | `'high'` | Anti-detect detection mode |
|
|
112
|
+
|
|
113
|
+
### `SentinelInstance.get(options?): Promise<CaptureResult>`
|
|
114
|
+
|
|
115
|
+
Capture device signals, send to endpoint, return result.
|
|
116
|
+
|
|
117
|
+
| Option | Type | Description |
|
|
118
|
+
|--------|------|-------------|
|
|
119
|
+
| `ignoreCache` | `boolean` | Skip cache, force fresh request |
|
|
120
|
+
| `linkedId` | `string` | Custom identifier (user login, order ID) |
|
|
121
|
+
| `tag` | `Record<string, unknown>` | Custom metadata |
|
|
122
|
+
|
|
123
|
+
### `SentinelInstance.clearCache(): void`
|
|
124
|
+
|
|
125
|
+
Clear cached result. Next `.get()` will make a fresh request.
|
|
126
|
+
|
|
127
|
+
### `CaptureResult`
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
{
|
|
131
|
+
requestId: string // Unique event ID
|
|
132
|
+
deviceId: string // Stable device identifier
|
|
133
|
+
signedDeviceToken: string // Signed token for persistence
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Browser Support
|
|
138
|
+
|
|
139
|
+
| Browser | Version |
|
|
140
|
+
|---------|---------|
|
|
141
|
+
| Chrome | 80+ |
|
|
142
|
+
| Firefox | 113+ |
|
|
143
|
+
| Safari | 16.4+ |
|
|
144
|
+
| Edge | 80+ |
|
|
145
|
+
| Samsung Internet | 14+ |
|
|
146
|
+
|
|
147
|
+
## Bundle Sizes
|
|
148
|
+
|
|
149
|
+
| Format | File | Size | Gzipped |
|
|
150
|
+
|--------|------|------|---------|
|
|
151
|
+
| IIFE | `stl.min.js` | 190 KB | ~60 KB |
|
|
152
|
+
| ESM | `stl.esm.min.js` | 196 KB | ~62 KB |
|
|
153
|
+
| CJS | `stl.cjs.min.js` | 196 KB | ~62 KB |
|
|
154
|
+
| UMD | `stl.umd.min.js` | 190 KB | ~60 KB |
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
Proprietary. See LICENSE for details.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
# @danetix/sentinel (RU)
|
|
163
|
+
|
|
164
|
+
SDK для анализа устройств от [Danetix](https://danetix.com). Собирает 155+ сигналов браузера для идентификации устройств, обнаружения ботов и защиты от подмены.
|
|
165
|
+
|
|
166
|
+
## Быстрый старт
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<script type="module">
|
|
170
|
+
const sentinel = import('https://your-domain.com/stl.esm.min.js')
|
|
171
|
+
.then(S => S.start({
|
|
172
|
+
apiKey: 'ВАШ_API_КЛЮЧ',
|
|
173
|
+
endpoint: 'https://your-domain.com/ingest'
|
|
174
|
+
}))
|
|
175
|
+
|
|
176
|
+
sentinel
|
|
177
|
+
.then(s => s.get())
|
|
178
|
+
.then(result => {
|
|
179
|
+
console.log(result.requestId)
|
|
180
|
+
console.log(result.deviceId)
|
|
181
|
+
})
|
|
182
|
+
</script>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Установка
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npm install @danetix/sentinel
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Использование в SPA
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
import { start } from '@danetix/sentinel'
|
|
195
|
+
|
|
196
|
+
const sentinel = start({
|
|
197
|
+
apiKey: 'ВАШ_API_КЛЮЧ',
|
|
198
|
+
endpoint: '/ingest',
|
|
199
|
+
cache: { ttl: 300, location: 'sessionStorage' }
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
// Вызывать при каждой смене роута
|
|
203
|
+
router.afterEach(() => sentinel.get())
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Опции кеширования
|
|
207
|
+
|
|
208
|
+
| Опция | Тип | Описание |
|
|
209
|
+
|-------|-----|----------|
|
|
210
|
+
| `ttl` | `number` | Время жизни кеша в секундах |
|
|
211
|
+
| `location` | `'memory' \| 'localStorage' \| 'sessionStorage'` | Где хранить кеш |
|
|
212
|
+
|
|
213
|
+
Без `cache` — каждый `.get()` отправляет запрос на сервер.
|
|
214
|
+
|
|
215
|
+
## Лицензия
|
|
216
|
+
|
|
217
|
+
Проприетарная. Подробности в файле LICENSE.
|