@sockethub/server 5.0.0-alpha.3 → 5.0.0-alpha.4

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 (95) hide show
  1. package/coverage/tmp/coverage-39338-1663949520416-0.json +1 -0
  2. package/dist/bootstrap/init.js +2 -1
  3. package/dist/bootstrap/init.js.map +1 -1
  4. package/dist/config.d.ts +7 -1
  5. package/dist/config.js +6 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/index.d.ts +1 -2
  8. package/dist/index.js +7 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/janitor.d.ts +27 -12
  11. package/dist/janitor.js +97 -66
  12. package/dist/janitor.js.map +1 -1
  13. package/dist/listener.d.ts +4 -1
  14. package/dist/listener.js +8 -5
  15. package/dist/listener.js.map +1 -1
  16. package/dist/middleware/create-activity-object.d.ts +3 -1
  17. package/dist/middleware/create-activity-object.js.map +1 -1
  18. package/dist/middleware/expand-activity-stream.d.ts +2 -1
  19. package/dist/middleware/expand-activity-stream.js +4 -1
  20. package/dist/middleware/expand-activity-stream.js.map +1 -1
  21. package/dist/middleware/expand-activity-stream.test.data.js +4 -4
  22. package/dist/middleware/expand-activity-stream.test.data.js.map +1 -1
  23. package/dist/middleware/store-credentials.d.ts +3 -3
  24. package/dist/middleware/store-credentials.js +2 -12
  25. package/dist/middleware/store-credentials.js.map +1 -1
  26. package/dist/middleware/validate.d.ts +2 -2
  27. package/dist/middleware/validate.js +1 -3
  28. package/dist/middleware/validate.js.map +1 -1
  29. package/dist/middleware/validate.test.data.js +5 -5
  30. package/dist/middleware/validate.test.data.js.map +1 -1
  31. package/dist/middleware.d.ts +14 -3
  32. package/dist/middleware.js +3 -1
  33. package/dist/middleware.js.map +1 -1
  34. package/dist/platform-instance.d.ts +11 -10
  35. package/dist/platform-instance.js +77 -62
  36. package/dist/platform-instance.js.map +1 -1
  37. package/dist/platform.js +93 -104
  38. package/dist/platform.js.map +1 -1
  39. package/dist/process-manager.js +7 -3
  40. package/dist/process-manager.js.map +1 -1
  41. package/dist/routes.d.ts +1 -1
  42. package/dist/routes.js +1 -1
  43. package/dist/routes.js.map +1 -1
  44. package/dist/sockethub.d.ts +1 -22
  45. package/dist/sockethub.js +19 -26
  46. package/dist/sockethub.js.map +1 -1
  47. package/package.json +30 -36
  48. package/src/bootstrap/init.d.ts +17 -7
  49. package/src/bootstrap/init.ts +2 -1
  50. package/src/config.ts +9 -1
  51. package/src/index.ts +3 -2
  52. package/src/janitor.test.ts +189 -0
  53. package/src/janitor.ts +110 -65
  54. package/src/listener.ts +11 -7
  55. package/src/middleware/create-activity-object.ts +5 -2
  56. package/src/middleware/expand-activity-stream.test.data.ts +5 -5
  57. package/src/middleware/expand-activity-stream.test.ts +2 -2
  58. package/src/middleware/expand-activity-stream.ts +12 -7
  59. package/src/middleware/store-credentials.test.ts +4 -6
  60. package/src/middleware/store-credentials.ts +8 -14
  61. package/src/middleware/validate.test.data.ts +5 -5
  62. package/src/middleware/validate.ts +4 -6
  63. package/src/middleware.ts +28 -11
  64. package/src/platform-instance.test.ts +18 -18
  65. package/src/platform-instance.ts +98 -73
  66. package/src/platform.ts +79 -101
  67. package/src/process-manager.ts +1 -1
  68. package/src/routes.ts +3 -2
  69. package/src/sockethub.ts +29 -57
  70. package/views/examples/dummy.ejs +3 -1
  71. package/views/examples/shared.js +1 -1
  72. package/views/examples/xmpp.ejs +60 -34
  73. package/coverage/tmp/coverage-93126-1649152190997-0.json +0 -1
  74. package/dist/common.d.ts +0 -3
  75. package/dist/common.js +0 -20
  76. package/dist/common.js.map +0 -1
  77. package/dist/crypto.d.ts +0 -10
  78. package/dist/crypto.js +0 -38
  79. package/dist/crypto.js.map +0 -1
  80. package/dist/store.d.ts +0 -5
  81. package/dist/store.js +0 -17
  82. package/dist/store.js.map +0 -1
  83. package/src/common.test.ts +0 -54
  84. package/src/common.ts +0 -14
  85. package/src/config.d.ts +0 -2
  86. package/src/crypto.d.ts +0 -5
  87. package/src/crypto.test.ts +0 -41
  88. package/src/crypto.ts +0 -41
  89. package/src/janitor.d.ts +0 -8
  90. package/src/middleware/validate.d.ts +0 -1
  91. package/src/middleware.d.ts +0 -21
  92. package/src/sockethub.d.ts +0 -1
  93. package/src/store.test.ts +0 -28
  94. package/src/store.ts +0 -17
  95. package/test/queue.functional.test.js +0 -0
package/src/platform.ts CHANGED
@@ -1,11 +1,8 @@
1
1
  import debug from 'debug';
2
- import hash from "object-hash";
3
- import Queue from 'bull';
4
- import { IActivityStream } from "@sockethub/schemas";
5
- import { getPlatformId, decryptJobData } from "./common";
6
- import { JobDataDecrypted, JobEncrypted } from "./sockethub";
7
- import { MessageFromParent } from './platform-instance';
8
- import { getSessionStore } from "./store";
2
+ import {IActivityStream, CallbackInterface} from "@sockethub/schemas";
3
+ import crypto, {getPlatformId} from "@sockethub/crypto";
4
+ import {CredentialsStore, JobQueue, RedisConfig} from "@sockethub/data-layer";
5
+ import {JobDataDecrypted} from "@sockethub/data-layer/dist";
9
6
 
10
7
  // command-line params
11
8
  const parentId = process.argv[2];
@@ -16,9 +13,11 @@ let logger = debug(loggerPrefix);
16
13
 
17
14
  const redisConfig = process.env.REDIS_URL ? process.env.REDIS_URL
18
15
  : { host: process.env.REDIS_HOST, port: process.env.REDIS_PORT };
16
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
19
17
  const PlatformModule = require(`@sockethub/platform-${platformName}`);
20
18
 
21
- let queueStarted = false;
19
+ let jobQueue: JobQueue;
20
+ let jobQueueStarted = false;
22
21
  let parentSecret1: string, parentSecret2: string;
23
22
 
24
23
  logger(`platform handler initialized for ${platformName} ${identifier}`);
@@ -28,6 +27,11 @@ export interface PlatformSession {
28
27
  sendToClient(msg: IActivityStream, special?: string): void;
29
28
  updateActor(credentials: object): void;
30
29
  }
30
+ interface SecretInterface {
31
+ parentSecret1: string,
32
+ parentSecret2: string
33
+ }
34
+ interface SecretFromParent extends Array<string|SecretInterface>{0: string, 1: SecretInterface}
31
35
 
32
36
  /**
33
37
  * Handle any uncaught errors from the platform by alerting the worker and shutting down.
@@ -44,15 +48,17 @@ process.on('uncaughtException', (err) => {
44
48
  * Incoming messages from the worker to this platform. Data is an array, the first property is the
45
49
  * method to call, the rest are params.
46
50
  */
47
- process.on('message', (data: MessageFromParent) => {
51
+ process.on('message', async (data: SecretFromParent) => {
48
52
  if (data[0] === 'secrets') {
49
- parentSecret1 = data[1].parentSecret1;
50
- parentSecret2 = data[1].parentSecret2;
51
- startQueueListener();
53
+ const {parentSecret2: parentSecret3, parentSecret1: parentSecret} = data[1];
54
+ parentSecret1 = parentSecret;
55
+ parentSecret2 = parentSecret3;
56
+ await startQueueListener();
57
+ } else {
58
+ throw new Error('received unknown command from parent thread');
52
59
  }
53
60
  });
54
61
 
55
-
56
62
  /**
57
63
  * Initialize platform module
58
64
  */
@@ -63,87 +69,54 @@ const platformSession: PlatformSession = {
63
69
  };
64
70
  const platform = new PlatformModule(platformSession);
65
71
 
66
- /**
67
- * Get the credentials stored for this user in this sessions store, if given the correct
68
- * sessionSecret.
69
- * @param actorId
70
- * @param sessionId
71
- * @param sessionSecret
72
- * @param cb
73
- */
74
- function getCredentials(actorId: string, sessionId: string, sessionSecret: string, cb: Function) {
75
- if (platform.config.noCredentials) { return cb(); }
76
- const store = getSessionStore(parentId, parentSecret1, sessionId, sessionSecret);
77
- store.get(actorId, (err, credentials) => {
78
- if (platform.config.persist) {
79
- // don't continue if we don't get credentials
80
- if (err) { return cb(err); }
81
- } else if (! credentials) {
82
- // also skip if this is a non-persist platform with no credentials
83
- return cb();
84
- }
85
-
86
- if (platform.credentialsHash) {
87
- if (platform.credentialsHash !== hash(credentials.object)) {
88
- return cb('provided credentials do not match existing platform instance for actor '
89
- + platform.actor.id);
90
- }
91
- } else {
92
- platform.credentialsHash = hash(credentials.object);
93
- }
94
- cb(undefined, credentials);
95
- });
96
- }
97
-
98
72
  /**
99
73
  * Returns a function used to handle completed jobs from the platform code (the `done` callback).
100
- * @param secret the secret used to decrypt credentials
101
74
  */
102
- function getJobHandler(secret: string) {
103
- return (job: JobEncrypted, done: Function) => {
104
- const jobData: JobDataDecrypted = decryptJobData(job, secret);
105
- const jobLog = debug(`${loggerPrefix}:${jobData.sessionId}`);
106
- jobLog(`received ${jobData.title} ${jobData.msg.type}`);
107
- const sessionSecret = jobData.msg.sessionSecret;
108
- delete jobData.msg.sessionSecret;
109
-
110
- return getCredentials(jobData.msg.actor.id, jobData.sessionId, sessionSecret,
111
- (err, credentials) => {
112
- if (err) { return done(new Error(err)); }
113
- let jobCallbackCalled = false;
114
- const doneCallback = (err, result) => {
115
- if (jobCallbackCalled) { return; }
116
- jobCallbackCalled = true;
117
- if (err) {
118
- jobLog(`errored ${jobData.title} ${jobData.msg.type}`);
119
- let errMsg;
120
- // some error objects (eg. TimeoutError) don't interoplate correctly to human-readable
121
- // so we have to do this little dance
122
- try {
123
- errMsg = err.toString();
124
- } catch (e) {
125
- errMsg = err;
126
- }
127
- done(new Error(errMsg));
128
- } else {
129
- jobLog(`completed ${jobData.title} ${jobData.msg.type}`);
130
- done(null, result);
131
- }
132
- };
133
- if ((Array.isArray(platform.config.requireCredentials)) &&
134
- (platform.config.requireCredentials.includes(jobData.msg.type))) {
135
- // add the credentials object if this method requires it
136
- platform[jobData.msg.type](jobData.msg, credentials, doneCallback);
137
- } else if (platform.config.persist) {
138
- if (platform.initialized) {
139
- platform[jobData.msg.type](jobData.msg, doneCallback);
140
- } else {
141
- done(new Error(`${jobData.msg.type} called on uninitialized platform`));
142
- }
143
- } else {
144
- platform[jobData.msg.type](jobData.msg, doneCallback);
75
+ function getJobHandler() {
76
+ return (job: JobDataDecrypted, done: CallbackInterface) => {
77
+ const jobLog = debug(`${loggerPrefix}:${job.sessionId}`);
78
+ jobLog(`received ${job.title} ${job.msg.type}`);
79
+ const credentialStore = new CredentialsStore(
80
+ parentId, job.sessionId, parentSecret1 + job.msg.sessionSecret, redisConfig as RedisConfig
81
+ );
82
+ delete job.msg.sessionSecret;
83
+
84
+ let jobCallbackCalled = false;
85
+ const doneCallback = (err, result) => {
86
+ if (jobCallbackCalled) { return; }
87
+ jobCallbackCalled = true;
88
+ if (err) {
89
+ jobLog(`failed ${job.title} ${job.msg.type}`);
90
+ let errMsg;
91
+ // some error objects (eg. TimeoutError) don't interpolate correctly to human-readable
92
+ // so we have to do this little dance
93
+ try {
94
+ errMsg = err.toString();
95
+ } catch (e) {
96
+ errMsg = err;
145
97
  }
98
+ done(new Error(errMsg));
99
+ } else {
100
+ jobLog(`completed ${job.title} ${job.msg.type}`);
101
+ done(null, result);
102
+ }
103
+ };
104
+
105
+ platform.config.requireCredentials ? platform.config.requireCredentials : [];
106
+ if (platform.config.requireCredentials.includes(job.msg.type)) {
107
+ // this method requires credentials and should be called even if the platform is not
108
+ // yet initialized, because they need to authenticate before they are initialized.
109
+ credentialStore.get(job.msg.actor.id, platform.credentialsHash).then((credentials) => {
110
+ platform[job.msg.type](job.msg, credentials, doneCallback);
111
+ }).catch((err) => {
112
+ jobLog('error ' + err.toString());
113
+ return done(new Error(err.toString()));
146
114
  });
115
+ } else if ((platform.config.persist) && (!platform.initialized)) {
116
+ done(new Error(`${job.msg.type} called on uninitialized platform`));
117
+ } else {
118
+ platform[job.msg.type](job.msg, doneCallback);
119
+ }
147
120
  };
148
121
  }
149
122
 
@@ -163,29 +136,34 @@ function getSendFunction(command: string) {
163
136
  * both the queue thread (listening on the channel for jobs) and the logging object are updated.
164
137
  * @param credentials
165
138
  */
166
- function updateActor(credentials) {
139
+ async function updateActor(credentials) {
167
140
  identifier = getPlatformId(platformName, credentials.actor.id);
168
141
  logger(`platform actor updated to ${credentials.actor.id} identifier ${identifier}`);
169
142
  logger = debug(`sockethub:platform:${identifier}`);
170
- platform.credentialsHash = hash(credentials.object);
143
+ platform.credentialsHash = crypto.objectHash(credentials.object);
171
144
  platform.debug = debug(`sockethub:platform:${platformName}:${identifier}`);
172
145
  process.send(['updateActor', undefined, identifier]);
173
- startQueueListener(true);
146
+ await startQueueListener(true);
174
147
  }
175
148
 
176
149
  /**
177
- * starts listening on the queue for incoming jobs
150
+ * Starts listening on the queue for incoming jobs
178
151
  * @param refresh boolean if the param is true, we re-init the queue.process
179
152
  * (used when identifier changes)
180
153
  */
181
- function startQueueListener(refresh: boolean = false) {
182
- const secret = parentSecret1 + parentSecret2;
183
- if ((queueStarted) && (!refresh)) {
184
- logger('start queue called multiple times, skipping');
185
- return;
154
+ async function startQueueListener(refresh = false) {
155
+ if (jobQueueStarted) {
156
+ if (refresh) {
157
+ await jobQueue.shutdown();
158
+ } else {
159
+ logger('start queue called multiple times, skipping');
160
+ return;
161
+ }
186
162
  }
187
- const queue = new Queue(parentId + identifier, { redis: redisConfig });
188
- queueStarted = true;
163
+ jobQueue = new JobQueue(
164
+ parentId, identifier, parentSecret1 + parentSecret2, redisConfig as RedisConfig
165
+ );
189
166
  logger('listening on the queue for incoming jobs');
190
- queue.process(getJobHandler(secret));
167
+ jobQueue.onJob(getJobHandler());
168
+ jobQueueStarted = true;
191
169
  }
@@ -1,7 +1,7 @@
1
1
  import init from './bootstrap/init';
2
2
  import PlatformInstance, {
3
3
  platformInstances, PlatformInstanceParams, MessageFromParent } from "./platform-instance";
4
- import { getPlatformId } from "./common";
4
+ import {getPlatformId} from "@sockethub/crypto";
5
5
 
6
6
  class ProcessManager {
7
7
  private readonly parentId: string;
package/src/routes.ts CHANGED
@@ -39,7 +39,7 @@ export const examplePages: IRoutePaths = {
39
39
 
40
40
 
41
41
  function prepFileRoutes(pathMap) {
42
- let _routes = [];
42
+ const _routes = [];
43
43
  Object.keys(pathMap).forEach((key) => {
44
44
  _routes.push({
45
45
  meta: {
@@ -88,7 +88,8 @@ function addRoute(app) {
88
88
  * Setup
89
89
  */
90
90
  const routes = {
91
- setup: function (app: any, examplesEnabled: boolean = config.get('examples:enabled')) {
91
+ setup: function (app: unknown,
92
+ examplesEnabled: boolean = config.get('examples:enabled') as boolean) {
92
93
  baseRoutes.forEach(addRoute(app));
93
94
  if (examplesEnabled) {
94
95
  exampleRoutes.forEach(addRoute(app));
package/src/sockethub.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import debug from 'debug';
2
- import { Socket } from "socket.io";
3
- import { IActivityStream } from "@sockethub/schemas";
2
+ import {Socket} from "socket.io";
3
+ import crypto from "@sockethub/crypto";
4
+ import {CredentialsStore} from "@sockethub/data-layer";
4
5
 
5
- import crypto from './crypto';
6
6
  import init from './bootstrap/init';
7
- import middleware from './middleware';
7
+ import middleware, {MiddlewareChainInterface} from './middleware';
8
8
  import createActivityObject from "./middleware/create-activity-object";
9
9
  import expandActivityStream from "./middleware/expand-activity-stream";
10
10
  import storeCredentials from "./middleware/store-credentials";
@@ -12,34 +12,11 @@ import validate from "./middleware/validate";
12
12
  import janitor from './janitor';
13
13
  import listener from './listener';
14
14
  import ProcessManager from "./process-manager";
15
- import PlatformInstance, { platformInstances } from "./platform-instance";
16
- import { getSessionStore } from "./store";
15
+ import nconf from "nconf";
16
+ import {IActivityStream} from "@sockethub/schemas";
17
17
 
18
18
  const log = debug('sockethub:server:core');
19
19
 
20
-
21
- export interface JobDataDecrypted {
22
- title?: string;
23
- msg: IActivityStream;
24
- sessionId: string;
25
- }
26
-
27
- export interface JobDataEncrypted {
28
- title?: string;
29
- msg: string;
30
- sessionId: string;
31
- }
32
-
33
- export interface JobDecrypted {
34
- data: JobDataDecrypted,
35
- remove?: Function;
36
- }
37
-
38
- export interface JobEncrypted {
39
- data: JobDataEncrypted,
40
- remove?: Function;
41
- }
42
-
43
20
  function attachError(err, msg) {
44
21
  if (typeof msg !== 'object') {
45
22
  msg = { context: 'error' };
@@ -56,11 +33,9 @@ class Sockethub {
56
33
  counter: number;
57
34
  platforms: Map<string, object>;
58
35
  status: boolean;
59
- queue: any;
60
36
  processManager: ProcessManager;
61
37
 
62
38
  constructor() {
63
- this.counter = 0;
64
39
  this.platforms = init.platforms;
65
40
  this.status = false;
66
41
  this.parentId = crypto.randToken(16);
@@ -82,34 +57,27 @@ class Sockethub {
82
57
  }
83
58
 
84
59
  log('active platforms: ', [...init.platforms.keys()]);
85
- janitor.clean(); // start cleanup cycle
86
60
  listener.start(); // start external services
61
+ janitor.start(); // start cleanup cycle
87
62
  log('registering handlers');
88
63
  listener.io.on('connection', this.handleIncomingConnection.bind(this));
89
64
  }
90
65
 
91
- async removeAllPlatformInstances() {
92
- for (let platform of platformInstances) {
93
- await platform[1].destroy();
94
- }
66
+ async shutdown() {
67
+ await janitor.stop();
95
68
  }
96
69
 
97
- private createJob(socketId: string, platformInstance: PlatformInstance, msg): JobDataEncrypted {
98
- const title = `${msg.context}-${(msg.id) ? msg.id : this.counter++}`;
99
- const job: JobDataEncrypted = {
100
- title: title,
101
- sessionId: socketId,
102
- msg: crypto.encrypt(msg, this.parentSecret1 + this.parentSecret2)
103
- };
104
- return job;
105
- };
106
-
107
70
  private handleIncomingConnection(socket: Socket) {
108
71
  // session-specific debug messages
109
72
  const sessionLog = debug('sockethub:server:core:' + socket.id),
110
73
  sessionSecret = crypto.randToken(16),
111
74
  // store instance is session-specific
112
- store = getSessionStore(this.parentId, this.parentSecret1, socket.id, sessionSecret);
75
+ // store = getSessionStore(this.parentId, this.parentSecret1, socket.id, sessionSecret);
76
+ credentialsStore = new CredentialsStore(
77
+ this.parentId, socket.id,
78
+ this.parentSecret1 + sessionSecret,
79
+ nconf.get('redis')
80
+ );
113
81
 
114
82
  sessionLog(`socket.io connection`);
115
83
 
@@ -121,9 +89,9 @@ class Sockethub {
121
89
  middleware('credentials')
122
90
  .use(expandActivityStream)
123
91
  .use(validate('credentials', socket.id))
124
- .use(storeCredentials(store, sessionLog))
92
+ .use(storeCredentials(credentialsStore) as MiddlewareChainInterface)
125
93
  .use((err, data, next) => {
126
- // error handler
94
+ // error handler
127
95
  next(attachError(err, data));
128
96
  }).use((data, next) => { next(); })
129
97
  .done());
@@ -144,20 +112,24 @@ class Sockethub {
144
112
  .use(expandActivityStream)
145
113
  .use(validate('message', socket.id))
146
114
  .use((msg, next) => {
147
- // The platform thread must find the credentials on their own using the given
148
- // sessionSecret, which indicates that this specific session (socket
149
- // connection) has provided credentials.
115
+ // The platform thread must find the credentials on their own using the given
116
+ // sessionSecret, which indicates that this specific session (socket
117
+ // connection) has provided credentials.
150
118
  msg.sessionSecret = sessionSecret;
151
119
  next(msg);
152
120
  }).use((err, data, next) => {
153
121
  next(attachError(err, data));
154
- }).use((msg, next) => {
122
+ }).use(async (msg: IActivityStream, next) => {
155
123
  const platformInstance = this.processManager.get(msg.context, msg.actor.id, socket.id);
156
- sessionLog(`queued to channel ${platformInstance.id}`);
157
- const job = this.createJob(socket.id, platformInstance, msg);
158
124
  // job validated and queued, store socket.io callback for when job is completed
159
- platformInstance.completedJobHandlers.set(job.title, next);
160
- platformInstance.queue.add(job);
125
+ const job = await platformInstance.jobQueue.add(socket.id, msg);
126
+ if (job) {
127
+ platformInstance.completedJobHandlers.set(job.title, next);
128
+ } else {
129
+ // failed to add job to queue, reject handler immediately
130
+ msg.error = 'failed to add job to queue';
131
+ next(msg);
132
+ }
161
133
  }).done());
162
134
  }
163
135
  }
@@ -83,7 +83,9 @@
83
83
  }
84
84
  };
85
85
  bdebug('sending message: ', msg);
86
- sc.socket.emit('message', msg);
86
+ sc.socket.emit('message', msg, (d) => {
87
+ bdebug('completed', d)
88
+ });
87
89
 
88
90
  $('#m').val('');
89
91
  return false;
@@ -29,7 +29,7 @@ ExamplesShared.prototype.__displayUnknownContent = function (msg) {
29
29
  };
30
30
 
31
31
  ExamplesShared.prototype.processIncomingMessage = function (msg) {
32
- console.log('incoming message: ', msg);
32
+ console.log(msg);
33
33
  if (msg.type === 'query') {
34
34
  if (msg.object.members) {
35
35
  $('#messages').append($('<li>').text(` users in ${msg.actor.name}`))
@@ -58,6 +58,7 @@
58
58
 
59
59
  <script>
60
60
  debug = function (msg, obj) { console.log(msg, obj); };
61
+ let counter = 0;
61
62
  const examplesShared = new ExamplesShared();
62
63
  localStorage.debug = 'sockethub:*';
63
64
  let config = {
@@ -92,21 +93,24 @@
92
93
  sc.ActivityStreams.Object.create(asObject);
93
94
  }
94
95
 
95
- function handleMessage(msg) {
96
- if (msg.error) {
97
- debug('received error: ', msg);
98
- console.error(msg.error);
99
- } else if (msg['type'] === 'connect') {
100
- $('.modal').css('display', 'none');
101
- } else if (msg['type'] === 'join') {
102
- $('input#m').prop('disabled', false);
103
- $('button#send').prop('disabled', false);
104
- } else {
105
- examplesShared.processIncomingMessage(msg);
106
- }
96
+ function handleMessage(text) {
97
+ return (msg) => {
98
+ console.log(text);
99
+ if (msg.error) {
100
+ debug('error: ', msg);
101
+ console.error(msg.error);
102
+ } else if (msg['type'] === 'connect') {
103
+ $('.modal').css('display', 'none');
104
+ } else if (msg['type'] === 'join') {
105
+ $('input#m').prop('disabled', false);
106
+ $('button#send').prop('disabled', false);
107
+ } else {
108
+ examplesShared.processIncomingMessage(msg);
109
+ }
110
+ };
107
111
  }
108
112
  // handle incoming messages from the Sockethub server
109
- sc.socket.on('message', handleMessage);
113
+ sc.socket.on('message', handleMessage("incoming message"));
110
114
 
111
115
  $('.actor').click(function (e) {
112
116
  e.preventDefault();
@@ -117,15 +121,24 @@
117
121
  $('#chat').submit(function (e) {
118
122
  e.preventDefault();
119
123
  const input = $('#m').val();
120
- const [target, text_message] = input.split(':');
121
-
122
- if ((!target || !text_message)) {
123
- console.log(
124
- 'unable to send message without target specified ' +
125
- '[room@server.org: hello world]: ',
126
- target, text_message, input);
127
- return false;
124
+ let [targetId, text_message] = input.split(':');
125
+
126
+ if (!text_message) {
127
+ text_message = targetId;
128
+ targetId = undefined;
129
+ }
130
+
131
+ let target = {
132
+ id: 'kosmos-random@kosmos.chat',
133
+ type: 'room'
134
+ }
135
+ if (targetId) {
136
+ target = {
137
+ id: targetId,
138
+ type: 'room'
139
+ }
128
140
  }
141
+
129
142
  const msg = {
130
143
  type: 'send',
131
144
  context: 'xmpp',
@@ -137,9 +150,8 @@
137
150
  target: target
138
151
  };
139
152
 
140
- console.log('[normalize?] sending ', msg);
141
153
  debug('sending message: ', msg);
142
- sc.socket.emit('message', msg, handleMessage);
154
+ sc.socket.emit('message', msg, handleMessage('callback from sent message'));
143
155
  $('#m').val('');
144
156
  return false;
145
157
  });
@@ -165,27 +177,41 @@
165
177
  sc.socket.emit('credentials', credentials, (err) => {
166
178
  if (err) {
167
179
  console.error('failed to create credentials: ', err);
180
+ } else {
181
+ console.log('completed credentials');
168
182
  }
169
183
  });
170
184
 
171
- const msg = {
185
+ const connectMsg = {
172
186
  type: 'connect',
173
187
  context: 'xmpp',
174
- actor: actorString
188
+ actor: actorString,
189
+ object: {
190
+ type: 'message',
191
+ content: `debug:${++counter}`
192
+ }
175
193
  };
194
+ debug('sending connect message: ', connectMsg);
195
+ sc.socket.emit('message', connectMsg, handleMessage('callback from connect'));
176
196
 
177
- debug('sending message: ', msg);
178
- sc.socket.emit('message', msg, handleMessage);
179
- msg.type = 'join';
180
- msg.target = {
181
- type: 'room',
182
- id: 'kosmos-random@kosmos.chat'
197
+ const joinMsg = {
198
+ type: 'join',
199
+ context: 'xmpp',
200
+ actor: actorString,
201
+ target: {
202
+ type: 'room',
203
+ id: 'kosmos-random@kosmos.chat'
204
+ },
205
+ object: {
206
+ type: 'message',
207
+ content: `debug:${counter}`
208
+ }
183
209
  };
184
- debug('sending message: ', msg);
185
- sc.socket.emit('message', msg, handleMessage);
210
+ debug('sending join message: ', joinMsg);
211
+ sc.socket.emit('message', joinMsg, handleMessage('callback from join'));
186
212
  }, 100);
187
213
  return false;
188
214
  });
189
215
  </script>
190
216
  </body>
191
- </html>
217
+ </html>