@tellescope/sdk 0.0.14 → 0.0.18

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 (48) hide show
  1. package/lib/cjs/enduser.d.ts +34 -5
  2. package/lib/cjs/enduser.d.ts.map +1 -1
  3. package/lib/cjs/enduser.js +5 -4
  4. package/lib/cjs/enduser.js.map +1 -1
  5. package/lib/cjs/sdk.d.ts +51 -16
  6. package/lib/cjs/sdk.d.ts.map +1 -1
  7. package/lib/cjs/sdk.js +10 -10
  8. package/lib/cjs/sdk.js.map +1 -1
  9. package/lib/cjs/session.d.ts +5 -21
  10. package/lib/cjs/session.d.ts.map +1 -1
  11. package/lib/cjs/session.js +12 -0
  12. package/lib/cjs/session.js.map +1 -1
  13. package/lib/cjs/tests/public_endpoint_tests.js +4 -4
  14. package/lib/cjs/tests/public_endpoint_tests.js.map +1 -1
  15. package/lib/cjs/tests/socket_tests.d.ts +1 -1
  16. package/lib/cjs/tests/socket_tests.d.ts.map +1 -1
  17. package/lib/cjs/tests/socket_tests.js +125 -8
  18. package/lib/cjs/tests/socket_tests.js.map +1 -1
  19. package/lib/cjs/tests/tests.js +207 -97
  20. package/lib/cjs/tests/tests.js.map +1 -1
  21. package/lib/esm/enduser.d.ts +34 -5
  22. package/lib/esm/enduser.d.ts.map +1 -1
  23. package/lib/esm/enduser.js +5 -4
  24. package/lib/esm/enduser.js.map +1 -1
  25. package/lib/esm/sdk.d.ts +51 -16
  26. package/lib/esm/sdk.d.ts.map +1 -1
  27. package/lib/esm/sdk.js +10 -10
  28. package/lib/esm/sdk.js.map +1 -1
  29. package/lib/esm/session.d.ts +5 -21
  30. package/lib/esm/session.d.ts.map +1 -1
  31. package/lib/esm/session.js +12 -0
  32. package/lib/esm/session.js.map +1 -1
  33. package/lib/esm/tests/public_endpoint_tests.js +4 -4
  34. package/lib/esm/tests/public_endpoint_tests.js.map +1 -1
  35. package/lib/esm/tests/socket_tests.d.ts +1 -1
  36. package/lib/esm/tests/socket_tests.d.ts.map +1 -1
  37. package/lib/esm/tests/socket_tests.js +123 -8
  38. package/lib/esm/tests/socket_tests.js.map +1 -1
  39. package/lib/esm/tests/tests.js +188 -97
  40. package/lib/esm/tests/tests.js.map +1 -1
  41. package/lib/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +10 -10
  43. package/src/enduser.ts +12 -8
  44. package/src/sdk.ts +31 -20
  45. package/src/session.ts +8 -18
  46. package/src/tests/public_endpoint_tests.ts +4 -4
  47. package/src/tests/socket_tests.ts +68 -5
  48. package/src/tests/tests.ts +116 -36
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/sdk",
3
- "version": "0.0.14",
3
+ "version": "0.0.18",
4
4
  "description": "Code for interacting with the Tellescope API",
5
5
  "main": "./lib/cjs/sdk.js",
6
6
  "module": "./lib/esm/sdk.js",
@@ -30,14 +30,14 @@
30
30
  },
31
31
  "homepage": "https://github.com/tellescope-os/tellescope#readme",
32
32
  "dependencies": {
33
- "@tellescope/constants": "^0.0.14",
34
- "@tellescope/schema": "^0.0.14",
35
- "@tellescope/testing": "^0.0.14",
36
- "@tellescope/types-client": "^0.0.14",
37
- "@tellescope/types-models": "^0.0.14",
38
- "@tellescope/types-utilities": "^0.0.14",
39
- "@tellescope/utilities": "^0.0.14",
40
- "@tellescope/validation": "^0.0.14",
33
+ "@tellescope/constants": "^0.0.18",
34
+ "@tellescope/schema": "^0.0.18",
35
+ "@tellescope/testing": "^0.0.18",
36
+ "@tellescope/types-client": "^0.0.18",
37
+ "@tellescope/types-models": "^0.0.18",
38
+ "@tellescope/types-utilities": "^0.0.18",
39
+ "@tellescope/utilities": "^0.0.18",
40
+ "@tellescope/validation": "^0.0.18",
41
41
  "axios": "^0.21.1",
42
42
  "form-data": "^4.0.0",
43
43
  "socket.io-client": "^4.2.0",
@@ -53,5 +53,5 @@
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
- "gitHead": "b57352502a35237c417fa4d5f571f0bb0aa07be2"
56
+ "gitHead": "8019bedb3e6f90e2d26ee71ee989bd05fc1b7ee6"
57
57
  }
package/src/enduser.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { io } from 'socket.io-client'
2
2
 
3
- import { Session, SessionOptions, APIQuery } from "./session"
3
+ import { Session, SessionOptions } from "./session"
4
+ import { APIQuery } from "./sdk"
4
5
  import { url_safe_path } from "@tellescope/utilities"
5
6
 
6
7
  import { S3PresignedPost, UserIdentity } from "@tellescope/types-utilities"
@@ -14,7 +15,6 @@ import {
14
15
  Enduser,
15
16
  File,
16
17
  } from "@tellescope/types-client"
17
- import { stringValidator } from "@tellescope/validation";
18
18
 
19
19
  export interface EnduserSessionOptions extends SessionOptions {}
20
20
 
@@ -30,8 +30,9 @@ export const defaultQueries = <N extends keyof ClientModelForName>(
30
30
  return {
31
31
  createOne: o => s._POST(`/v1/${singularName}`, o),
32
32
  createSome: os => s._POST(`/v1/${safeName}`, { create: os }),
33
- getOne: (id, filter) => s._GET(`/v1/${singularName}/${id}`, { filter }),
34
- getSome: (o) => s._GET(`/v1/${safeName}`, o),
33
+ getOne: (argument) => typeof argument === 'string' ? s._GET(`/v1/${singularName}/${argument}`)
34
+ : s._GET(`/v1/${singularName}`, { filter: argument}),
35
+ getSome: o => s._GET(`/v1/${safeName}`, o),
35
36
  updateOne: (id, updates, options) => s._PATCH(`/v1/${singularName}/${id}`, { updates, options }),
36
37
  deleteOne: id => s._DELETE(`/v1/${singularName}/${id}`),
37
38
  }
@@ -42,7 +43,7 @@ type EnduserQueries = { [K in EnduserAccessibleModels]: APIQuery<K> } & {
42
43
  logout: () => Promise<void>;
43
44
  },
44
45
  users: {
45
- display_names: () => Promise<{ fname: string, lname: string, id: string }[]>
46
+ display_info: () => Promise<{ fname?: string, lname?: string, id: string, lastActive?: Date, lastLogout?: Date }[]>
46
47
  },
47
48
  files: {
48
49
  prepare_file_upload: (args: { name: string, size: number, type: string }) => Promise<{ presignedUpload: S3PresignedPost, file: File }>,
@@ -76,7 +77,7 @@ export class EnduserSession extends Session {
76
77
  logout: () => this._POST('/v1/logout-enduser'),
77
78
  }
78
79
  this.api.users = {
79
- display_names: () => this._GET<{}, { fname: string, lname: string, id: string }[] >(`/v1/user-display-names`),
80
+ display_info: () => this._GET<{}, { fname: string, lname: string, id: string }[] >(`/v1/user-display-info`),
80
81
  }
81
82
  this.api.meetings = {
82
83
  attendee_info: a => this._GET('/v1/attendee-info', a),
@@ -124,8 +125,11 @@ export class EnduserSession extends Session {
124
125
  return { authToken, enduser }
125
126
  }
126
127
 
127
- authenticate = async (email: string, password: string) => this.handle_new_session(
128
- await this.POST<{email: string, password: string }, { authToken: string, enduser: Enduser }>('/v1/login-enduser', { email, password })
128
+ authenticate = async (email: string, password: string, o?: { expirationInSeconds?: number }) => this.handle_new_session(
129
+ await this.POST<
130
+ {email: string, password: string, expirationInSeconds?: number },
131
+ { authToken: string, enduser: Enduser }
132
+ >('/v1/login-enduser', { email, password, ...o })
129
133
  )
130
134
 
131
135
  refresh_session = async () => {
package/src/sdk.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  AttendeeInfo,
3
3
  JourneyState,
4
- MeetingStatus,
5
4
  Meeting,
6
5
  UserSession,
7
6
  MeetingInfo,
7
+ ReadFilter,
8
8
  } from "@tellescope/types-models"
9
9
 
10
10
  import {
@@ -19,11 +19,19 @@ import {
19
19
  import { CustomUpdateOptions, SortOption, S3PresignedPost, UserIdentity } from "@tellescope/types-utilities"
20
20
  import { url_safe_path } from "@tellescope/utilities"
21
21
 
22
- import { Session as SessionManager, SessionOptions, Filter } from "./session"
22
+ import { Session as SessionManager, SessionOptions } from "./session"
23
23
 
24
24
  export * from "./public"
25
25
  export * from "./enduser"
26
26
 
27
+ export type LoadFunction<T> = (o?: {
28
+ lastId?: string,
29
+ limit?: number,
30
+ sort?: SortOption,
31
+ threadKey?: string,
32
+ filter?: ReadFilter<T>,
33
+ }) => Promise<T[]>
34
+
27
35
  export interface APIQuery<
28
36
  N extends keyof ClientModelForName,
29
37
  T=ClientModelForName[N],
@@ -34,8 +42,8 @@ export interface APIQuery<
34
42
  {
35
43
  createOne: (t: CREATE) => Promise<T>;
36
44
  createSome: (ts: CREATE[]) => Promise<{ created: T[], errors: object[] }>;
37
- getOne: (id: string, filter?: Filter<Partial<T>>) => Promise<T>;
38
- getSome: (o?: { lastId?: string, limit?: number, sort?: SortOption, threadKey?: string, filter?: Filter<Partial<T>> }) => Promise<T[]>
45
+ getOne: (argument: string | ReadFilter<T>) => Promise<T>;
46
+ getSome: LoadFunction<T>;
39
47
  updateOne: (id: string, updates: UPDATE, options?: CustomUpdateOptions) => Promise<T>;
40
48
  deleteOne: (id: string) => Promise<void>;
41
49
  }
@@ -50,7 +58,8 @@ export const defaultQueries = <N extends keyof ClientModelForName>(
50
58
  return {
51
59
  createOne: o => s._POST(`/v1/${singularName}`, o),
52
60
  createSome: os => s._POST(`/v1/${safeName}`, { create: os }),
53
- getOne: (id, filter) => s._GET(`/v1/${singularName}/${id}`, { filter }),
61
+ getOne: (argument) => typeof argument === 'string' ? s._GET(`/v1/${singularName}/${argument}`)
62
+ : s._GET(`/v1/${singularName}`, { filter: argument }),
54
63
  getSome: (o) => s._GET(`/v1/${safeName}`, o),
55
64
  updateOne: (id, updates, options) => s._PATCH(`/v1/${singularName}/${id}`, { updates, options }),
56
65
  deleteOne: id => s._DELETE(`/v1/${singularName}/${id}`),
@@ -72,16 +81,17 @@ const loadDefaultQueries = (s: Session): { [K in keyof ClientModelForName] : API
72
81
  files: defaultQueries(s, 'files'),
73
82
  tickets: defaultQueries(s, 'tickets'),
74
83
  meetings: defaultQueries(s, 'meetings'),
84
+ notes: defaultQueries(s, 'notes'),
75
85
  })
76
86
 
77
87
  type Queries = { [K in keyof ClientModelForName]: APIQuery<K> } & {
78
88
  journeys: {
79
- updateState: (args: { id: string, name: string, updates: JourneyState }) => Promise<void>
89
+ update_state: (args: { id: string, name: string, updates: JourneyState }) => Promise<void>
80
90
  },
81
91
  endusers: {
82
- setPassword: (args: { id: string, password: string }) => Promise<void>,
83
- isAuthenticated: (args: { id: string, authToken: string }) => Promise<{ isAuthenticated: boolean, enduser: Enduser }>
84
- generateAuthToken: (args: { id: string }) => Promise<{ authToken: string }>
92
+ set_password: (args: { id: string, password: string }) => Promise<void>,
93
+ is_authenticated: (args: { id: string, authToken: string }) => Promise<{ isAuthenticated: boolean, enduser: Enduser }>
94
+ generate_auth_token: (args: { id?: string, phone?: string, email?: string, externalId?: string }) => Promise<{ authToken: string, enduser: Enduser }>
85
95
  },
86
96
  users: {
87
97
  display_names: () => Promise<{ fname: string, lname: string, id: string }[]>,
@@ -110,10 +120,10 @@ export class Session extends SessionManager {
110
120
  super({ ...o, cacheKey: o?.cacheKey || "tellescope_user" })
111
121
  const queries = loadDefaultQueries(this) as Queries
112
122
 
113
- queries.journeys.updateState = ({id, name, updates}) => this._PATCH(`/v1/journey/${id}/state/${name}`, { updates })
114
- queries.endusers.setPassword = ({id, password}) => this._POST(`/v1/set-enduser-password`, { id, password })
115
- queries.endusers.isAuthenticated = ({id, authToken}) => this._GET(`/v1/enduser-is-authenticated`, { id, authToken })
116
- queries.endusers.generateAuthToken = args => this._GET(`/v1/generate-enduser-auth-token`, args)
123
+ queries.journeys.update_state = ({id, name, updates}) => this._PATCH(`/v1/journey/${id}/state/${name}`, { updates })
124
+ queries.endusers.set_password = ({id, password}) => this._POST(`/v1/set-enduser-password`, { id, password })
125
+ queries.endusers.is_authenticated = ({id, authToken}) => this._GET(`/v1/enduser-is-authenticated`, { id, authToken })
126
+ queries.endusers.generate_auth_token = args => this._GET(`/v1/generate-enduser-auth-token`, args)
117
127
  queries.users.display_names = () => this._GET<{}, { fname: string, lname: string, id: string }[]>(`/v1/user-display-names`),
118
128
  queries.files.prepare_file_upload = (args) => this._POST(`/v1/prepare-file-upload`, args),
119
129
  queries.files.file_download_URL = a => this._GET('/v1/file-download-URL', a),
@@ -170,13 +180,14 @@ export class Session extends SessionManager {
170
180
  if (this.AUTO_REFRESH_MS < elapsedSessionMS) { return await this.refresh_session()}
171
181
  }
172
182
 
173
- authenticate = async (email: string, password: string, url?: string) => {
174
- if (url) this.host = url
175
-
176
- return this.handle_new_session(
177
- await this.POST<{email: string, password: string }, UserSession & { authToken: string }>('/submit-login', { email, password })
178
- )
179
- }
183
+ authenticate = async (email: string, password: string, o?: { expirationInSeconds?: number }) => (
184
+ this.handle_new_session(
185
+ await this.POST<
186
+ {email: string, password: string, expirationInSeconds?: number },
187
+ UserSession & { authToken: string }
188
+ >('/submit-login', { email, password, ...o })
189
+ )
190
+ )
180
191
  logout = async () => {
181
192
  this.clearState()
182
193
  await this.POST('/logout-api').catch(console.error)
package/src/session.ts CHANGED
@@ -22,6 +22,7 @@ export interface SessionOptions {
22
22
  authToken?: string;
23
23
  host?: string;
24
24
  cacheKey?: string;
25
+ expirationInSeconds?: number,
25
26
  handleUnauthenticated?: () => Promise<void>;
26
27
  }
27
28
 
@@ -29,24 +30,6 @@ interface RequestOptions {
29
30
  refresh_session?: () => Promise<any>,
30
31
  }
31
32
 
32
- export type Filter<T> = { [K in keyof T]: T[K] }
33
-
34
- export interface APIQuery<
35
- N extends keyof ClientModelForName,
36
- T=ClientModelForName[N],
37
- Req=ClientModelForName_required[N],
38
- CREATE=Omit<Req & Partial<T>, keyof ClientModelForName_readonly[N]>,
39
- UPDATE=Omit<Partial<T>, keyof (ClientModelForName_readonly[N] & ClientModelForName_updatesDisabled[N])>,
40
- >
41
- {
42
- createOne: (t: CREATE) => Promise<T>;
43
- createSome: (ts: CREATE[]) => Promise<{ created: T[], errors: object[] }>;
44
- getOne: (id: string, filter?: Filter<Partial<T>>) => Promise<T>;
45
- getSome: (o?: { lastId?: string, limit?: number, sort?: SortOption, threadKey?: string }, f?: Filter<Partial<T>>) => Promise<T[]>
46
- updateOne: (id: string, updates: UPDATE, options?: CustomUpdateOptions) => Promise<T>;
47
- deleteOne: (id: string) => Promise<void>;
48
- }
49
-
50
33
  const generateBearer = (authToken: string) => `Bearer ${authToken}`
51
34
 
52
35
  const parseError = (err: any) => {
@@ -71,6 +54,7 @@ export class Session {
71
54
  apiKey?: string;
72
55
  socket?: Socket;
73
56
  handleUnauthenticated?: SessionOptions['handleUnauthenticated']
57
+ expirationInSeconds?: number;
74
58
  socketAuthenticated: boolean;
75
59
  userInfo: { businessId?: string };
76
60
  sessionStart = Date.now();
@@ -81,6 +65,7 @@ export class Session {
81
65
  constructor(o={} as SessionOptions & RequestOptions) {
82
66
  this.host= o.host ?? DEFAULT_HOST
83
67
  this.apiKey = o.apiKey ?? '';
68
+ this.expirationInSeconds = o.expirationInSeconds
84
69
  this.socket = undefined as Socket | undefined
85
70
  this.socketAuthenticated = false
86
71
  this.handleUnauthenticated = o.handleUnauthenticated
@@ -195,6 +180,11 @@ export class Session {
195
180
  catch(err) { console.error(err); throw err }
196
181
  }
197
182
 
183
+ DOWNLOAD = async (downloadURL: string) => {
184
+ const content = await axios.get(downloadURL)
185
+ return content.data
186
+ }
187
+
198
188
  EMIT = async (route: string, args: object, authenticated=true, options={} as RequestOptions) => {
199
189
  this.socket?.emit(route, { ...args, ...authenticated ? { authToken: this.authToken } : {} } )
200
190
  }
@@ -32,14 +32,14 @@ const enduser_login_tests = async () => {
32
32
  )
33
33
  await async_test(
34
34
  'setPassword',
35
- () => sdk.api.endusers.setPassword({ id: e.id, password }),
35
+ () => sdk.api.endusers.set_password({ id: e.id, password }),
36
36
  { onResult: _ => true }
37
37
  )
38
38
 
39
39
  let authToken = 'placeholder'
40
40
  await async_test(
41
41
  'isAuthenticated (no)',
42
- () => sdk.api.endusers.isAuthenticated({ id: e.id, authToken }),
42
+ () => sdk.api.endusers.is_authenticated({ id: e.id, authToken }),
43
43
  { onResult: ({ isAuthenticated, enduser }) => isAuthenticated === false && enduser === null }
44
44
  )
45
45
  await async_test(
@@ -49,7 +49,7 @@ const enduser_login_tests = async () => {
49
49
  )
50
50
  await async_test(
51
51
  'isAuthenticated (yes)',
52
- () => sdk.api.endusers.isAuthenticated({ id: e.id, authToken }),
52
+ () => sdk.api.endusers.is_authenticated({ id: e.id, authToken }),
53
53
  { onResult: ({ isAuthenticated, enduser }) => isAuthenticated === true && enduser?.id === e.id }
54
54
  )
55
55
  }
@@ -58,7 +58,7 @@ const enduser_login_tests = async () => {
58
58
  log_header("Public Endpoints")
59
59
 
60
60
  try {
61
- await sdk.authenticate(email, password, host)
61
+ await sdk.authenticate(email, password)
62
62
  await sdk.reset_db()
63
63
 
64
64
  await enduser_login_tests()
@@ -1,3 +1,4 @@
1
+ import { createHash } from "crypto"
1
2
  import {
2
3
  assert,
3
4
  async_test,
@@ -17,6 +18,7 @@ import { EnduserSession } from "../enduser"
17
18
  import { Session, /* APIQuery */ } from "../sdk"
18
19
  import { PLACEHOLDER_ID } from "@tellescope/constants"
19
20
 
21
+ export const get_sha256 = (s='') => createHash('sha256').update(s).digest('hex')
20
22
 
21
23
  const host = process.env.TEST_URL || 'http://localhost:8080'
22
24
  const [email, password] = [process.env.TEST_EMAIL, process.env.TEST_PASSWORD]
@@ -133,7 +135,7 @@ const access_tests = async () => {
133
135
 
134
136
  const enduser_tests = async () => {
135
137
  const enduser = await user1.api.endusers.createOne({ email: "enduser@tellescope.com" })
136
- await user1.api.endusers.setPassword({ id: enduser.id, password: 'enduserPassword!' })
138
+ await user1.api.endusers.set_password({ id: enduser.id, password: 'enduserPassword!' })
137
139
 
138
140
  await enduserSDK.authenticate(enduser.email as string, 'enduserPassword!')
139
141
  await wait(undefined, 25)
@@ -198,28 +200,89 @@ const enduser_tests = async () => {
198
200
  // await user1.api.chats.deleteOne(messageToUser.id)
199
201
  }
200
202
 
203
+ const TEST_SESSION_DURATION = 2 // seconds
204
+ const SESSION_TIMEOUT_DELAY = 2000 // ms
205
+ const deauthentication_tests = async (byTimeout=false) => {
206
+ log_header(`Unauthenticated Tests ${byTimeout ? '- With Timeout, requires Worker' : '- With Manual Logout' }`)
207
+
208
+ const enduser = await user1.api.endusers.createOne({ email: "socketenduser@tellescope.com" })
209
+ await user1.api.endusers.set_password({ id: enduser.id, password: 'enduserPassword!' })
210
+ await enduserSDK.authenticate(enduser.email as string, 'enduserPassword!', { expirationInSeconds: byTimeout ? TEST_SESSION_DURATION : undefined })
211
+ await wait(undefined, 25)
212
+
213
+ const room = await user1.api.chat_rooms.createOne({
214
+ type: 'external',
215
+ userIds: [user1.userInfo.id],
216
+ enduserIds: [enduser.id],
217
+ })
218
+
219
+ const userEvents = [] as ChatMessage[]
220
+ const enduserEvents = [] as ChatMessage[]
221
+ user1.subscribe({ [room.id]: 'chats' })
222
+ enduserSDK.subscribe({ [room.id]: 'chats' })
223
+ user1.handle_events({ 'created-chats': rs => userEvents.push(...rs) })
224
+ enduserSDK.handle_events({ 'created-chats': rs => enduserEvents.push(...rs) })
225
+ await wait(undefined, 10)
226
+
227
+ if (!byTimeout) {
228
+ await enduserSDK.api.endusers.logout()
229
+ } else {
230
+ await wait(undefined, TEST_SESSION_DURATION * 1000 + SESSION_TIMEOUT_DELAY)
231
+ }
232
+ await user1.api.chats.createOne({ roomId: room.id, message: "Hello!" })
233
+ await wait(undefined, 25)
234
+ assert(objects_equivalent(enduserEvents[0], undefined), 'enduser got message after logout on socket', 'enduser logged out')
235
+
236
+ // re-authenticate enduser to send message to user
237
+ await enduserSDK.authenticate(enduser.email as string, 'enduserPassword!')
238
+
239
+ // ensure user logged out appropriately for not receiving message
240
+ await user1.logout()
241
+ if (byTimeout) {
242
+ await user1.authenticate(email, password, { expirationInSeconds: byTimeout ? TEST_SESSION_DURATION : undefined } )
243
+ await wait(undefined, TEST_SESSION_DURATION * 1000 + SESSION_TIMEOUT_DELAY)
244
+ }
245
+ await enduserSDK.api.chats.createOne({ roomId: room.id, message: "Hello right back!" })
246
+ await wait(undefined, 25)
247
+ assert(objects_equivalent(userEvents[0], undefined), 'user got message after logout', 'user logged out')
248
+
249
+ // must come before cleanup, so cleanup works
250
+ await user1.authenticate(email, password), // reauthenticate for later tests as needed
251
+
252
+ // cleanup
253
+ await Promise.all([
254
+ user1.api.endusers.deleteOne(enduser.id),
255
+ user1.api.chat_rooms.deleteOne(room.id), // deletes chats as side effect
256
+ ])
257
+ }
258
+
201
259
  (async () => {
202
260
  log_header("Sockets")
203
261
 
204
262
  try {
205
- await user1.authenticate(email, password, host)
263
+ await user1.authenticate(email, password)
206
264
  await user1.reset_db()
207
- await user2.authenticate(email2, password2, host) // generate authToken + socket connection for API keyj
265
+ await user2.authenticate(email2, password2) // generate authToken + socket connection for API keyj
208
266
  await wait(undefined, 25)
209
267
 
210
268
  let loopCount = 0
211
269
  while (!(user1.socketAuthenticated && user2.socketAuthenticated) && ++loopCount < 10) {
212
- user2.authenticate_socket()
270
+ if (!user1.socketAuthenticated) user1.authenticate_socket()
271
+ if (!user2.socketAuthenticated) user2.authenticate_socket()
213
272
  await wait(undefined, 100)
214
273
  }
215
274
  if (loopCount === 10) {
216
275
  console.log("Failed to authenticate")
217
276
  process.exit()
218
277
  }
219
-
278
+
220
279
  await enduser_tests()
221
280
  await basic_tests()
222
281
  await access_tests()
282
+
283
+ await deauthentication_tests() // should come last!
284
+ await deauthentication_tests(true) // should come last!
285
+
223
286
  } catch(err) {
224
287
  console.error(err)
225
288
  }