@relazio/plugin-sdk 0.1.0 → 0.2.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/CHANGELOG.md +96 -0
- package/README.md +206 -200
- package/dist/core/types.d.ts +8 -8
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -1
- package/dist/utils/builders.d.ts +147 -0
- package/dist/utils/builders.d.ts.map +1 -0
- package/dist/utils/builders.js +316 -0
- package/dist/utils/id-generator.d.ts +81 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +122 -0
- package/dist/utils/result-builder.d.ts +109 -0
- package/dist/utils/result-builder.d.ts.map +1 -0
- package/dist/utils/result-builder.js +185 -0
- package/docs/builders-guide.md +520 -0
- package/docs/examples.md +238 -0
- package/docs/quick-start.md +287 -0
- package/docs/response-format.md +515 -0
- package/package.json +5 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2025-12-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Universal Entity Builder**: Complete builder system for creating entities and edges
|
|
12
|
+
- `createEntity()` - Universal, scalable function for creating any entity type (present or future)
|
|
13
|
+
- `EntityBuilder` - Fluent builder for advanced entity construction
|
|
14
|
+
- `createEdge()` - Edge creation function with validation
|
|
15
|
+
- `EdgeBuilder` - Fluent builder for complex edges
|
|
16
|
+
- **Automatic ID Generation**: Deterministic ID generation system
|
|
17
|
+
- `generateEntityId()` - MD5 hash-based deterministic entity IDs
|
|
18
|
+
- `generateEdgeId()` - Deterministic edge IDs
|
|
19
|
+
- `generateRandomId()` - Random IDs for temporary entities
|
|
20
|
+
- `normalizeValue()` - Value normalization for ID consistency
|
|
21
|
+
- **ResultBuilder**: Fluent builder for transform results
|
|
22
|
+
- `.addEntity()` - Add entity with automatic edge creation
|
|
23
|
+
- `.addEntities()` - Add multiple entities of the same type
|
|
24
|
+
- `.addEntityOnly()` - Add entity without edge
|
|
25
|
+
- `.setMessage()` - Set success message
|
|
26
|
+
- `.addMetadata()` - Add metadata to result
|
|
27
|
+
- **Helper Functions**: Utility functions for common cases
|
|
28
|
+
- `emptyResult()` - Empty result with optional message
|
|
29
|
+
- `errorResult()` - Error result
|
|
30
|
+
- `singleEntityResult()` - Single entity result
|
|
31
|
+
- `multiEntityResult()` - Multiple entity result
|
|
32
|
+
- **Validation Utilities**: Automatic format validation
|
|
33
|
+
- `validateEntities()` - Validate entity array
|
|
34
|
+
- `validateEdges()` - Validate edge array
|
|
35
|
+
- `validateTransformResult()` - Validate complete result
|
|
36
|
+
- **Documentation**: Complete documentation and examples
|
|
37
|
+
- Quick Start Guide
|
|
38
|
+
- Builders Guide
|
|
39
|
+
- Response Format Specification
|
|
40
|
+
- New comprehensive example: `simple-sync-example`
|
|
41
|
+
- Updated async example: `async-subdomain-scanner`
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- **BREAKING**: `OSINTEntity` now requires mandatory `id` field
|
|
45
|
+
- **BREAKING**: `OSINTEdge` now requires mandatory `id` field
|
|
46
|
+
- **BREAKING**: Removed support for `targetId: 'auto'` in edges
|
|
47
|
+
- **Scalability Improvement**: Removed type-specific helpers in favor of universal `createEntity()`
|
|
48
|
+
- Advantage: No SDK updates needed for new entity types
|
|
49
|
+
- Advantage: Supports custom entity types without code changes
|
|
50
|
+
- Advantage: Consistent, predictable API
|
|
51
|
+
- Updated all entity types to align with Relazio external format
|
|
52
|
+
- Added new entity types: `username`, `credential`, `social`, `document`, `image`, `video`, `wallet`, `transaction`, `exchange`, `maps`
|
|
53
|
+
- `TransformInput.entity` is now of type `OSINTEntity` (includes ID)
|
|
54
|
+
- Updated examples to use scalable approach
|
|
55
|
+
- Reorganized documentation to `docs/` folder
|
|
56
|
+
- All documentation rewritten in formal English
|
|
57
|
+
|
|
58
|
+
### Removed
|
|
59
|
+
- Type-specific helper functions (`createIP`, `createDomain`, etc.) - replaced with universal `createEntity()`
|
|
60
|
+
- Migration guide (not needed for initial release)
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
- Automatic format validation for responses
|
|
64
|
+
- Guaranteed unique IDs for all entities and edges
|
|
65
|
+
- Consistent field naming (only `metadata`, not `properties`)
|
|
66
|
+
|
|
67
|
+
## [0.1.1] - 2025-12-20
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- Simplified documentation
|
|
71
|
+
- Translated documentation to English
|
|
72
|
+
- Made documentation more formal and concise
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
- HTTP localhost support for development (manifest generator)
|
|
76
|
+
|
|
77
|
+
## [0.1.0] - 2025-12-20
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
- Initial public release
|
|
81
|
+
- Multi-tenant support with automatic organization management
|
|
82
|
+
- Synchronous and asynchronous transform handlers
|
|
83
|
+
- Built-in Express server with CORS and error handling
|
|
84
|
+
- Automatic `/register`, `/unregister`, `/manifest.json` endpoints
|
|
85
|
+
- HMAC-SHA256 signature utilities for webhook security
|
|
86
|
+
- Job progress tracking for async operations
|
|
87
|
+
- InstallationRegistry for organization management
|
|
88
|
+
- In-memory storage (development) and custom storage support (production)
|
|
89
|
+
- TypeScript support with full type definitions
|
|
90
|
+
- Working examples (email-parser, dns-toolkit, async-subdomain-scanner, multi-tenant-plugin)
|
|
91
|
+
|
|
92
|
+
### Security
|
|
93
|
+
- HMAC-SHA256 webhook signatures
|
|
94
|
+
- Organization isolation
|
|
95
|
+
- Unique webhook secrets per organization
|
|
96
|
+
- TLS certificate validation
|
package/README.md
CHANGED
|
@@ -1,98 +1,47 @@
|
|
|
1
|
-
# Relazio
|
|
1
|
+
# Relazio Plugin SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official SDK for building external plugins for the Relazio OSINT platform.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@relazio/plugin-sdk)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
**Platform Version**: 2.0.0
|
|
10
|
-
**SDK Status**: 📋 Documentation Phase
|
|
11
|
-
**Target Release**: Q1 2026
|
|
8
|
+
## Overview
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
The Relazio Plugin SDK provides a complete framework for building secure, scalable external plugins that extend the Relazio platform's capabilities with minimal boilerplate.
|
|
14
11
|
|
|
15
|
-
##
|
|
12
|
+
## Features
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
- **Multi-Tenant Support**: Automatic organization management with isolated configurations
|
|
15
|
+
- **Sync & Async Transforms**: Support for both immediate and long-running operations
|
|
16
|
+
- **Automatic Endpoints**: Built-in `/register`, `/unregister`, and `/manifest.json` endpoints
|
|
17
|
+
- **Security**: HMAC-SHA256 signature generation and validation
|
|
18
|
+
- **Job Management**: Progress tracking and webhook notifications for async operations
|
|
19
|
+
- **TypeScript**: Full type safety and IntelliSense support
|
|
20
|
+
- **Scalable Entity Creation**: Universal `createEntity()` function works with any entity type
|
|
21
|
+
- **Automatic ID Generation**: Deterministic ID generation for entities and edges
|
|
22
|
+
- **Result Builder**: Fluent API for constructing complex transform results
|
|
23
|
+
- **Automatic Validation**: Format validation according to Relazio specifications
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Il sistema plugin esterni della piattaforma è **PRODUCTION READY** (Dicembre 2025):
|
|
22
|
-
|
|
23
|
-
- ✅ Manifest validation (HTTPS, TLS, Zod)
|
|
24
|
-
- ✅ Installation flow completo
|
|
25
|
-
- ✅ Webhook system con HMAC-SHA256
|
|
26
|
-
- ✅ Job queue con 7 stati
|
|
27
|
-
- ✅ Rate limiting (30/min, 500/hour, 2000/day)
|
|
28
|
-
- ✅ Timeout enforcement (30 min max)
|
|
29
|
-
- ✅ Security completa
|
|
30
|
-
- ✅ E2E testing (44 test, 91% pass)
|
|
31
|
-
|
|
32
|
-
### SDK Packages Status
|
|
33
|
-
|
|
34
|
-
- ✅ `@relazio/plugin-sdk` - NPM package (TypeScript/JavaScript) - **COMPLETO** ⭐
|
|
35
|
-
- ✅ Core plugin system
|
|
36
|
-
- ✅ Sync & async transforms
|
|
37
|
-
- ✅ HMAC signature utilities
|
|
38
|
-
- ✅ Job progress tracking
|
|
39
|
-
- ✅ Express server integration
|
|
40
|
-
- ✅ **Multi-tenant support** (NEW!)
|
|
41
|
-
- [ ] `relazio-plugin-sdk` - PyPI package (Python) - Q1 2026
|
|
42
|
-
- [ ] CLI tool per scaffold plugin - Q1 2026
|
|
43
|
-
- [ ] Mock platform per testing locale - Q2 2026
|
|
44
|
-
- ✅ Repository esempi plugin - **4 esempi disponibili**
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 📚 Documentazione
|
|
49
|
-
|
|
50
|
-
Tutta la documentazione è disponibile nella cartella `docs/`:
|
|
51
|
-
|
|
52
|
-
### Per Utenti
|
|
53
|
-
|
|
54
|
-
- **[EXTERNAL_PLUGINS_README.md](docs/EXTERNAL_PLUGINS_README.md)** - Quick start guide per installare e usare plugin esterni
|
|
55
|
-
|
|
56
|
-
### Per Sviluppatori
|
|
57
|
-
|
|
58
|
-
- **[QUICKSTART.md](QUICKSTART.md)** - ⭐ Quick start per creare plugin (3 righe di codice!)
|
|
59
|
-
- **[SDK.md](docs/SDK.md)** - ⭐ SDK API reference completa (TypeScript/Python)
|
|
60
|
-
- **[MULTI_TENANT.md](docs/MULTI_TENANT.md)** - Guida multi-tenancy (architettura standard)
|
|
61
|
-
- **[CONFIGURATION.md](docs/CONFIGURATION.md)** - Guida configurazione (string, number, boolean, select)
|
|
62
|
-
- **[EXTERNAL_PLUGINS.md](docs/EXTERNAL_PLUGINS.md)** - Architettura sistema plugin esterni
|
|
63
|
-
- **[EXTERNAL_PLUGINS_FLOW.md](docs/EXTERNAL_PLUGINS_FLOW.md)** - Flussi dettagliati step-by-step
|
|
64
|
-
- **[IMPLEMENTATION_EXTERNAL_PLUGINS.md](docs/IMPLEMENTATION_EXTERNAL_PLUGINS.md)** - Piano implementazione (reference)
|
|
65
|
-
|
|
66
|
-
### Reference
|
|
67
|
-
|
|
68
|
-
- **[EXTERNAL_PLUGINS_COMPLETE.md](docs/EXTERNAL_PLUGINS_COMPLETE.md)** - Riepilogo completo dell'implementazione platform
|
|
69
|
-
- **[PLUGIN_SYSTEM.md](docs/PLUGIN_SYSTEM.md)** - Plugin built-in (reference)
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 🚀 Quick Start
|
|
74
|
-
|
|
75
|
-
### Installazione
|
|
25
|
+
## Installation
|
|
76
26
|
|
|
77
27
|
```bash
|
|
78
28
|
npm install @relazio/plugin-sdk
|
|
79
29
|
```
|
|
80
30
|
|
|
81
|
-
|
|
31
|
+
## Quick Start
|
|
82
32
|
|
|
83
33
|
```typescript
|
|
84
|
-
import { RelazioPlugin } from '@relazio/plugin-sdk';
|
|
34
|
+
import { RelazioPlugin, createEntity, ResultBuilder } from '@relazio/plugin-sdk';
|
|
85
35
|
|
|
86
36
|
const plugin = new RelazioPlugin({
|
|
87
37
|
id: 'my-plugin',
|
|
88
38
|
name: 'My Plugin',
|
|
89
39
|
version: '1.0.0',
|
|
90
40
|
author: 'Your Name',
|
|
91
|
-
description: '
|
|
41
|
+
description: 'Plugin description',
|
|
92
42
|
category: 'network'
|
|
93
43
|
});
|
|
94
44
|
|
|
95
|
-
// Registra transform
|
|
96
45
|
plugin.transform({
|
|
97
46
|
id: 'my-transform',
|
|
98
47
|
name: 'My Transform',
|
|
@@ -100,156 +49,213 @@ plugin.transform({
|
|
|
100
49
|
inputType: 'domain',
|
|
101
50
|
outputTypes: ['ip'],
|
|
102
51
|
|
|
103
|
-
|
|
104
|
-
//
|
|
105
|
-
|
|
52
|
+
async handler(input) {
|
|
53
|
+
// Create entity using universal createEntity()
|
|
54
|
+
const ip = createEntity('ip', '8.8.8.8', {
|
|
55
|
+
label: 'Google DNS',
|
|
56
|
+
metadata: { country: 'US' }
|
|
57
|
+
});
|
|
106
58
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
],
|
|
115
|
-
edges: []
|
|
116
|
-
};
|
|
59
|
+
// Build result with automatic edge creation
|
|
60
|
+
return new ResultBuilder(input)
|
|
61
|
+
.addEntity(ip, 'resolves to', {
|
|
62
|
+
relationship: 'dns_resolution'
|
|
63
|
+
})
|
|
64
|
+
.setMessage('DNS resolved successfully')
|
|
65
|
+
.build();
|
|
117
66
|
}
|
|
118
67
|
});
|
|
119
68
|
|
|
120
|
-
|
|
121
|
-
plugin.start({
|
|
69
|
+
await plugin.start({
|
|
122
70
|
port: 3000,
|
|
123
|
-
multiTenant: true
|
|
71
|
+
multiTenant: true
|
|
124
72
|
});
|
|
125
73
|
```
|
|
126
74
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
- **Email Parser** - Transform sincrona semplice
|
|
137
|
-
- **DNS Toolkit** - Multiple transforms sincrone
|
|
138
|
-
- **Multi-Tenant Plugin** - Transform asincrona con multi-organization
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## 🎯 Roadmap
|
|
143
|
-
|
|
144
|
-
### Phase 1: Documentation ✅ (Completata - Dicembre 2025)
|
|
145
|
-
- [x] Architecture design
|
|
146
|
-
- [x] SDK API design
|
|
147
|
-
- [x] Flow documentation
|
|
148
|
-
- [x] Security requirements
|
|
149
|
-
- [x] Platform implementation
|
|
150
|
-
|
|
151
|
-
### Phase 2: TypeScript SDK ✅ (Completata - Dicembre 2025)
|
|
152
|
-
- [x] Core SDK implementation
|
|
153
|
-
- [x] Manifest generator
|
|
154
|
-
- [x] HMAC signing utilities
|
|
155
|
-
- [x] Webhook handler
|
|
156
|
-
- [x] Job progress tracking
|
|
157
|
-
- [x] Testing utilities
|
|
158
|
-
- [x] Esempi funzionanti
|
|
159
|
-
- [ ] NPM package publication (Q1 2026)
|
|
160
|
-
- [ ] CLI tool (Q1 2026)
|
|
161
|
-
|
|
162
|
-
### Phase 3: Python SDK (Q1 2026)
|
|
163
|
-
- [ ] Core SDK implementation
|
|
164
|
-
- [ ] Manifest generator
|
|
165
|
-
- [ ] HMAC signing utilities
|
|
166
|
-
- [ ] Webhook handler (Flask/FastAPI)
|
|
167
|
-
- [ ] Job progress tracking
|
|
168
|
-
- [ ] Testing utilities
|
|
169
|
-
- [ ] CLI tool
|
|
170
|
-
- [ ] PyPI package publication
|
|
171
|
-
|
|
172
|
-
### Phase 4: Developer Experience (Q2 2026)
|
|
173
|
-
- [ ] Developer portal
|
|
174
|
-
- [ ] Plugin examples repository
|
|
175
|
-
- [ ] Video tutorials
|
|
176
|
-
- [ ] Plugin templates (starter kits)
|
|
177
|
-
- [ ] Testing playground
|
|
178
|
-
- [ ] Plugin marketplace submission
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## 🔐 Security Requirements
|
|
183
|
-
|
|
184
|
-
### Mandatory (Enforced by Platform)
|
|
185
|
-
|
|
186
|
-
- ✅ **HTTPS**: All endpoints must use HTTPS (HTTP rejected)
|
|
187
|
-
- ✅ **TLS Valid**: Valid SSL certificate required
|
|
188
|
-
- ✅ **HMAC Signature**: All webhooks must be signed with HMAC-SHA256
|
|
189
|
-
- ✅ **Rate Limiting**: 30 req/min, 500 req/hour, 2000 req/day
|
|
190
|
-
- ✅ **Timeouts**: 30s sync, 5s async response, 30 min job max
|
|
191
|
-
|
|
192
|
-
### SDK Handles
|
|
193
|
-
|
|
194
|
-
- HMAC signature generation
|
|
195
|
-
- Webhook endpoint setup
|
|
196
|
-
- Job progress tracking
|
|
197
|
-
- Error handling
|
|
198
|
-
- Timeout awareness
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
## 📦 Package Structure (Future)
|
|
75
|
+
## Documentation
|
|
76
|
+
|
|
77
|
+
- **[Quick Start Guide](./docs/quick-start.md)** - Get started in 5 minutes with sync and async examples
|
|
78
|
+
- **[Builders Guide](./docs/builders-guide.md)** - Complete guide to builders and utilities
|
|
79
|
+
- **[Response Format Specification](./docs/response-format.md)** - Required response format
|
|
80
|
+
- **[Examples Documentation](./docs/examples.md)** - Complete working examples
|
|
81
|
+
- [simple-sync-example](./examples/simple-sync-example/) - Synchronous transform example
|
|
82
|
+
- [async-subdomain-scanner](./examples/async-subdomain-scanner/) - Asynchronous transform example
|
|
83
|
+
- [Changelog](./CHANGELOG.md) - Version history
|
|
203
84
|
|
|
85
|
+
## Entity & Edge Builders
|
|
86
|
+
|
|
87
|
+
The SDK uses a dynamic, scalable approach that works with any entity type:
|
|
88
|
+
|
|
89
|
+
### Universal Entity Creation
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { createEntity } from '@relazio/plugin-sdk';
|
|
93
|
+
|
|
94
|
+
// Works with ANY type - even future types!
|
|
95
|
+
const ip = createEntity('ip', '8.8.8.8', {
|
|
96
|
+
label: 'Google DNS',
|
|
97
|
+
metadata: { country: 'US', isp: 'Google LLC' }
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const domain = createEntity('domain', 'example.com');
|
|
101
|
+
|
|
102
|
+
const location = createEntity('location', 'New York, NY', {
|
|
103
|
+
metadata: { latitude: 40.7, longitude: -74.0 }
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Works with custom types too!
|
|
107
|
+
const customEntity = createEntity('future-entity-type', 'value', {
|
|
108
|
+
metadata: { /* ... */ }
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// ID automatically generated: "ip-c909e98d"
|
|
112
|
+
console.log(ip.id);
|
|
204
113
|
```
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
114
|
+
|
|
115
|
+
**Advantages**:
|
|
116
|
+
- No SDK updates needed for new entity types
|
|
117
|
+
- Works with custom entity types
|
|
118
|
+
- Type-safe with TypeScript
|
|
119
|
+
- Deterministic ID generation
|
|
120
|
+
|
|
121
|
+
### Result Builder
|
|
122
|
+
|
|
123
|
+
Build complex results easily:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { ResultBuilder, createEntity } from '@relazio/plugin-sdk';
|
|
127
|
+
|
|
128
|
+
handler: async (input) => {
|
|
129
|
+
const location = createEntity('location', 'Mountain View, CA', {
|
|
130
|
+
metadata: { latitude: 37.386, longitude: -122.084 }
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const org = createEntity('organization', 'Google LLC', {
|
|
134
|
+
metadata: { asn: 'AS15169' }
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Edges created automatically!
|
|
138
|
+
return new ResultBuilder(input)
|
|
139
|
+
.addEntity(location, 'located in', {
|
|
140
|
+
relationship: 'geolocation'
|
|
141
|
+
})
|
|
142
|
+
.addEntity(org, 'assigned by', {
|
|
143
|
+
relationship: 'isp_assignment'
|
|
144
|
+
})
|
|
145
|
+
.setMessage('IP analyzed successfully')
|
|
146
|
+
.build();
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Supported Entity Types
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
type EntityType =
|
|
154
|
+
| 'email' | 'domain' | 'ip' | 'person' | 'username'
|
|
155
|
+
| 'phone' | 'organization' | 'hash' | 'credential'
|
|
156
|
+
| 'social' | 'document' | 'note' | 'image' | 'video'
|
|
157
|
+
| 'location' | 'wallet' | 'transaction' | 'exchange'
|
|
158
|
+
| 'url' | 'maps' | 'custom';
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Multi-Tenant Architecture
|
|
162
|
+
|
|
163
|
+
The SDK automatically handles organization registration and management:
|
|
164
|
+
|
|
165
|
+
1. Platform requests `/register` with organization details
|
|
166
|
+
2. SDK generates unique webhook secret
|
|
167
|
+
3. SDK stores organization configuration
|
|
168
|
+
4. Platform receives webhook secret
|
|
169
|
+
5. Plugin processes requests with organization isolation
|
|
170
|
+
|
|
171
|
+
## Security
|
|
172
|
+
|
|
173
|
+
All plugins must implement the following security requirements:
|
|
174
|
+
|
|
175
|
+
- **HTTPS**: Production endpoints must use HTTPS
|
|
176
|
+
- **HMAC Signatures**: All webhooks are signed with HMAC-SHA256
|
|
177
|
+
- **Rate Limiting**: Enforced by the platform (30 req/min, 500 req/hour)
|
|
178
|
+
- **Timeouts**: 30s for sync transforms, 30 minutes maximum for async jobs
|
|
179
|
+
|
|
180
|
+
## API Reference
|
|
181
|
+
|
|
182
|
+
### Core Classes
|
|
183
|
+
|
|
184
|
+
#### RelazioPlugin
|
|
185
|
+
|
|
186
|
+
Main plugin class that manages transforms and server lifecycle.
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const plugin = new RelazioPlugin(config: PluginConfig)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Transform Registration
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Synchronous transform
|
|
196
|
+
plugin.transform({
|
|
197
|
+
id: string,
|
|
198
|
+
name: string,
|
|
199
|
+
description: string,
|
|
200
|
+
inputType: EntityType,
|
|
201
|
+
outputTypes: EntityType[],
|
|
202
|
+
handler: async (input, config) => TransformResult
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
// Asynchronous transform
|
|
206
|
+
plugin.asyncTransform({
|
|
207
|
+
id: string,
|
|
208
|
+
name: string,
|
|
209
|
+
description: string,
|
|
210
|
+
inputType: EntityType,
|
|
211
|
+
outputTypes: EntityType[],
|
|
212
|
+
handler: async (input, config, job) => TransformResult
|
|
213
|
+
})
|
|
226
214
|
```
|
|
227
215
|
|
|
228
|
-
|
|
216
|
+
#### Server Management
|
|
229
217
|
|
|
230
|
-
|
|
218
|
+
```typescript
|
|
219
|
+
await plugin.start({
|
|
220
|
+
port: number,
|
|
221
|
+
host?: string,
|
|
222
|
+
multiTenant?: boolean,
|
|
223
|
+
https?: { key: string, cert: string }
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
await plugin.stop()
|
|
227
|
+
```
|
|
231
228
|
|
|
232
|
-
|
|
229
|
+
## Requirements
|
|
233
230
|
|
|
234
|
-
|
|
231
|
+
- Node.js >= 18.0.0
|
|
232
|
+
- TypeScript >= 5.0.0 (for development)
|
|
235
233
|
|
|
236
|
-
##
|
|
234
|
+
## Examples
|
|
237
235
|
|
|
238
|
-
|
|
236
|
+
### Synchronous Transform
|
|
239
237
|
|
|
240
|
-
|
|
238
|
+
```bash
|
|
239
|
+
cd examples/simple-sync-example
|
|
240
|
+
npm install
|
|
241
|
+
npm start
|
|
242
|
+
```
|
|
241
243
|
|
|
242
|
-
|
|
244
|
+
### Asynchronous Transform
|
|
243
245
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
```bash
|
|
247
|
+
cd examples/async-subdomain-scanner
|
|
248
|
+
npm install
|
|
249
|
+
npm start
|
|
250
|
+
```
|
|
248
251
|
|
|
249
|
-
|
|
252
|
+
## License
|
|
250
253
|
|
|
251
|
-
|
|
252
|
-
**Platform**: ✅ Production Ready (Dicembre 2025)
|
|
253
|
-
**SDK**: 🚧 In Development (Q1 2026)
|
|
254
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
254
255
|
|
|
256
|
+
## Links
|
|
255
257
|
|
|
258
|
+
- [npm Package](https://www.npmjs.com/package/@relazio/plugin-sdk)
|
|
259
|
+
- [GitHub Repository](https://github.com/relazio/plugin-sdk)
|
|
260
|
+
- [Issue Tracker](https://github.com/relazio/plugin-sdk/issues)
|
|
261
|
+
- [Documentation](./docs/)
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tipi core per Relazio Plugin SDK
|
|
3
3
|
*/
|
|
4
|
-
export type EntityType = 'domain' | 'ip' | '
|
|
4
|
+
export type EntityType = 'email' | 'domain' | 'ip' | 'person' | 'username' | 'phone' | 'organization' | 'hash' | 'credential' | 'social' | 'document' | 'note' | 'image' | 'video' | 'location' | 'wallet' | 'transaction' | 'exchange' | 'url' | 'maps' | 'custom';
|
|
5
5
|
export type PluginCategory = 'network' | 'identity' | 'social' | 'financial' | 'security' | 'other';
|
|
6
6
|
export type JobStatus = 'pending' | 'submitted' | 'processing' | 'completed' | 'failed' | 'timeout' | 'cancelled';
|
|
7
7
|
/**
|
|
8
|
-
* Entità OSINT
|
|
8
|
+
* Entità OSINT (formato esterno - con ID obbligatorio)
|
|
9
9
|
*/
|
|
10
10
|
export interface OSINTEntity {
|
|
11
|
+
id: string;
|
|
11
12
|
type: EntityType;
|
|
12
13
|
value: string;
|
|
13
14
|
label?: string;
|
|
14
15
|
metadata?: Record<string, any>;
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
|
-
* Arco/connessione tra entità
|
|
18
|
+
* Arco/connessione tra entità (formato esterno)
|
|
18
19
|
*/
|
|
19
20
|
export interface OSINTEdge {
|
|
21
|
+
id: string;
|
|
20
22
|
sourceId: string;
|
|
21
|
-
targetId: string
|
|
23
|
+
targetId: string;
|
|
22
24
|
label: string;
|
|
23
|
-
relationship
|
|
25
|
+
relationship?: string;
|
|
24
26
|
metadata?: Record<string, any>;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Input per una transform
|
|
28
30
|
*/
|
|
29
31
|
export interface TransformInput {
|
|
30
|
-
entity: OSINTEntity
|
|
31
|
-
id: string;
|
|
32
|
-
};
|
|
32
|
+
entity: OSINTEntity;
|
|
33
33
|
config?: Record<string, any>;
|
|
34
34
|
organizationId?: string;
|
|
35
35
|
}
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,IAAI,GACJ,OAAO,GACP,OAAO,GACP,QAAQ,GACR,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,7 @@ export { InstallationRegistry, MemoryStorage } from './registry/installation';
|
|
|
12
12
|
export type { Installation, RegistrationRequest, RegistrationResponse, InstallationStorage } from './registry/installation';
|
|
13
13
|
export { ExpressServer } from './server/express';
|
|
14
14
|
export type { Server } from './server/express';
|
|
15
|
+
export { createEntity, createEdge, EntityBuilder, EdgeBuilder, validateEntities, validateEdges, validateTransformResult, } from './utils/builders';
|
|
16
|
+
export { generateEntityId, generateEdgeId, generateRandomId, normalizeValue, isValidEntityId, isValidEdgeId, } from './utils/id-generator';
|
|
17
|
+
export { ResultBuilder, emptyResult, errorResult, singleEntityResult, multiEntityResult, } from './utils/result-builder';
|
|
15
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,YAAY,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,WAAW,EACX,SAAS,EACT,cAAc,EACd,eAAe,EACf,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACvF,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,EACL,oBAAoB,EACpB,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,YAAY,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,WAAW,EACX,SAAS,EACT,cAAc,EACd,eAAe,EACf,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACvF,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,EACL,oBAAoB,EACpB,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAEL,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,EAEX,gBAAgB,EAChB,aAAa,EACb,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,aAAa,EACb,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC"}
|