@kkuffour/solid-moderation-plugin 0.2.2 → 0.3.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.
Files changed (74) hide show
  1. package/.data/.internal/idp/keys/cookie-secret$.json +1 -0
  2. package/.data/.internal/idp/keys/jwks$.json +1 -0
  3. package/.data/.internal/setup/current-base-url$.json +1 -0
  4. package/PLUGIN_DEVELOPER_GUIDE.md +213 -0
  5. package/README.md +25 -28
  6. package/components/context.jsonld +6 -245
  7. package/config/default.json +14 -28
  8. package/dist/ModerationHandler.d.ts +21 -0
  9. package/dist/ModerationHandler.d.ts.map +1 -0
  10. package/dist/ModerationHandler.js +158 -0
  11. package/dist/ModerationHandler.js.map +1 -0
  12. package/dist/ModerationHandler.jsonld +126 -0
  13. package/dist/components/components.jsonld +13 -0
  14. package/dist/components/context.jsonld +11 -0
  15. package/dist/index.d.ts +1 -6
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -6
  18. package/dist/index.js.map +1 -1
  19. package/dist/providers/SightEngineProvider.jsonld +2 -2
  20. package/package.json +11 -11
  21. package/src/ModerationHandler.ts +189 -0
  22. package/src/index.ts +1 -6
  23. package/ARCHITECTURE.md +0 -52
  24. package/CONFIG-GUIDE.md +0 -49
  25. package/DEVELOPMENT.md +0 -129
  26. package/ENV-VARIABLES.md +0 -137
  27. package/INSTALLATION.md +0 -90
  28. package/MIGRATION.md +0 -81
  29. package/PRODUCTION.md +0 -186
  30. package/PUBLISHING.md +0 -104
  31. package/TESTING.md +0 -93
  32. package/components/components.jsonld +0 -18
  33. package/dist/ModerationConfig.d.ts +0 -16
  34. package/dist/ModerationConfig.d.ts.map +0 -1
  35. package/dist/ModerationConfig.js +0 -18
  36. package/dist/ModerationConfig.js.map +0 -1
  37. package/dist/ModerationConfig.jsonld +0 -66
  38. package/dist/ModerationMixin.d.ts +0 -13
  39. package/dist/ModerationMixin.d.ts.map +0 -1
  40. package/dist/ModerationMixin.js +0 -136
  41. package/dist/ModerationMixin.js.map +0 -1
  42. package/dist/ModerationMixin.jsonld +0 -180
  43. package/dist/ModerationOperationHandler.d.ts +0 -16
  44. package/dist/ModerationOperationHandler.d.ts.map +0 -1
  45. package/dist/ModerationOperationHandler.js +0 -45
  46. package/dist/ModerationOperationHandler.js.map +0 -1
  47. package/dist/ModerationOperationHandler.jsonld +0 -140
  48. package/dist/ModerationRecord.d.ts +0 -20
  49. package/dist/ModerationRecord.d.ts.map +0 -1
  50. package/dist/ModerationRecord.js +0 -3
  51. package/dist/ModerationRecord.js.map +0 -1
  52. package/dist/ModerationRecord.jsonld +0 -59
  53. package/dist/ModerationResourceStore.d.ts +0 -30
  54. package/dist/ModerationResourceStore.d.ts.map +0 -1
  55. package/dist/ModerationResourceStore.js +0 -167
  56. package/dist/ModerationResourceStore.js.map +0 -1
  57. package/dist/ModerationResourceStore.jsonld +0 -157
  58. package/dist/ModerationStore.d.ts +0 -12
  59. package/dist/ModerationStore.d.ts.map +0 -1
  60. package/dist/ModerationStore.js +0 -37
  61. package/dist/ModerationStore.js.map +0 -1
  62. package/dist/ModerationStore.jsonld +0 -59
  63. package/dist/util/GuardedStream.d.ts +0 -33
  64. package/dist/util/GuardedStream.d.ts.map +0 -1
  65. package/dist/util/GuardedStream.js +0 -89
  66. package/dist/util/GuardedStream.js.map +0 -1
  67. package/simple-test.json +0 -7
  68. package/src/ModerationConfig.ts +0 -29
  69. package/src/ModerationMixin.ts +0 -153
  70. package/src/ModerationOperationHandler.ts +0 -64
  71. package/src/ModerationRecord.ts +0 -19
  72. package/src/ModerationResourceStore.ts +0 -227
  73. package/src/ModerationStore.ts +0 -41
  74. package/src/util/GuardedStream.ts +0 -101
@@ -0,0 +1 @@
1
+ {"key":"idp/keys/cookie-secret","payload":["59d073a4fc66124c74d4d8f2d32f0383ef82d91122b25ee81ad691a46dc785203c2720e6e47d9ab7f19bf8970f460cb672267c6c47064e91f36285542b8d694b"]}
@@ -0,0 +1 @@
1
+ {"key":"idp/keys/jwks","payload":{"keys":[{"kty":"EC","x":"ttiH782m1M7AgKeQtsBJbJ6wx453vyKjJxho6vS7GpQ","y":"38doyGzPtVycO8Su7jVHDiY3n1zDofPNlUqYBut8FSA","crv":"P-256","d":"lVK7R5xL1Oph5Vh7FZPOZNwr24QTRu3HECdC8DLKd9Y","alg":"ES256"}]}}
@@ -0,0 +1 @@
1
+ {"key":"setup/current-base-url","payload":"http://localhost:3009/"}
@@ -0,0 +1,213 @@
1
+ # Plugin Developer Guide: Using the ExtensionHandler
2
+
3
+ ## Quick Start
4
+
5
+ To create a plugin that extends Community Solid Server functionality:
6
+
7
+ ### 1. Create Your Handler Class
8
+
9
+ Your handler must extend `OperationHandler` from CSS:
10
+
11
+ ```typescript
12
+ import { OperationHandler } from '@solid/community-server';
13
+ import type { OperationHandlerInput, ResponseDescription } from '@solid/community-server';
14
+ import { NotFoundHttpError } from '@solid/community-server';
15
+
16
+ export class MyPluginHandler extends OperationHandler {
17
+ public async handle(input: OperationHandlerInput): Promise<ResponseDescription> {
18
+ const { operation } = input;
19
+
20
+ // Your custom logic here
21
+ // Example: Check if operation should be handled
22
+ if (this.shouldHandle(operation)) {
23
+ // Process the operation
24
+ return this.processOperation(operation);
25
+ }
26
+
27
+ // Pass to next handler in chain
28
+ throw new NotFoundHttpError();
29
+ }
30
+
31
+ private shouldHandle(operation: Operation): boolean {
32
+ // Your logic to determine if this operation should be handled
33
+ return operation.method === 'POST' || operation.method === 'PUT';
34
+ }
35
+
36
+ private async processOperation(operation: Operation): Promise<ResponseDescription> {
37
+ // Your processing logic
38
+ // Return a ResponseDescription or throw an error
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### 2. Create Components.js Configuration
44
+
45
+ Create a config file (e.g., `config/default.json`) in your plugin package:
46
+
47
+ ```json
48
+ {
49
+ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
50
+ "import": ["css:config/file.json"],
51
+ "@graph": [
52
+ {
53
+ "@id": "urn:solid-server:default:ExtensionHandler",
54
+ "@type": "MyPluginHandler",
55
+ "MyPluginHandler:config": { "@id": "urn:my-plugin:config" }
56
+ },
57
+ {
58
+ "@id": "urn:my-plugin:config",
59
+ "@type": "MyPluginConfig",
60
+ "MyPluginConfig:enabled": true,
61
+ "MyPluginConfig:apiKey": "@ENV:MY_PLUGIN_API_KEY"
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ ### 3. Package Structure
68
+
69
+ ```
70
+ my-solid-plugin/
71
+ ├── package.json
72
+ ├── src/
73
+ │ ├── MyPluginHandler.ts
74
+ │ └── index.ts
75
+ ├── config/
76
+ │ └── default.json
77
+ └── components/
78
+ └── context.jsonld
79
+ ```
80
+
81
+ ### 4. Package.json Setup
82
+
83
+ ```json
84
+ {
85
+ "name": "@myorg/solid-plugin",
86
+ "version": "1.0.0",
87
+ "main": "dist/index.js",
88
+ "types": "dist/index.d.ts",
89
+ "lsd:module": true,
90
+ "lsd:components": "components/components.jsonld",
91
+ "lsd:contexts": {
92
+ "https://linkedsoftwaredependencies.org/bundles/npm/@myorg/solid-plugin/^1.0.0/components/context.jsonld": "components/context.jsonld"
93
+ },
94
+ "peerDependencies": {
95
+ "@solid/community-server": "^7.0.0"
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### 5. User Installation
101
+
102
+ Users install both CSS and your plugin:
103
+
104
+ ```bash
105
+ npm install @solid/community-server
106
+ npm install @myorg/solid-plugin
107
+ ```
108
+
109
+ ### 6. User Configuration
110
+
111
+ Users run CSS with your plugin config:
112
+
113
+ ```bash
114
+ npx community-solid-server \
115
+ -c @css:config/file.json \
116
+ -c @myorg/solid-plugin:config/default.json \
117
+ -f data/ -p 3000
118
+ ```
119
+
120
+ Or create a combined config file:
121
+
122
+ ```json
123
+ {
124
+ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
125
+ "import": [
126
+ "css:config/file.json",
127
+ "@myorg/solid-plugin:config/default.json"
128
+ ]
129
+ }
130
+ ```
131
+
132
+ ## Key Points
133
+
134
+ ### The Extension Point
135
+
136
+ **URN**: `urn:solid-server:default:ExtensionHandler`
137
+
138
+ **Interface**: `OperationHandler`
139
+
140
+ **Position**: First in the handler chain (runs before GET, POST, PUT, etc.)
141
+
142
+ **Behavior**: Your handler is called for EVERY operation. If you don't handle it, throw `NotFoundHttpError` to pass to the next handler.
143
+
144
+ ### Handler Chain Flow
145
+
146
+ ```
147
+ Request → ExtensionHandler (your plugin) → GET/POST/PUT/etc handlers → Response
148
+ ```
149
+
150
+ If your handler throws `NotFoundHttpError`, the request continues to standard handlers.
151
+
152
+ If your handler returns a `ResponseDescription`, the request is complete.
153
+
154
+ ### What You Can Do
155
+
156
+ - **Content moderation**: Scan uploads before they're stored
157
+ - **Rate limiting**: Track and limit requests per user
158
+ - **Virus scanning**: Check files for malware
159
+ - **Custom validation**: Enforce business rules
160
+ - **Analytics**: Log operations for analysis
161
+ - **Webhooks**: Notify external services
162
+ - **Data transformation**: Modify data before storage
163
+
164
+ ### What You Cannot Do
165
+
166
+ - Override core CSS components (GET/POST/PUT handlers, ResourceStore, etc.)
167
+ - Change the handler chain order
168
+ - Remove the extension point
169
+
170
+ ## Example: Content Moderation Plugin
171
+
172
+ ```typescript
173
+ export class ModerationHandler extends OperationHandler {
174
+ private readonly moderationClient: ModerationClient;
175
+
176
+ public constructor(moderationClient: ModerationClient) {
177
+ super();
178
+ this.moderationClient = moderationClient;
179
+ }
180
+
181
+ public async handle({ operation }: OperationHandlerInput): Promise<ResponseDescription> {
182
+ // Only moderate POST and PUT operations with content
183
+ if ((operation.method === 'POST' || operation.method === 'PUT') && operation.body) {
184
+ const result = await this.moderationClient.scan(operation.body);
185
+
186
+ if (result.isInappropriate) {
187
+ throw new ForbiddenHttpError(`Content blocked: ${result.reason}`);
188
+ }
189
+ }
190
+
191
+ // Pass to next handler
192
+ throw new NotFoundHttpError();
193
+ }
194
+ }
195
+ ```
196
+
197
+ ## Testing Your Plugin
198
+
199
+ 1. Install CSS and your plugin locally
200
+ 2. Create a test config that uses your plugin
201
+ 3. Start the server: `npm start -- -c test-config.json -f data/ -p 3000`
202
+ 4. Test operations: `curl -X POST http://localhost:3000/test -d "data"`
203
+ 5. Verify your handler is called and behaves correctly
204
+
205
+ ## Reference Implementation
206
+
207
+ See `@solid/access-token-verifier` for a complete example of a CSS plugin package.
208
+
209
+ ## Support
210
+
211
+ - CSS Documentation: https://communitysolidserver.github.io/CommunitySolidServer/
212
+ - Components.js: https://componentsjs.readthedocs.io/
213
+ - CSS Discussions: https://github.com/CommunitySolidServer/CommunitySolidServer/discussions
package/README.md CHANGED
@@ -1,11 +1,16 @@
1
- # @solid/moderation-plugin
1
+ # @kkuffour/solid-moderation-plugin
2
2
 
3
3
  Content moderation plugin for Community Solid Server using SightEngine API.
4
4
 
5
+ ## Status
6
+
7
+ ✅ **Functional** - Uses CSS ExtensionHandler pattern (v0.3.0+)
8
+
5
9
  ## Installation
6
10
 
7
11
  ```bash
8
- npm install @solid/moderation-plugin
12
+ npm install @solid/community-server
13
+ npm install @kkuffour/solid-moderation-plugin
9
14
  ```
10
15
 
11
16
  ## Configuration
@@ -13,41 +18,33 @@ npm install @solid/moderation-plugin
13
18
  Set environment variables:
14
19
 
15
20
  ```bash
16
- export SIGHTENGINE_API_USER=your_api_user
17
- export SIGHTENGINE_API_SECRET=your_api_secret
18
- ```
19
-
20
- Create a configuration file that imports the plugin:
21
-
22
- ```json
23
- {
24
- "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
25
- "import": [
26
- "css:config/file.json",
27
- "@solid/moderation-plugin:config/default.json"
28
- ]
29
- }
21
+ export SIGHTENGINE_API_USER="your_api_user"
22
+ export SIGHTENGINE_API_SECRET="your_api_secret"
30
23
  ```
31
24
 
32
- ## Usage
25
+ Run CSS with the plugin:
33
26
 
34
27
  ```bash
35
- npx @solid/community-server -c config-with-moderation.json
28
+ npx community-solid-server \
29
+ -c @css:config/file.json \
30
+ -c @kkuffour/solid-moderation-plugin:config/default.json \
31
+ -f data/ -p 3000
36
32
  ```
37
33
 
38
- ## Features
34
+ ## How It Works
35
+
36
+ The plugin uses CSS's `ExtensionHandler` pattern to intercept POST/PUT/PATCH operations before they reach storage:
39
37
 
40
- - Image moderation (nudity, violence, gore, weapons, etc.)
41
- - Text moderation (profanity, hate speech, toxic content)
42
- - Video moderation
43
- - Configurable thresholds
44
- - Audit logging
45
- - Fail-open policy (allows content if API fails)
38
+ 1. Handler runs first in the operation chain
39
+ 2. Moderates image/video/text content using SightEngine API
40
+ 3. Blocks inappropriate content with 403 Forbidden
41
+ 4. Passes approved content to standard handlers
46
42
 
47
- ## Configuration Options
43
+ ## Components
48
44
 
49
- See `config/default.json` for all available options and thresholds.
45
+ - `ModerationHandler` - OperationHandler that moderates POST/PUT/PATCH operations
46
+ - `SightEngineProvider` - SightEngine API client
50
47
 
51
48
  ## License
52
49
 
53
- MIT
50
+ MIT
@@ -1,250 +1,11 @@
1
1
  {
2
2
  "@context": [
3
- "https://linkedsoftwaredependencies.org/bundles/npm/componentsjs/^5.0.0/components/context.jsonld",
3
+ "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
4
4
  {
5
- "npmd": "https://linkedsoftwaredependencies.org/bundles/npm/",
6
- "ksmp": "npmd:@kkuffour/solid-moderation-plugin/^0.2.0/",
7
- "ModerationOperationHandler": {
8
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler",
9
- "@prefix": true,
10
- "@context": {
11
- "enabled": {
12
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_enabled"
13
- },
14
- "auditLoggingEnabled": {
15
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_auditLoggingEnabled"
16
- },
17
- "auditLoggingStorePath": {
18
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_auditLoggingStorePath"
19
- },
20
- "sightEngineApiUser": {
21
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_sightEngineApiUser"
22
- },
23
- "sightEngineApiSecret": {
24
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_sightEngineApiSecret"
25
- },
26
- "imagesEnabled": {
27
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_imagesEnabled"
28
- },
29
- "textEnabled": {
30
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textEnabled"
31
- },
32
- "videoEnabled": {
33
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_videoEnabled"
34
- },
35
- "imageNudityThreshold": {
36
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_imageNudityThreshold"
37
- },
38
- "textSexualThreshold": {
39
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textSexualThreshold"
40
- },
41
- "textToxicThreshold": {
42
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textToxicThreshold"
43
- },
44
- "videoNudityThreshold": {
45
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_videoNudityThreshold"
46
- },
47
- "source": {
48
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_source"
49
- },
50
- "": {
51
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_enabled"
52
- },
53
- "ggingEnabled": {
54
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_auditLoggingEnabled"
55
- },
56
- "ggingStorePath": {
57
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_auditLoggingStorePath"
58
- },
59
- "gineApiUser": {
60
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_sightEngineApiUser"
61
- },
62
- "gineApiSecret": {
63
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_sightEngineApiSecret"
64
- },
65
- "nabled": {
66
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_imagesEnabled"
67
- },
68
- "bled": {
69
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textEnabled"
70
- },
71
- "abled": {
72
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_videoEnabled"
73
- },
74
- "dityThreshold": {
75
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_videoNudityThreshold"
76
- },
77
- "ualThreshold": {
78
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textSexualThreshold"
79
- },
80
- "icThreshold": {
81
- "@id": "ksmp:dist/ModerationOperationHandler.jsonld#ModerationOperationHandler_textToxicThreshold"
82
- }
83
- }
84
- },
85
- "ModerationResourceStore": {
86
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore",
87
- "@prefix": true,
88
- "@context": {
89
- "enabled": {
90
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_enabled"
91
- },
92
- "imageNudityThreshold": {
93
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_imageNudityThreshold"
94
- },
95
- "textSexualThreshold": {
96
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_textSexualThreshold"
97
- },
98
- "textToxicThreshold": {
99
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_textToxicThreshold"
100
- },
101
- "videoNudityThreshold": {
102
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_videoNudityThreshold"
103
- },
104
- "client": {
105
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_client"
106
- },
107
- "source": {
108
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_source"
109
- },
110
- "": {
111
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_enabled"
112
- },
113
- "dityThreshold": {
114
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_videoNudityThreshold"
115
- },
116
- "ualThreshold": {
117
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_textSexualThreshold"
118
- },
119
- "icThreshold": {
120
- "@id": "ksmp:dist/ModerationResourceStore.jsonld#ModerationResourceStore_textToxicThreshold"
121
- }
122
- }
123
- },
124
- "ModerationConfig": {
125
- "@id": "ksmp:dist/ModerationConfig.jsonld#ModerationConfig",
126
- "@prefix": true,
127
- "@context": {}
128
- },
129
- "ModerationStore": {
130
- "@id": "ksmp:dist/ModerationStore.jsonld#ModerationStore",
131
- "@prefix": true,
132
- "@context": {
133
- "storePath": {
134
- "@id": "ksmp:dist/ModerationStore.jsonld#ModerationStore_storePath"
135
- }
136
- }
137
- },
138
- "ModerationRecord": {
139
- "@id": "ksmp:dist/ModerationRecord.jsonld#ModerationRecord",
140
- "@prefix": true,
141
- "@context": {}
142
- },
143
- "ModerationMixin": {
144
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin",
145
- "@prefix": true,
146
- "@context": {
147
- "moderationConfig_enabled": {
148
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_enabled"
149
- },
150
- "moderationConfig_auditLoggingEnabled": {
151
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_auditLoggingEnabled"
152
- },
153
- "moderationConfig_auditLoggingStorePath": {
154
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_auditLoggingStorePath"
155
- },
156
- "moderationConfig_sightEngineApiUser": {
157
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_sightEngineApiUser"
158
- },
159
- "moderationConfig_sightEngineApiSecret": {
160
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_sightEngineApiSecret"
161
- },
162
- "moderationConfig_imagesEnabled": {
163
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_imagesEnabled"
164
- },
165
- "moderationConfig_textEnabled": {
166
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textEnabled"
167
- },
168
- "moderationConfig_videoEnabled": {
169
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_videoEnabled"
170
- },
171
- "moderationConfig_imageNudityThreshold": {
172
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_imageNudityThreshold"
173
- },
174
- "moderationConfig_textSexualThreshold": {
175
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textSexualThreshold"
176
- },
177
- "moderationConfig_textToxicThreshold": {
178
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textToxicThreshold"
179
- },
180
- "moderationConfig_videoNudityThreshold": {
181
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_videoNudityThreshold"
182
- },
183
- "enabled": {
184
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_enabled"
185
- },
186
- "auditLoggingEnabled": {
187
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_auditLoggingEnabled"
188
- },
189
- "auditLoggingStorePath": {
190
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_auditLoggingStorePath"
191
- },
192
- "sightEngineApiUser": {
193
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_sightEngineApiUser"
194
- },
195
- "sightEngineApiSecret": {
196
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_sightEngineApiSecret"
197
- },
198
- "imagesEnabled": {
199
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_imagesEnabled"
200
- },
201
- "textEnabled": {
202
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textEnabled"
203
- },
204
- "videoEnabled": {
205
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_videoEnabled"
206
- },
207
- "imageNudityThreshold": {
208
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_imageNudityThreshold"
209
- },
210
- "textSexualThreshold": {
211
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textSexualThreshold"
212
- },
213
- "textToxicThreshold": {
214
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_textToxicThreshold"
215
- },
216
- "videoNudityThreshold": {
217
- "@id": "ksmp:dist/ModerationMixin.jsonld#ModerationMixin_moderationConfig_videoNudityThreshold"
218
- }
219
- }
220
- },
221
- "SightEngineProvider": {
222
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineProvider",
223
- "@prefix": true,
224
- "@context": {
225
- "apiUser": {
226
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineProvider_apiUser"
227
- },
228
- "apiSecret": {
229
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineProvider_apiSecret"
230
- }
231
- }
232
- },
233
- "SightEngineResult": {
234
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineResult",
235
- "@prefix": true,
236
- "@context": {}
237
- },
238
- "SightEngineTextResult": {
239
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineTextResult",
240
- "@prefix": true,
241
- "@context": {}
242
- },
243
- "SightEngineVideoResult": {
244
- "@id": "ksmp:dist/providers/SightEngineProvider.jsonld#SightEngineVideoResult",
245
- "@prefix": true,
246
- "@context": {}
247
- }
5
+ "ksmp": "https://linkedsoftwaredependencies.org/bundles/npm/@kkuffour/solid-moderation-plugin/",
6
+
7
+ "ModerationHandler": "ksmp:ModerationHandler",
8
+ "SightEngineProvider": "ksmp:SightEngineProvider"
248
9
  }
249
10
  ]
250
- }
11
+ }
@@ -1,39 +1,25 @@
1
1
  {
2
2
  "@context": [
3
3
  "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
4
- "https://linkedsoftwaredependencies.org/bundles/npm/@kkuffour/solid-moderation-plugin/^0.2.0/components/context.jsonld"
5
- ],
6
- "import": [
7
- "css:config/file.json"
4
+ "https://linkedsoftwaredependencies.org/bundles/npm/@kkuffour/solid-moderation-plugin/^0.3.0/components/context.jsonld"
8
5
  ],
9
6
  "@graph": [
10
7
  {
11
- "@comment": "SightEngine API client",
12
- "@id": "urn:solid-moderation:SightEngineProvider",
13
- "@type": "SightEngineProvider",
14
- "SightEngineProvider:_apiUser": "${SIGHTENGINE_API_USER}",
15
- "SightEngineProvider:_apiSecret": "${SIGHTENGINE_API_SECRET}"
8
+ "comment": "TEST: If you see this in logs, config is loaded",
9
+ "@id": "urn:solid-server:default:ExtensionHandler",
10
+ "@type": "ModerationHandler",
11
+ "ModerationHandler:_client": { "@id": "urn:moderation:SightEngineClient" },
12
+ "ModerationHandler:_enabled": true,
13
+ "ModerationHandler:_imageNudityThreshold": 0.1,
14
+ "ModerationHandler:_textSexualThreshold": 0.1,
15
+ "ModerationHandler:_textToxicThreshold": 0.1,
16
+ "ModerationHandler:_videoNudityThreshold": 0.1
16
17
  },
17
18
  {
18
- "@comment": "Original ResourceStore - renamed to avoid conflict",
19
- "@id": "urn:solid-server:default:ResourceStore_Original",
20
- "@type": "DataAccessorBasedStore",
21
- "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" },
22
- "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" },
23
- "accessor": { "@id": "urn:solid-server:default:DataAccessor" },
24
- "metadataStrategy": { "@id": "urn:solid-server:default:MetadataStrategy" }
25
- },
26
- {
27
- "@comment": "Moderation wrapper for ResourceStore",
28
- "@id": "urn:solid-server:default:ResourceStore",
29
- "@type": "ModerationResourceStore",
30
- "ModerationResourceStore:_source": { "@id": "urn:solid-server:default:ResourceStore_Original" },
31
- "ModerationResourceStore:_client": { "@id": "urn:solid-moderation:SightEngineProvider" },
32
- "ModerationResourceStore:_enabled": true,
33
- "ModerationResourceStore:_imageNudityThreshold": 0.5,
34
- "ModerationResourceStore:_textSexualThreshold": 0.5,
35
- "ModerationResourceStore:_textToxicThreshold": 0.5,
36
- "ModerationResourceStore:_videoNudityThreshold": 0.5
19
+ "@id": "urn:moderation:SightEngineClient",
20
+ "@type": "SightEngineProvider",
21
+ "SightEngineProvider:_apiUser": "@ENV:SIGHTENGINE_API_USER",
22
+ "SightEngineProvider:_apiSecret": "@ENV:SIGHTENGINE_API_SECRET"
37
23
  }
38
24
  ]
39
25
  }
@@ -0,0 +1,21 @@
1
+ import { OperationHandler } from '@solid/community-server';
2
+ import type { OperationHandlerInput, ResponseDescription } from '@solid/community-server';
3
+ import type { SightEngineProvider } from './providers/SightEngineProvider';
4
+ export declare class ModerationHandler extends OperationHandler {
5
+ private readonly logger;
6
+ private readonly client;
7
+ private readonly enabled;
8
+ private readonly imageNudityThreshold;
9
+ private readonly textSexualThreshold;
10
+ private readonly textToxicThreshold;
11
+ private readonly videoNudityThreshold;
12
+ constructor(client: SightEngineProvider, enabled: boolean, imageNudityThreshold: number, textSexualThreshold: number, textToxicThreshold: number, videoNudityThreshold: number);
13
+ handle({ operation }: OperationHandlerInput): Promise<ResponseDescription>;
14
+ private shouldModerate;
15
+ private isModeratable;
16
+ private moderateImage;
17
+ private moderateVideo;
18
+ private moderateText;
19
+ private getFileExtension;
20
+ }
21
+ //# sourceMappingURL=ModerationHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModerationHandler.d.ts","sourceRoot":"","sources":["../src/ModerationHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA0E,MAAM,yBAAyB,CAAC;AACnI,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,qBAAa,iBAAkB,SAAQ,gBAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;gBAG5C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,OAAO,EAChB,oBAAoB,EAAE,MAAM,EAC5B,mBAAmB,EAAE,MAAM,EAC3B,kBAAkB,EAAE,MAAM,EAC1B,oBAAoB,EAAE,MAAM;IAejB,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwDvF,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;YAMP,aAAa;YAyBb,aAAa;YAyBb,YAAY;IAyB1B,OAAO,CAAC,gBAAgB;CAWzB"}