@sockethub/platform-irc 4.0.0-alpha.12 → 4.0.0-alpha.14

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/dist/index.js CHANGED
@@ -4574,6 +4574,7 @@ var require_limitLength = __commonJS((exports) => {
4574
4574
  var require_pattern = __commonJS((exports) => {
4575
4575
  Object.defineProperty(exports, "__esModule", { value: true });
4576
4576
  var code_1 = require_code2();
4577
+ var util_1 = require_util();
4577
4578
  var codegen_1 = require_codegen();
4578
4579
  var error = {
4579
4580
  message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
@@ -4586,10 +4587,18 @@ var require_pattern = __commonJS((exports) => {
4586
4587
  $data: true,
4587
4588
  error,
4588
4589
  code(cxt) {
4589
- const { data, $data, schema, schemaCode, it } = cxt;
4590
+ const { gen, data, $data, schema, schemaCode, it } = cxt;
4590
4591
  const u = it.opts.unicodeRegExp ? "u" : "";
4591
- const regExp = $data ? (0, codegen_1._)`(new RegExp(${schemaCode}, ${u}))` : (0, code_1.usePattern)(cxt, schema);
4592
- cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
4592
+ if ($data) {
4593
+ const { regExp } = it.opts.code;
4594
+ const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._)`new RegExp` : (0, util_1.useFunc)(gen, regExp);
4595
+ const valid = gen.let("valid");
4596
+ gen.try(() => gen.assign(valid, (0, codegen_1._)`${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
4597
+ cxt.fail$data((0, codegen_1._)`!${valid}`);
4598
+ } else {
4599
+ const regExp = (0, code_1.usePattern)(cxt, schema);
4600
+ cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
4601
+ }
4593
4602
  }
4594
4603
  };
4595
4604
  exports.default = def;
@@ -15749,22 +15758,22 @@ var require_ajv_formats_draft2019 = __commonJS((exports, module) => {
15749
15758
  };
15750
15759
  });
15751
15760
 
15752
- // ../../node_modules/r-result/result.js
15761
+ // ../../node_modules/irc-socket-sasl/result.js
15753
15762
  var require_result = __commonJS((exports, module) => {
15754
15763
  var inspect = __require("util").inspect;
15755
15764
  var Ok = function(t) {
15756
- const Result = Object.create(methods);
15765
+ const Result = Object.create(resultMethods);
15757
15766
  Result.is_ok = true;
15758
15767
  Result.value = t;
15759
15768
  return Result;
15760
15769
  };
15761
15770
  var Fail = function(f) {
15762
- const Result = Object.create(methods);
15771
+ const Result = Object.create(resultMethods);
15763
15772
  Result.is_ok = false;
15764
15773
  Result.value = f;
15765
15774
  return Result;
15766
15775
  };
15767
- var methods = {
15776
+ var resultMethods = {
15768
15777
  ok: function(errorMessage) {
15769
15778
  if (this.is_ok) {
15770
15779
  return this.value;
@@ -15899,29 +15908,13 @@ var require_result = __commonJS((exports, module) => {
15899
15908
  Ok,
15900
15909
  Fail
15901
15910
  };
15902
- var methodToFunction = function(method) {
15903
- return function() {
15904
- var context = arguments[0];
15905
- var args = Array.prototype.slice.call(arguments, 1);
15906
- return method.apply(context, args);
15907
- };
15908
- };
15909
- Object.keys(methods).forEach(function(key) {
15910
- if (key === "inspect") {
15911
- return;
15912
- }
15913
- var method = methods[key];
15914
- module.exports[key] = methodToFunction(method);
15915
- });
15916
15911
  });
15917
15912
 
15918
15913
  // ../../node_modules/irc-socket-sasl/irc-socket.js
15919
15914
  var require_irc_socket = __commonJS((exports, module) => {
15920
15915
  var EventEmitter = __require("events").EventEmitter;
15921
15916
  var format = __require("util").format;
15922
- var rresult = require_result();
15923
- var Ok = rresult.Ok;
15924
- var Fail = rresult.Fail;
15917
+ var { Ok, Fail } = require_result();
15925
15918
  var includes = function(array, value) {
15926
15919
  return array.indexOf(value) !== -1;
15927
15920
  };
@@ -15934,13 +15927,20 @@ var require_irc_socket = __commonJS((exports, module) => {
15934
15927
  var endsWith = function(string, postfix) {
15935
15928
  return string.lastIndexOf(postfix) === string.length - postfix.length;
15936
15929
  };
15930
+ var encodeSaslCredential = function(mechanism, username, secret) {
15931
+ if (mechanism === "OAUTHBEARER") {
15932
+ return Buffer.from("n,,\x01auth=Bearer " + secret + "\x01\x01").toString("base64");
15933
+ }
15934
+ return Buffer.from(username + "\x00" + username + "\x00" + secret).toString("base64");
15935
+ };
15937
15936
  var failures = {
15938
15937
  killed: "killed",
15939
15938
  nicknamesUnavailable: "nicknames unavailable",
15940
15939
  badProxyConfiguration: "bad proxy configuration",
15941
15940
  missingRequiredCapabilities: "missing required capabilities",
15942
15941
  badPassword: "bad password",
15943
- socketEnded: "socket ended"
15942
+ socketEnded: "socket ended",
15943
+ saslAuthenticationFailed: "sasl authentication failed"
15944
15944
  };
15945
15945
 
15946
15946
  class IrcSocket extends EventEmitter {
@@ -15965,12 +15965,16 @@ var require_irc_socket = __commonJS((exports, module) => {
15965
15965
  if (config.saslPassword) {
15966
15966
  this.saslUsername = config.saslUsername || config.username;
15967
15967
  this.saslPassword = config.saslPassword;
15968
+ this.saslMechanism = (config.saslMechanism || "PLAIN").toUpperCase();
15969
+ if (this.saslMechanism !== "PLAIN" && this.saslMechanism !== "OAUTHBEARER") {
15970
+ throw new Error("Unsupported SASL mechanism: " + config.saslMechanism);
15971
+ }
15968
15972
  }
15969
15973
  this.username = config.username;
15970
15974
  this.realname = config.realname;
15971
15975
  this.nicknames = config.nicknames.slice();
15972
15976
  this.timeout = config.timeout || 5 * 60 * 1000;
15973
- this.connectOptions = typeof config.connectOptions === "object" ? Object.create(config.connectOptions) : {};
15977
+ this.connectOptions = typeof config.connectOptions === "object" && config.connectOptions !== null ? { ...config.connectOptions } : {};
15974
15978
  this.connectOptions.port = config.port || 6667;
15975
15979
  this.connectOptions.host = config.server;
15976
15980
  this.on("data", function(line) {
@@ -16017,6 +16021,8 @@ var require_irc_socket = __commonJS((exports, module) => {
16017
16021
  this.emit("connect");
16018
16022
  timeout = setTimeout(onSilence, timeoutPeriod);
16019
16023
  let serverCapabilities, acknowledgedCapabilities, sentRequests, respondedRequests, allRequestsSent, nickname;
16024
+ let saslResponseSent = false;
16025
+ let saslChallenge = "";
16020
16026
  if (this.capabilities) {
16021
16027
  this.capabilities.requires = this.capabilities.requires || [];
16022
16028
  this.capabilities.wants = this.capabilities.wants || [];
@@ -16086,7 +16092,7 @@ var require_irc_socket = __commonJS((exports, module) => {
16086
16092
  acknowledgedCapabilities.push(capability);
16087
16093
  }
16088
16094
  if (acknowledgedCapabilities.includes("sasl")) {
16089
- this.raw(["AUTHENTICATE", "PLAIN"]);
16095
+ this.raw(["AUTHENTICATE", this.saslMechanism || "PLAIN"]);
16090
16096
  }
16091
16097
  }
16092
16098
  if (sentRequests === respondedRequests) {
@@ -16100,13 +16106,48 @@ var require_irc_socket = __commonJS((exports, module) => {
16100
16106
  if (endsWith(line, "Login unsuccessful")) {
16101
16107
  this.resolvePromise(Fail(failures.badPassword));
16102
16108
  }
16103
- } else if (parts[0] === "AUTHENTICATE") {
16104
- if (parts[1] === "+") {
16105
- const encPW = Buffer.from(this.saslUsername + "\x00" + this.saslUsername + "\x00" + this.saslPassword).toString("base64");
16106
- this.raw(["AUTHENTICATE", encPW]);
16109
+ } else if (parts[0] === "AUTHENTICATE" || numeric === "AUTHENTICATE") {
16110
+ const chunkSize = 400;
16111
+ const authArg = numeric === "AUTHENTICATE" ? parts[2] : parts[1];
16112
+ if (!saslResponseSent) {
16113
+ if (authArg !== "+") {
16114
+ return;
16115
+ }
16116
+ const payload = encodeSaslCredential(this.saslMechanism, this.saslUsername, this.saslPassword);
16117
+ if (payload.length === 0) {
16118
+ this.raw(["AUTHENTICATE", "+"]);
16119
+ } else {
16120
+ for (let i = 0;i < payload.length; i += chunkSize) {
16121
+ this.raw(["AUTHENTICATE", payload.slice(i, i + chunkSize)]);
16122
+ }
16123
+ if (payload.length % chunkSize === 0) {
16124
+ this.raw(["AUTHENTICATE", "+"]);
16125
+ }
16126
+ }
16127
+ saslResponseSent = true;
16128
+ } else {
16129
+ let challengeComplete = false;
16130
+ if (authArg === "+") {
16131
+ challengeComplete = true;
16132
+ } else {
16133
+ saslChallenge += authArg;
16134
+ if (authArg.length < chunkSize) {
16135
+ challengeComplete = true;
16136
+ }
16137
+ }
16138
+ if (challengeComplete) {
16139
+ saslChallenge = "";
16140
+ if (this.saslMechanism === "OAUTHBEARER") {
16141
+ this.raw(["AUTHENTICATE", "AQ=="]);
16142
+ }
16143
+ }
16107
16144
  }
16108
16145
  } else if (numeric === "903") {
16109
16146
  this.raw("CAP END");
16147
+ } else if (numeric === "902" || numeric === "904" || numeric === "905" || numeric === "906" || numeric === "907") {
16148
+ this.raw("QUIT");
16149
+ this.resolvePromise(Fail(failures.saslAuthenticationFailed));
16150
+ return;
16110
16151
  } else if (numeric === "001") {
16111
16152
  this.status = "running";
16112
16153
  const data = {
@@ -16251,7 +16292,7 @@ class ASEmitter {
16251
16292
  }
16252
16293
  emitEvent(code, asObject) {
16253
16294
  if (typeof asObject === "object" && !asObject.published) {
16254
- asObject.published = `${Date.now()}`;
16295
+ asObject.published = new Date().toISOString();
16255
16296
  }
16256
16297
  this.events.emit(code, asObject);
16257
16298
  }
@@ -16698,7 +16739,7 @@ class IrcToActivityStreams {
16698
16739
  }
16699
16740
  };
16700
16741
  break;
16701
- case TOPIC_SET_BY:
16742
+ case TOPIC_SET_BY: {
16702
16743
  if (!this.__buffer[TOPIC_IS]) {
16703
16744
  break;
16704
16745
  }
@@ -16708,10 +16749,14 @@ class IrcToActivityStreams {
16708
16749
  id: `${nick}@${this.server}`,
16709
16750
  name: nick
16710
16751
  };
16711
- this.__buffer[TOPIC_IS].published = msg[0];
16752
+ const topicSetEpochSeconds = Number.parseInt(msg[0], 10);
16753
+ if (Number.isFinite(topicSetEpochSeconds)) {
16754
+ this.__buffer[TOPIC_IS].published = new Date(topicSetEpochSeconds * 1000).toISOString();
16755
+ }
16712
16756
  ase.emitEvent(EVENT_INCOMING2, this.__buffer[TOPIC_IS]);
16713
16757
  delete this.__buffer[TOPIC_IS];
16714
16758
  break;
16759
+ }
16715
16760
  case WHO:
16716
16761
  case WHO_OLD:
16717
16762
  nick = msg[3].length <= 2 ? msg[2] : msg[3];
@@ -16731,6 +16776,7 @@ class IrcToActivityStreams {
16731
16776
  // ../schemas/src/context.ts
16732
16777
  var AS2_BASE_CONTEXT_URL = "https://www.w3.org/ns/activitystreams";
16733
16778
  var SOCKETHUB_BASE_CONTEXT_URL = "https://sockethub.org/ns/context/v1.jsonld";
16779
+ var PLATFORM_CONTEXT_PREFIX = "https://sockethub.org/ns/context/platform/";
16734
16780
  var ERROR_PLATFORM_ID = "error";
16735
16781
  var ERROR_PLATFORM_CONTEXT_URL = "https://sockethub.org/ns/context/platform/error/v1.jsonld";
16736
16782
  var INTERNAL_PLATFORM_ID = "sockethub:internal";
@@ -16738,12 +16784,9 @@ var INTERNAL_PLATFORM_CONTEXT_URL = "https://sockethub.org/ns/context/platform/s
16738
16784
  var platformContextToPlatformId = new Map;
16739
16785
  var platformContextToSchemaId = new Map;
16740
16786
  var platformContextToCredentialsSchemaId = new Map;
16741
- function buildCanonicalContext(platformContextUrl) {
16742
- return [
16743
- AS2_BASE_CONTEXT_URL,
16744
- SOCKETHUB_BASE_CONTEXT_URL,
16745
- platformContextUrl
16746
- ];
16787
+ function buildCanonicalContext(platform) {
16788
+ const platformUrl = platform.startsWith("https://") ? platform : `${PLATFORM_CONTEXT_PREFIX}${platform}/v1.jsonld`;
16789
+ return [AS2_BASE_CONTEXT_URL, SOCKETHUB_BASE_CONTEXT_URL, platformUrl];
16747
16790
  }
16748
16791
  function registerPlatformContext(platformId, platformContextUrl, schemaId, credentialsSchemaId) {
16749
16792
  platformContextToPlatformId.set(platformContextUrl, platformId);
@@ -16752,18 +16795,7 @@ function registerPlatformContext(platformId, platformContextUrl, schemaId, crede
16752
16795
  }
16753
16796
 
16754
16797
  // ../schemas/src/helpers/objects.ts
16755
- var validObjectRefs = [];
16756
- var validObjectDefs = {};
16757
16798
  var ObjectTypesSchema = {
16758
- credentials: {
16759
- required: ["type"],
16760
- additionalProperties: true,
16761
- properties: {
16762
- type: {
16763
- enum: ["credentials"]
16764
- }
16765
- }
16766
- },
16767
16799
  feed: {
16768
16800
  required: ["id", "type"],
16769
16801
  additionalProperties: true,
@@ -16789,36 +16821,6 @@ var ObjectTypesSchema = {
16789
16821
  }
16790
16822
  }
16791
16823
  },
16792
- message: {
16793
- required: ["type", "content"],
16794
- additionalProperties: true,
16795
- properties: {
16796
- type: {
16797
- enum: ["message"]
16798
- },
16799
- id: {
16800
- type: "string"
16801
- },
16802
- name: {
16803
- type: "string"
16804
- },
16805
- content: {
16806
- type: "string"
16807
- }
16808
- }
16809
- },
16810
- me: {
16811
- required: ["type", "content"],
16812
- additionalProperties: true,
16813
- properties: {
16814
- type: {
16815
- enum: ["me"]
16816
- },
16817
- content: {
16818
- type: "string"
16819
- }
16820
- }
16821
- },
16822
16824
  person: {
16823
16825
  required: ["id", "type"],
16824
16826
  additionalProperties: true,
@@ -16895,71 +16897,6 @@ var ObjectTypesSchema = {
16895
16897
  }
16896
16898
  }
16897
16899
  },
16898
- attendance: {
16899
- required: ["type"],
16900
- additionalProperties: false,
16901
- properties: {
16902
- type: {
16903
- enum: ["attendance"]
16904
- },
16905
- members: {
16906
- type: "array",
16907
- items: {
16908
- type: "string"
16909
- }
16910
- }
16911
- }
16912
- },
16913
- presence: {
16914
- required: ["type"],
16915
- additionalProperties: false,
16916
- properties: {
16917
- type: {
16918
- enum: ["presence"]
16919
- },
16920
- presence: {
16921
- enum: ["away", "chat", "dnd", "xa", "offline", "online"]
16922
- },
16923
- role: {
16924
- enum: ["owner", "member", "participant", "admin"]
16925
- },
16926
- content: {
16927
- type: "string"
16928
- }
16929
- }
16930
- },
16931
- relationship: {
16932
- required: ["type", "relationship"],
16933
- additionalProperties: false,
16934
- properties: {
16935
- type: {
16936
- enum: ["relationship"]
16937
- },
16938
- relationship: {
16939
- enum: ["role"]
16940
- },
16941
- subject: {
16942
- type: "object",
16943
- oneOf: [{ $ref: "#/definitions/type/presence" }]
16944
- },
16945
- object: {
16946
- type: "object",
16947
- oneOf: validObjectRefs
16948
- }
16949
- }
16950
- },
16951
- topic: {
16952
- required: ["type"],
16953
- additionalProperties: false,
16954
- properties: {
16955
- type: {
16956
- enum: ["topic"]
16957
- },
16958
- content: {
16959
- type: "string"
16960
- }
16961
- }
16962
- },
16963
16900
  address: {
16964
16901
  required: ["type"],
16965
16902
  additionalProperties: false,
@@ -16968,18 +16905,6 @@ var ObjectTypesSchema = {
16968
16905
  enum: ["address"]
16969
16906
  }
16970
16907
  }
16971
- },
16972
- heartbeat: {
16973
- required: ["type", "timestamp"],
16974
- additionalProperties: false,
16975
- properties: {
16976
- type: {
16977
- enum: ["heartbeat"]
16978
- },
16979
- timestamp: {
16980
- type: "number"
16981
- }
16982
- }
16983
16908
  }
16984
16909
  };
16985
16910
  var ObjectTypesList = Object.keys(ObjectTypesSchema);
@@ -17006,36 +16931,8 @@ var validActorRefs = ActorTypesList.map((type) => ({
17006
16931
  var validTargetRefs = TargetTypesList.map((type) => ({
17007
16932
  $ref: `#/definitions/type/${type}`
17008
16933
  }));
17009
- for (const type of ObjectTypesList) {
17010
- if (type === "credentials") {
17011
- continue;
17012
- }
17013
- validObjectRefs.push({ $ref: `#/definitions/type/${type}` });
17014
- validObjectDefs[type] = ObjectTypesSchema[type];
17015
- }
17016
-
17017
- // ../schemas/src/schemas/activity-object.ts
17018
- var ActivityObjectSchema = {
17019
- $id: "https://sockethub.org/schemas/v/activity-object.json",
17020
- description: "Schema for Sockethub Activity Objects",
17021
- type: "object",
17022
- required: ["object"],
17023
- properties: {
17024
- object: {
17025
- type: "object",
17026
- oneOf: validObjectRefs
17027
- }
17028
- },
17029
- definitions: {
17030
- type: validObjectDefs
17031
- }
17032
- };
17033
16934
 
17034
16935
  // ../schemas/src/schemas/activity-stream.ts
17035
- var validObjectRefs2 = [];
17036
- for (const type of ObjectTypesList) {
17037
- validObjectRefs2.push({ $ref: `#/definitions/type/${type}` });
17038
- }
17039
16936
  var contextSchema = {
17040
16937
  type: "array",
17041
16938
  minItems: 3,
@@ -17064,6 +16961,7 @@ var ActivityStreamSchema = {
17064
16961
  description: "Schema for Sockethub Activity Streams",
17065
16962
  type: "object",
17066
16963
  required: ["@context", "type", "actor"],
16964
+ additionalProperties: false,
17067
16965
  properties: {
17068
16966
  "@context": contextSchema,
17069
16967
  id: {
@@ -17079,8 +16977,7 @@ var ActivityStreamSchema = {
17079
16977
  oneOf: validTargetRefs
17080
16978
  },
17081
16979
  object: {
17082
- type: "object",
17083
- oneOf: validObjectRefs2
16980
+ type: "object"
17084
16981
  },
17085
16982
  published: {
17086
16983
  type: "string",
@@ -17093,11 +16990,6 @@ var ActivityStreamSchema = {
17093
16990
  };
17094
16991
 
17095
16992
  // ../schemas/src/schemas/sockethub-config.ts
17096
- var connectConfigPlatforms = {
17097
- connectTimeoutMs: {
17098
- type: "number"
17099
- }
17100
- };
17101
16993
  var SockethubConfigSchema = {
17102
16994
  $id: "https://sockethub.org/schemas/v/sockethub-config.json",
17103
16995
  description: "Sockethub Config Schema",
@@ -17112,6 +17004,10 @@ var SockethubConfigSchema = {
17112
17004
  type: "boolean",
17113
17005
  default: true
17114
17006
  },
17007
+ info: {
17008
+ type: "boolean",
17009
+ default: false
17010
+ },
17115
17011
  logging: {
17116
17012
  type: "object",
17117
17013
  additionalProperties: false,
@@ -17132,71 +17028,88 @@ var SockethubConfigSchema = {
17132
17028
  }
17133
17029
  }
17134
17030
  },
17031
+ platforms: {
17032
+ type: "array",
17033
+ items: {
17034
+ type: "string"
17035
+ },
17036
+ default: [
17037
+ "@sockethub/platform-dummy",
17038
+ "@sockethub/platform-feeds",
17039
+ "@sockethub/platform-irc",
17040
+ "@sockethub/platform-metadata",
17041
+ "@sockethub/platform-xmpp"
17042
+ ]
17043
+ },
17135
17044
  packageConfig: {
17136
17045
  type: "object",
17137
17046
  properties: {
17138
- "@sockethub/activity-streams": {
17047
+ "@sockethub/platform-dummy": {
17139
17048
  type: "object",
17140
17049
  additionalProperties: false,
17141
17050
  properties: {
17142
- specialObjs: {
17143
- type: "array",
17144
- items: {
17145
- type: "string"
17146
- },
17147
- default: ["credentials"]
17148
- },
17149
- failOnUnknownObjectProperties: {
17150
- type: "boolean",
17151
- default: true
17152
- }
17051
+ greeting: { type: "string", default: "Hello" }
17153
17052
  }
17154
17053
  },
17155
- "@sockethub/platform-dummy": {
17054
+ "@sockethub/platform-feeds": {
17156
17055
  type: "object",
17157
17056
  additionalProperties: false,
17158
17057
  properties: {
17159
- greeting: {
17160
- type: "string",
17161
- default: "Hello"
17162
- }
17058
+ connectTimeoutMs: { type: "number" },
17059
+ allowPrivateAddresses: { type: "boolean" },
17060
+ concurrency: { type: "integer", minimum: 1 }
17163
17061
  }
17164
17062
  },
17165
- "@sockethub/platform-feeds": {
17063
+ "@sockethub/platform-irc": {
17166
17064
  type: "object",
17167
17065
  additionalProperties: false,
17168
17066
  properties: {
17169
- ...connectConfigPlatforms
17067
+ connectTimeoutMs: { type: "number" }
17170
17068
  }
17171
17069
  },
17172
- "@sockethub/platform-irc": {
17070
+ "@sockethub/platform-xmpp": {
17173
17071
  type: "object",
17174
17072
  additionalProperties: false,
17175
17073
  properties: {
17176
- ...connectConfigPlatforms
17074
+ connectTimeoutMs: { type: "number" }
17177
17075
  }
17178
17076
  },
17179
- "@sockethub/platform-xmpp": {
17077
+ "@sockethub/platform-metadata": {
17180
17078
  type: "object",
17181
17079
  additionalProperties: false,
17182
17080
  properties: {
17183
- ...connectConfigPlatforms
17081
+ allowPrivateAddresses: { type: "boolean" },
17082
+ concurrency: { type: "integer", minimum: 1 }
17184
17083
  }
17185
17084
  }
17186
17085
  }
17187
17086
  },
17188
- platforms: {
17189
- type: "array",
17190
- items: {
17191
- type: "string"
17192
- },
17193
- default: [
17194
- "@sockethub/platform-dummy",
17195
- "@sockethub/platform-feeds",
17196
- "@sockethub/platform-irc",
17197
- "@sockethub/platform-metadata",
17198
- "@sockethub/platform-xmpp"
17199
- ]
17087
+ credentials: {
17088
+ type: "object",
17089
+ additionalProperties: false,
17090
+ properties: {
17091
+ ttlMs: {
17092
+ type: "number",
17093
+ minimum: 0,
17094
+ default: 604800000,
17095
+ description: "Sliding TTL in milliseconds for per-session encrypted " + "credential keys in Redis, refreshed on every save and " + "read. A backstop against keys orphaned by crashes; " + "sessions normally delete their key on disconnect. " + "Size generously — idle sessions do not refresh it. " + "0 disables expiry."
17096
+ }
17097
+ }
17098
+ },
17099
+ credentialCheck: {
17100
+ type: "object",
17101
+ additionalProperties: false,
17102
+ properties: {
17103
+ reconnectIpSource: {
17104
+ type: "string",
17105
+ enum: ["socket", "proxy"],
17106
+ default: "socket"
17107
+ },
17108
+ proxyHeader: {
17109
+ type: "string",
17110
+ default: "x-forwarded-for"
17111
+ }
17112
+ }
17200
17113
  },
17201
17114
  public: {
17202
17115
  type: "object",
@@ -17235,6 +17148,22 @@ var SockethubConfigSchema = {
17235
17148
  blockDurationMs: {
17236
17149
  type: "number",
17237
17150
  default: 5000
17151
+ },
17152
+ maxConnectionsPerIp: {
17153
+ type: "number",
17154
+ minimum: 0,
17155
+ default: 0
17156
+ }
17157
+ }
17158
+ },
17159
+ limits: {
17160
+ type: "object",
17161
+ additionalProperties: false,
17162
+ properties: {
17163
+ maxPlatformInstances: {
17164
+ type: "number",
17165
+ minimum: 0,
17166
+ default: 0
17238
17167
  }
17239
17168
  }
17240
17169
  },
@@ -17292,6 +17221,59 @@ var SockethubConfigSchema = {
17292
17221
  path: {
17293
17222
  type: "string",
17294
17223
  default: "/sockethub"
17224
+ },
17225
+ cors: {
17226
+ type: "object",
17227
+ additionalProperties: false,
17228
+ properties: {
17229
+ origin: {
17230
+ type: "string",
17231
+ default: "*"
17232
+ }
17233
+ }
17234
+ }
17235
+ }
17236
+ },
17237
+ httpActions: {
17238
+ type: "object",
17239
+ additionalProperties: false,
17240
+ properties: {
17241
+ enabled: {
17242
+ type: "boolean",
17243
+ default: false
17244
+ },
17245
+ path: {
17246
+ type: "string",
17247
+ default: "/sockethub-http"
17248
+ },
17249
+ requireRequestId: {
17250
+ type: "boolean",
17251
+ default: true
17252
+ },
17253
+ maxMessagesPerRequest: {
17254
+ type: "number",
17255
+ minimum: 1,
17256
+ default: 20
17257
+ },
17258
+ maxPayloadBytes: {
17259
+ type: "number",
17260
+ minimum: 1,
17261
+ default: 262144
17262
+ },
17263
+ idempotencyTtlMs: {
17264
+ type: "number",
17265
+ minimum: 0,
17266
+ default: 300000
17267
+ },
17268
+ requestTimeoutMs: {
17269
+ type: "number",
17270
+ minimum: 0,
17271
+ default: 30000
17272
+ },
17273
+ idleTimeoutMs: {
17274
+ type: "number",
17275
+ minimum: 0,
17276
+ default: 15000
17295
17277
  }
17296
17278
  }
17297
17279
  },
@@ -17323,7 +17305,6 @@ var schemaURL = "https://sockethub.org/schemas/v0";
17323
17305
  var schemas = {};
17324
17306
  var systemContextsRegistered = false;
17325
17307
  schemas[`${schemaURL}/activity-stream`] = ActivityStreamSchema;
17326
- schemas[`${schemaURL}/activity-object`] = ActivityObjectSchema;
17327
17308
  for (const uri in schemas) {
17328
17309
  ajv.addSchema(schemas[uri], uri);
17329
17310
  }
@@ -17353,7 +17334,7 @@ var import_irc_socket_sasl = __toESM(require_irc_socket(), 1);
17353
17334
  var package_default = {
17354
17335
  name: "@sockethub/platform-irc",
17355
17336
  description: "A sockethub platform module implementing IRC functionality",
17356
- version: "4.0.0-alpha.12",
17337
+ version: "4.0.0-alpha.14",
17357
17338
  private: false,
17358
17339
  author: "Nick Jennings <nick@silverbucket.net>",
17359
17340
  license: "LGPL-3.0+",
@@ -17364,17 +17345,16 @@ var package_default = {
17364
17345
  main: "dist/index.js",
17365
17346
  exports: {
17366
17347
  ".": {
17367
- bun: "./src/index.ts",
17348
+ types: "./dist/index.d.ts",
17368
17349
  import: "./dist/index.js",
17369
17350
  default: "./dist/index.js"
17370
17351
  }
17371
17352
  },
17372
17353
  files: [
17373
- "src/",
17374
17354
  "dist/"
17375
17355
  ],
17376
17356
  engines: {
17377
- bun: ">=1.2"
17357
+ node: ">=20"
17378
17358
  },
17379
17359
  keywords: [
17380
17360
  "sockethub",
@@ -17398,23 +17378,24 @@ var package_default = {
17398
17378
  doc: "typedoc --options typedoc.json"
17399
17379
  },
17400
17380
  dependencies: {
17401
- "@sockethub/irc2as": "^4.0.0-alpha.12",
17402
- "irc-socket-sasl": "^4.0.0"
17381
+ "@sockethub/irc2as": "^4.0.0-alpha.14",
17382
+ "irc-socket-sasl": "^4.1.2"
17403
17383
  },
17404
17384
  devDependencies: {
17405
- "@sockethub/schemas": "^3.0.0-alpha.12",
17385
+ "@sockethub/schemas": "^3.0.0-alpha.14",
17406
17386
  "@types/bun": "latest",
17407
17387
  typedoc: "^0.28.14"
17408
17388
  },
17409
17389
  peerDependencies: {
17410
- "@sockethub/server": "^5.0.0-alpha.12"
17390
+ "@sockethub/server": "^5.0.0-alpha.14"
17411
17391
  },
17412
17392
  peerDependenciesMeta: {
17413
17393
  "@sockethub/server": {
17414
17394
  optional: true
17415
17395
  }
17416
17396
  },
17417
- gitHead: "cc495a5fcf7ce19a8f328a34bbc8cd1439bb67ce"
17397
+ gitHead: "4bc8ffa00d29aa78e59e269ac6e5ea9859ec01a8",
17398
+ types: "./dist/index.d.ts"
17418
17399
  };
17419
17400
 
17420
17401
  // src/schema.ts
@@ -17439,6 +17420,191 @@ var PlatformIrcSchema = {
17439
17420
  "announce",
17440
17421
  "disconnect"
17441
17422
  ]
17423
+ },
17424
+ object: {
17425
+ oneOf: [
17426
+ { $ref: "#/definitions/objectTypes/message" },
17427
+ { $ref: "#/definitions/objectTypes/topic" },
17428
+ { $ref: "#/definitions/objectTypes/address" },
17429
+ { $ref: "#/definitions/objectTypes/attendance" }
17430
+ ]
17431
+ }
17432
+ },
17433
+ definitions: {
17434
+ objectTypes: {
17435
+ message: {
17436
+ type: "object",
17437
+ required: ["type", "content"],
17438
+ additionalProperties: false,
17439
+ properties: {
17440
+ type: { enum: ["message"] },
17441
+ content: { type: "string" }
17442
+ }
17443
+ },
17444
+ topic: {
17445
+ type: "object",
17446
+ required: ["type", "content"],
17447
+ additionalProperties: false,
17448
+ properties: {
17449
+ type: { enum: ["topic"] },
17450
+ content: { type: "string" }
17451
+ }
17452
+ },
17453
+ address: {
17454
+ type: "object",
17455
+ required: ["type"],
17456
+ additionalProperties: false,
17457
+ properties: { type: { enum: ["address"] } }
17458
+ },
17459
+ attendance: {
17460
+ type: "object",
17461
+ required: ["type"],
17462
+ additionalProperties: false,
17463
+ properties: { type: { enum: ["attendance"] } }
17464
+ }
17465
+ }
17466
+ }
17467
+ },
17468
+ responses: {
17469
+ type: "object",
17470
+ required: ["type", "actor"],
17471
+ additionalProperties: false,
17472
+ properties: {
17473
+ "@context": { type: "array", items: { type: "string" } },
17474
+ id: { type: "string" },
17475
+ published: { type: "string" },
17476
+ type: {
17477
+ enum: ["update", "send", "join", "leave", "add", "remove"]
17478
+ },
17479
+ actor: {
17480
+ oneOf: [
17481
+ { $ref: "#/definitions/responses/person" },
17482
+ { $ref: "#/definitions/responses/service" }
17483
+ ]
17484
+ },
17485
+ target: {
17486
+ oneOf: [
17487
+ { $ref: "#/definitions/responses/person" },
17488
+ { $ref: "#/definitions/responses/room" },
17489
+ { $ref: "#/definitions/responses/service" }
17490
+ ]
17491
+ },
17492
+ error: { type: "string" },
17493
+ object: {
17494
+ oneOf: [
17495
+ { $ref: "#/definitions/responses/message" },
17496
+ { $ref: "#/definitions/responses/me" },
17497
+ { $ref: "#/definitions/responses/presence" },
17498
+ { $ref: "#/definitions/responses/topic" },
17499
+ { $ref: "#/definitions/responses/address" },
17500
+ { $ref: "#/definitions/responses/relationship" }
17501
+ ]
17502
+ }
17503
+ },
17504
+ definitions: {
17505
+ responses: {
17506
+ person: {
17507
+ type: "object",
17508
+ required: ["id", "type"],
17509
+ additionalProperties: false,
17510
+ properties: {
17511
+ id: { type: "string" },
17512
+ type: { enum: ["person"] },
17513
+ name: { type: "string" }
17514
+ }
17515
+ },
17516
+ service: {
17517
+ type: "object",
17518
+ required: ["id", "type"],
17519
+ additionalProperties: false,
17520
+ properties: {
17521
+ id: { type: "string" },
17522
+ type: { enum: ["service"] },
17523
+ name: { type: "string" }
17524
+ }
17525
+ },
17526
+ room: {
17527
+ type: "object",
17528
+ required: ["id", "type"],
17529
+ additionalProperties: false,
17530
+ properties: {
17531
+ id: { type: "string" },
17532
+ type: { enum: ["room"] },
17533
+ name: { type: "string" }
17534
+ }
17535
+ },
17536
+ message: {
17537
+ type: "object",
17538
+ required: ["type", "content"],
17539
+ additionalProperties: false,
17540
+ properties: {
17541
+ type: { enum: ["message"] },
17542
+ content: { type: "string" }
17543
+ }
17544
+ },
17545
+ me: {
17546
+ type: "object",
17547
+ required: ["type", "content"],
17548
+ additionalProperties: false,
17549
+ properties: {
17550
+ type: { enum: ["me"] },
17551
+ content: { type: "string" }
17552
+ }
17553
+ },
17554
+ presence: {
17555
+ type: "object",
17556
+ required: ["type"],
17557
+ additionalProperties: false,
17558
+ properties: {
17559
+ type: { enum: ["presence"] },
17560
+ role: {
17561
+ enum: ["owner", "member", "participant", "admin"]
17562
+ }
17563
+ }
17564
+ },
17565
+ topic: {
17566
+ type: "object",
17567
+ required: ["type", "content"],
17568
+ additionalProperties: false,
17569
+ properties: {
17570
+ type: { enum: ["topic"] },
17571
+ content: { type: "string" }
17572
+ }
17573
+ },
17574
+ address: {
17575
+ type: "object",
17576
+ required: ["type"],
17577
+ additionalProperties: false,
17578
+ properties: {
17579
+ type: { enum: ["address"] }
17580
+ }
17581
+ },
17582
+ relationship: {
17583
+ type: "object",
17584
+ required: ["type", "relationship"],
17585
+ additionalProperties: false,
17586
+ properties: {
17587
+ type: { enum: ["relationship"] },
17588
+ relationship: { enum: ["role"] },
17589
+ subject: {
17590
+ type: "object",
17591
+ required: ["type", "role"],
17592
+ additionalProperties: false,
17593
+ properties: {
17594
+ type: { enum: ["presence"] },
17595
+ role: {
17596
+ enum: [
17597
+ "owner",
17598
+ "member",
17599
+ "participant",
17600
+ "admin"
17601
+ ]
17602
+ }
17603
+ }
17604
+ },
17605
+ object: { $ref: "#/definitions/responses/room" }
17606
+ }
17607
+ }
17442
17608
  }
17443
17609
  }
17444
17610
  },
@@ -17453,6 +17619,38 @@ var PlatformIrcSchema = {
17453
17619
  type: "object",
17454
17620
  required: ["type", "nick", "server"],
17455
17621
  additionalProperties: false,
17622
+ not: { required: ["password", "token"] },
17623
+ allOf: [
17624
+ {
17625
+ anyOf: [
17626
+ {
17627
+ not: {
17628
+ properties: {
17629
+ saslMechanism: { const: "PLAIN" }
17630
+ },
17631
+ required: ["saslMechanism"]
17632
+ }
17633
+ },
17634
+ { required: ["password"] },
17635
+ { required: ["token"] }
17636
+ ]
17637
+ },
17638
+ {
17639
+ anyOf: [
17640
+ {
17641
+ not: {
17642
+ properties: {
17643
+ saslMechanism: {
17644
+ const: "OAUTHBEARER"
17645
+ }
17646
+ },
17647
+ required: ["saslMechanism"]
17648
+ }
17649
+ },
17650
+ { required: ["token"] }
17651
+ ]
17652
+ }
17653
+ ],
17456
17654
  properties: {
17457
17655
  type: {
17458
17656
  type: "string"
@@ -17464,7 +17662,12 @@ var PlatformIrcSchema = {
17464
17662
  type: "string"
17465
17663
  },
17466
17664
  password: {
17467
- type: "string"
17665
+ type: "string",
17666
+ minLength: 1
17667
+ },
17668
+ token: {
17669
+ type: "string",
17670
+ minLength: 1
17468
17671
  },
17469
17672
  server: {
17470
17673
  type: "string"
@@ -17477,6 +17680,13 @@ var PlatformIrcSchema = {
17477
17680
  },
17478
17681
  sasl: {
17479
17682
  type: "boolean"
17683
+ },
17684
+ saslMechanism: {
17685
+ type: "string",
17686
+ enum: ["PLAIN", "OAUTHBEARER"]
17687
+ },
17688
+ allowInvalidCert: {
17689
+ type: "boolean"
17480
17690
  }
17481
17691
  }
17482
17692
  }
@@ -17485,6 +17695,22 @@ var PlatformIrcSchema = {
17485
17695
  };
17486
17696
 
17487
17697
  // src/index.ts
17698
+ function flattenConnectOptions(options) {
17699
+ const flattened = Object.create(null);
17700
+ for (const key in options) {
17701
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
17702
+ continue;
17703
+ }
17704
+ flattened[key] = options[key];
17705
+ }
17706
+ return flattened;
17707
+ }
17708
+ var tlsTransport = {
17709
+ connect(options, ...rest) {
17710
+ return tls.connect(flattenConnectOptions(options), ...rest);
17711
+ }
17712
+ };
17713
+
17488
17714
  class IRC {
17489
17715
  log;
17490
17716
  credentialsHash;
@@ -17579,7 +17805,7 @@ class IRC {
17579
17805
  const { default: buildCommand } = await Promise.resolve().then(() => __toESM(require_octal_hack(), 1));
17580
17806
  const message = buildCommand(job.object.content);
17581
17807
  client.raw("PRIVMSG " + job.target.name + " :" + message);
17582
- return done("IRC commands temporarily disabled");
17808
+ return done();
17583
17809
  }
17584
17810
  if (job.object.type === "notice") {
17585
17811
  client.raw(`NOTICE ${job.target.name} :${job.object.content}`);
@@ -17630,8 +17856,12 @@ class IRC {
17630
17856
  return done(err);
17631
17857
  }
17632
17858
  if (job.object.type === "attendance") {
17633
- this.log.debug(`query() - sending NAMES for ${job.target.name}`);
17634
- client.raw(["NAMES", job.target.name]);
17859
+ const channel = this.resolveChannelName(job.target);
17860
+ if (!channel) {
17861
+ return done("cannot query attendance without a valid channel name");
17862
+ }
17863
+ this.log.debug(`query() - sending NAMES for ${channel}`);
17864
+ client.raw(["NAMES", channel]);
17635
17865
  done();
17636
17866
  } else {
17637
17867
  done(`unknown 'type' '${job.object.type}'`);
@@ -17654,6 +17884,19 @@ class IRC {
17654
17884
  this.client = undefined;
17655
17885
  return done();
17656
17886
  }
17887
+ resolveChannelName(target) {
17888
+ if (typeof target?.name === "string" && target.name.startsWith("#")) {
17889
+ return target.name;
17890
+ }
17891
+ if (typeof target?.id === "string") {
17892
+ const slash = target.id.indexOf("/");
17893
+ const candidate = slash >= 0 ? target.id.slice(slash + 1) : target.id;
17894
+ if (candidate.startsWith("#")) {
17895
+ return candidate;
17896
+ }
17897
+ }
17898
+ return;
17899
+ }
17657
17900
  isJoined(channel) {
17658
17901
  if (channel.indexOf("#") === 0) {
17659
17902
  return this.channels.has(channel);
@@ -17707,7 +17950,9 @@ class IRC {
17707
17950
  ircConnect(credentials, cb) {
17708
17951
  this.clientConnecting = true;
17709
17952
  const is_secure = typeof credentials.object.secure === "boolean" ? credentials.object.secure : true;
17710
- const is_sasl = typeof credentials.object.sasl === "boolean" ? credentials.object.sasl : !!credentials.object.password;
17953
+ const sasl_secret = credentials.object.token || credentials.object.password;
17954
+ const sasl_mechanism = credentials.object.saslMechanism || "PLAIN";
17955
+ const is_sasl = typeof credentials.object.sasl === "boolean" ? credentials.object.sasl : !!sasl_secret;
17711
17956
  const module_options = {
17712
17957
  username: credentials.object.username || credentials.object.nick,
17713
17958
  nicknames: [credentials.object.nick],
@@ -17717,14 +17962,17 @@ class IRC {
17717
17962
  debug: console.log
17718
17963
  };
17719
17964
  if (is_secure) {
17720
- module_options.connectOptions = { rejectUnauthorized: false };
17965
+ module_options.connectOptions = {
17966
+ rejectUnauthorized: !credentials.object.allowInvalidCert
17967
+ };
17721
17968
  }
17722
17969
  if (is_sasl) {
17723
- module_options.saslPassword = credentials.object.password;
17970
+ module_options.saslMechanism = sasl_mechanism;
17971
+ module_options.saslPassword = sasl_secret;
17724
17972
  module_options.capabilities = { requires: ["sasl"] };
17725
17973
  }
17726
- this.log.debug(`attempting to connect to ${module_options.server}:${module_options.port} transport: ${is_secure ? "secure" : "clear"} sasl: ${is_sasl}`);
17727
- const client = new import_irc_socket_sasl.default(module_options, is_secure ? tls : net);
17974
+ this.log.debug(`attempting to connect to ${module_options.server}:${module_options.port} transport: ${is_secure ? "secure" : "clear"} sasl: ${is_sasl}${is_sasl ? ` (${sasl_mechanism})` : ""}`);
17975
+ const client = new import_irc_socket_sasl.default(module_options, is_secure ? tlsTransport : net);
17728
17976
  const forceDisconnect = (err) => {
17729
17977
  this.forceDisconnect = true;
17730
17978
  this.clientConnecting = false;
@@ -17802,12 +18050,15 @@ class IRC {
17802
18050
  });
17803
18051
  this.irc2as.events.on("ping", (timestamp) => {
17804
18052
  this.log.debug(`received PING at ${timestamp}`);
17805
- this.client.raw("PONG");
18053
+ this.client?.raw("PONG");
17806
18054
  });
17807
18055
  }
17808
18056
  }
18057
+ var src_default = IRC;
17809
18058
  export {
17810
- IRC as default
18059
+ flattenConnectOptions,
18060
+ src_default as default,
18061
+ IRC
17811
18062
  };
17812
18063
 
17813
- //# debugId=D2F4C2CE472DA48C64756E2164756E21
18064
+ //# debugId=C6F79160F59E2E1364756E2164756E21