@sockethub/platform-irc 4.0.0-alpha.11 → 4.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@ This platform provides IRC client functionality, allowing web applications to co
8
8
  IRC servers, join channels, send messages, and handle IRC events through ActivityStreams
9
9
  messages.
10
10
 
11
- ## Implemented Verbs (`@type`)
11
+ ## Implemented Verbs (`type`)
12
12
 
13
13
  * **send** - Send messages to channels or users
14
14
  * **join** - Join IRC channels
@@ -22,16 +22,22 @@ messages.
22
22
 
23
23
  ```json
24
24
  {
25
- "@type": "send",
26
- "context": "irc",
25
+ "type": "send",
26
+ "@context": [
27
+ "https://www.w3.org/ns/activitystreams",
28
+ "https://sockethub.org/ns/context/v1.jsonld",
29
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
30
+ ],
27
31
  "actor": {
28
- "@id": "mynick@irc.libera.chat"
32
+ "id": "mynick@irc.libera.chat",
33
+ "type": "person"
29
34
  },
30
35
  "target": {
31
- "@id": "#general@irc.libera.chat"
36
+ "id": "#general@irc.libera.chat",
37
+ "type": "room"
32
38
  },
33
39
  "object": {
34
- "@type": "Note",
40
+ "type": "message",
35
41
  "content": "Hello IRC channel!"
36
42
  }
37
43
  }
@@ -41,13 +47,19 @@ messages.
41
47
 
42
48
  ```json
43
49
  {
44
- "@type": "join",
45
- "context": "irc",
50
+ "type": "join",
51
+ "@context": [
52
+ "https://www.w3.org/ns/activitystreams",
53
+ "https://sockethub.org/ns/context/v1.jsonld",
54
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
55
+ ],
46
56
  "actor": {
47
- "@id": "mynick@irc.libera.chat"
57
+ "id": "mynick@irc.libera.chat",
58
+ "type": "person"
48
59
  },
49
60
  "target": {
50
- "@id": "#general@irc.libera.chat"
61
+ "id": "#general@irc.libera.chat",
62
+ "type": "room"
51
63
  }
52
64
  }
53
65
  ```
@@ -56,21 +68,245 @@ messages.
56
68
 
57
69
  ```json
58
70
  {
59
- "@type": "send",
60
- "context": "irc",
71
+ "type": "send",
72
+ "@context": [
73
+ "https://www.w3.org/ns/activitystreams",
74
+ "https://sockethub.org/ns/context/v1.jsonld",
75
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
76
+ ],
61
77
  "actor": {
62
- "@id": "mynick@irc.libera.chat"
78
+ "id": "mynick@irc.libera.chat",
79
+ "type": "person"
63
80
  },
64
81
  "target": {
65
- "@id": "friend@irc.libera.chat"
82
+ "id": "friend@irc.libera.chat",
83
+ "type": "person"
66
84
  },
67
85
  "object": {
68
- "@type": "Note",
86
+ "type": "message",
69
87
  "content": "Hello friend!"
70
88
  }
71
89
  }
72
90
  ```
73
91
 
92
+ ### Update Topic Example
93
+
94
+ ```json
95
+ {
96
+ "type": "update",
97
+ "@context": [
98
+ "https://www.w3.org/ns/activitystreams",
99
+ "https://sockethub.org/ns/context/v1.jsonld",
100
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
101
+ ],
102
+ "actor": {
103
+ "id": "mynick@irc.libera.chat",
104
+ "type": "person"
105
+ },
106
+ "target": {
107
+ "id": "#general@irc.libera.chat",
108
+ "type": "room"
109
+ },
110
+ "object": {
111
+ "type": "topic",
112
+ "content": "New channel topic"
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### Update Nickname Example
118
+
119
+ ```json
120
+ {
121
+ "type": "update",
122
+ "@context": [
123
+ "https://www.w3.org/ns/activitystreams",
124
+ "https://sockethub.org/ns/context/v1.jsonld",
125
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
126
+ ],
127
+ "actor": {
128
+ "id": "mynick@irc.libera.chat",
129
+ "type": "person"
130
+ },
131
+ "target": {
132
+ "id": "newnick@irc.libera.chat",
133
+ "type": "person"
134
+ },
135
+ "object": {
136
+ "type": "address"
137
+ }
138
+ }
139
+ ```
140
+
141
+ ### Query Attendance Example
142
+
143
+ ```json
144
+ {
145
+ "type": "query",
146
+ "@context": [
147
+ "https://www.w3.org/ns/activitystreams",
148
+ "https://sockethub.org/ns/context/v1.jsonld",
149
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
150
+ ],
151
+ "actor": {
152
+ "id": "mynick@irc.libera.chat",
153
+ "type": "person"
154
+ },
155
+ "target": {
156
+ "id": "#general@irc.libera.chat",
157
+ "type": "room"
158
+ },
159
+ "object": {
160
+ "type": "attendance"
161
+ }
162
+ }
163
+ ```
164
+
165
+ ### Query Attendance Response Example
166
+
167
+ ```json
168
+ {
169
+ "type": "query",
170
+ "@context": [
171
+ "https://www.w3.org/ns/activitystreams",
172
+ "https://sockethub.org/ns/context/v1.jsonld",
173
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
174
+ ],
175
+ "actor": {
176
+ "id": "#general@irc.libera.chat",
177
+ "type": "room"
178
+ },
179
+ "target": {},
180
+ "object": {
181
+ "type": "attendance",
182
+ "members": ["alice", "bob", "carol"]
183
+ }
184
+ }
185
+ ```
186
+
187
+ ### Disconnect Example
188
+
189
+ ```json
190
+ {
191
+ "type": "disconnect",
192
+ "@context": [
193
+ "https://www.w3.org/ns/activitystreams",
194
+ "https://sockethub.org/ns/context/v1.jsonld",
195
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
196
+ ],
197
+ "actor": {
198
+ "id": "mynick@irc.libera.chat",
199
+ "type": "person"
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## Authentication
205
+
206
+ Authenticated connections use SASL. Two mechanisms are supported:
207
+
208
+ * **`PLAIN`** — sends a username and secret via SASL PLAIN. This is the
209
+ default mechanism, and is supported by most IRC networks (Libera.Chat,
210
+ OFTC, etc.). Both `password` and `token` use PLAIN by default. Use
211
+ `token` for personal access tokens (e.g. Libera.Chat NickServ tokens)
212
+ to avoid storing primary account passwords.
213
+ * **`OAUTHBEARER`** — sends an OAuth 2.0 access token instead of a password
214
+ ([RFC 7628](https://datatracker.ietf.org/doc/html/rfc7628)). Requires
215
+ `saslMechanism: "OAUTHBEARER"` to be set explicitly. Adoption on
216
+ public IRC networks is still limited; the main deployment is SourceHut's
217
+ `chat.sr.ht` (via the [soju](https://soju.im/) bouncer). Major networks
218
+ such as Libera.Chat, OFTC, and Hackint do not currently advertise
219
+ OAUTHBEARER. See emersion's [IRC × OAuth 2.0](https://emersion.fr/blog/2022/irc-and-oauth2/)
220
+ writeup for background. How to obtain the token is provider-specific and
221
+ outside the scope of this module.
222
+
223
+ `password` and `token` are mutually exclusive. Both default to SASL PLAIN;
224
+ set `saslMechanism: "OAUTHBEARER"` explicitly for OAuth 2.0 bearer tokens.
225
+ Secure connections validate the IRC server's TLS certificate by default. The
226
+ optional `allowInvalidCert` field defaults to `false`; when set to `true`, it
227
+ disables TLS certificate validation for secure connections. Use this
228
+ security-relevant opt-out only for trusted self-signed IRC networks.
229
+
230
+ ### Credentials with password (SASL PLAIN)
231
+
232
+ ```json
233
+ {
234
+ "type": "credentials",
235
+ "@context": [
236
+ "https://www.w3.org/ns/activitystreams",
237
+ "https://sockethub.org/ns/context/v1.jsonld",
238
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
239
+ ],
240
+ "actor": {
241
+ "id": "mynick@irc.libera.chat",
242
+ "type": "person"
243
+ },
244
+ "object": {
245
+ "type": "credentials",
246
+ "nick": "mynick",
247
+ "server": "irc.libera.chat",
248
+ "password": "secret",
249
+ "port": 6697,
250
+ "secure": true
251
+ }
252
+ }
253
+ ```
254
+
255
+ ### Credentials with personal access token (SASL PLAIN)
256
+
257
+ Networks like Libera.Chat accept NickServ personal access tokens via
258
+ SASL PLAIN. Use the `token` field instead of `password` to make the
259
+ distinction clear:
260
+
261
+ ```json
262
+ {
263
+ "type": "credentials",
264
+ "@context": [
265
+ "https://www.w3.org/ns/activitystreams",
266
+ "https://sockethub.org/ns/context/v1.jsonld",
267
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
268
+ ],
269
+ "actor": {
270
+ "id": "mynick@irc.libera.chat",
271
+ "type": "person"
272
+ },
273
+ "object": {
274
+ "type": "credentials",
275
+ "nick": "mynick",
276
+ "server": "irc.libera.chat",
277
+ "token": "my-personal-access-token",
278
+ "port": 6697,
279
+ "secure": true
280
+ }
281
+ }
282
+ ```
283
+
284
+ ### Credentials with OAuth token (SASL OAUTHBEARER)
285
+
286
+ ```json
287
+ {
288
+ "type": "credentials",
289
+ "@context": [
290
+ "https://www.w3.org/ns/activitystreams",
291
+ "https://sockethub.org/ns/context/v1.jsonld",
292
+ "https://sockethub.org/ns/context/platform/irc/v1.jsonld"
293
+ ],
294
+ "actor": {
295
+ "id": "mynick@chat.sr.ht",
296
+ "type": "person"
297
+ },
298
+ "object": {
299
+ "type": "credentials",
300
+ "nick": "mynick",
301
+ "server": "chat.sr.ht",
302
+ "token": "oauth-access-token",
303
+ "saslMechanism": "OAUTHBEARER",
304
+ "port": 6697,
305
+ "secure": true
306
+ }
307
+ }
308
+ ```
309
+
74
310
  ## Features
75
311
 
76
312
  * **Channel communication**: Join and participate in IRC channels
@@ -88,4 +324,5 @@ messages.
88
324
 
89
325
  ## API
90
326
 
91
- Detailed API documentation can be found [here](API.md)
327
+ API reference docs are generated from the source JSDoc and are not committed to this repository.
328
+ Run `bun run doc` in this package to generate them locally.
@@ -0,0 +1,136 @@
1
+ /**
2
+ * This is a platform for Sockethub implementing IRC functionality.
3
+ *
4
+ * Developed by Nick Jennings (https://github.com/silverbucket)
5
+ *
6
+ * Sockethub is licensed under the LGPLv3.
7
+ * See the LICENSE file for details.
8
+ *
9
+ * The latest version of this module can be found here:
10
+ * git://github.com/sockethub/sockethub.git
11
+ *
12
+ * For more information about Sockethub visit http://sockethub.org/.
13
+ *
14
+ * This program is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
+ */
18
+ import type { ActivityStream, PersistentPlatformConfig, PersistentPlatformInterface, PlatformCallback, PlatformSchemaStruct, PlatformSession } from "@sockethub/schemas";
19
+ import { type IrcSocketInstance } from "irc-socket-sasl";
20
+ import type { PlatformIrcCredentialsObject } from "./types.js";
21
+ export type { IrcSocketInstance } from "irc-socket-sasl";
22
+ export type { PlatformIrcCredentialsObject } from "./types.js";
23
+ export declare function flattenConnectOptions(options: Record<string, unknown>): Record<string, unknown>;
24
+ export type GetClientCallback = (err: string | null, client?: IrcSocketInstance) => void;
25
+ /**
26
+ * Handles all actions related to communication via the IRC protocol.
27
+ */
28
+ export declare class IRC implements PersistentPlatformInterface {
29
+ private readonly log;
30
+ credentialsHash: string | undefined;
31
+ config: PersistentPlatformConfig;
32
+ private readonly updateActor;
33
+ private readonly sendToClient;
34
+ private irc2as;
35
+ private forceDisconnect;
36
+ private clientConnecting;
37
+ private initialized;
38
+ private client?;
39
+ private jobQueue;
40
+ private channels;
41
+ private handledActors;
42
+ constructor(session: PlatformSession);
43
+ /**
44
+ * JSON schema defining the types this platform accepts.
45
+ *
46
+ * `password` and `token` are mutually exclusive. Both default to SASL
47
+ * PLAIN; set `saslMechanism: 'OAUTHBEARER'` explicitly for OAuth 2.0
48
+ * bearer tokens (RFC 7628). See the package README for canonical
49
+ * credentials payload examples.
50
+ */
51
+ get schema(): PlatformSchemaStruct;
52
+ /**
53
+ * Returns whether the platform is ready to handle jobs.
54
+ * For IRC, this means we have successfully connected to the server.
55
+ */
56
+ isInitialized(): boolean;
57
+ /**
58
+ * Function: connect
59
+ *
60
+ * Connect to an IRC server.
61
+ *
62
+ * @param {object} job activity streams object
63
+ * @param {object} credentials credentials object
64
+ * @param {object} done callback when job is done
65
+ */
66
+ connect(job: ActivityStream, credentials: PlatformIrcCredentialsObject, done: PlatformCallback): void;
67
+ /**
68
+ * Function: join
69
+ *
70
+ * Join a room or private conversation.
71
+ *
72
+ * @param {object} job activity streams object
73
+ * @param {object} done callback when job is done
74
+ */
75
+ join(job: ActivityStream, done: PlatformCallback): void;
76
+ /**
77
+ * Function leave
78
+ *
79
+ * Leave a room or private conversation.
80
+ *
81
+ * @param {object} job activity streams object
82
+ * @param {object} done callback when job is done
83
+ */
84
+ leave(job: ActivityStream, done: PlatformCallback): void;
85
+ /**
86
+ * Function: send
87
+ *
88
+ * Send a message to a room or private conversation.
89
+ *
90
+ * @param {object} job activity streams object
91
+ * @param {object} done callback when job is done
92
+ */
93
+ send(job: ActivityStream, done: PlatformCallback): void;
94
+ /**
95
+ * Function: update
96
+ *
97
+ * Indicate a change (i.e. room topic update, or nickname change).
98
+ *
99
+ * @param {object} job activity streams object
100
+ * @param {object} credentials credentials to verify this user is the right one
101
+ * @param {object} done callback when job is done
102
+ */
103
+ update(job: ActivityStream, credentials: PlatformIrcCredentialsObject, done: PlatformCallback): void;
104
+ /**
105
+ * Function: query
106
+ *
107
+ * Indicate an intent to query something (e.g. get a list of users in a room).
108
+ *
109
+ * @param {object} job activity streams object
110
+ * @param {object} done callback when job is done
111
+ */
112
+ query(job: ActivityStream, done: PlatformCallback): void;
113
+ /**
114
+ * Disconnect IRC client
115
+ * @param {object} job activity streams object
116
+ * @param done
117
+ */
118
+ disconnect(job: ActivityStream, done: PlatformCallback): void;
119
+ cleanup(done: PlatformCallback): any;
120
+ /**
121
+ * Resolve an IRC channel name from a job target. Prefers `target.name`,
122
+ * falling back to the channel segment of `target.id` (`<server>/<channel>`).
123
+ * Returns undefined when no valid `#channel` can be determined, so callers
124
+ * never emit a bare `NAMES` command (which floods the client with the
125
+ * server's entire channel list).
126
+ */
127
+ private resolveChannelName;
128
+ private isJoined;
129
+ private hasJoined;
130
+ private hasLeft;
131
+ private getClient;
132
+ private ircConnect;
133
+ private completeJob;
134
+ private registerListeners;
135
+ }
136
+ export default IRC;