@tellescope/sdk 1.75.0 → 1.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/sdk.d.ts +8 -1
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +1 -0
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +698 -155
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/sdk.d.ts +8 -1
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +1 -0
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +698 -155
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/sdk.ts +3 -0
- package/src/tests/tests.ts +503 -4
- package/test_generated.pdf +0 -0
package/src/tests/tests.ts
CHANGED
|
@@ -140,6 +140,44 @@ const setup_tests = async () => {
|
|
|
140
140
|
{ expectedResult: 'Authenticated!' }
|
|
141
141
|
)
|
|
142
142
|
|
|
143
|
+
// login rate limit tests
|
|
144
|
+
const badSDK = new Session({ host });
|
|
145
|
+
await badSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
146
|
+
await badSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
147
|
+
await badSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
148
|
+
await badSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
149
|
+
await badSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
150
|
+
await async_test(
|
|
151
|
+
'login rate limited',
|
|
152
|
+
() => badSDK.authenticate('bademail@tellescope.com', 'badpassword@tellescope.com'),
|
|
153
|
+
{ shouldError: true, onError: e => e.message === 'Too many login attempts' }
|
|
154
|
+
)
|
|
155
|
+
await async_test(
|
|
156
|
+
'login not rate limited for other user',
|
|
157
|
+
() => sdk.authenticate(email, password),
|
|
158
|
+
passOnAnyResult
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
const badEnduserSDK = new EnduserSession({ host, businessId });
|
|
162
|
+
await badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
163
|
+
await badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
164
|
+
await badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
165
|
+
await badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
166
|
+
await badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword').catch(console.error)
|
|
167
|
+
await async_test(
|
|
168
|
+
'login rate limited',
|
|
169
|
+
() => badEnduserSDK.authenticate('bademail@tellescope.com', 'badpassword@tellescope.com'),
|
|
170
|
+
{ shouldError: true, onError: e => e.message === 'Too many login attempts' }
|
|
171
|
+
)
|
|
172
|
+
await async_test(
|
|
173
|
+
'login not rate limited for other enduser',
|
|
174
|
+
() => badEnduserSDK.authenticate('otherbademail@tellescope.com', 'badpassword@tellescope.com'),
|
|
175
|
+
{ shouldError: true, onError: e => e.message !== 'Too many login attempts' }
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
// prevent additional login throttling
|
|
179
|
+
await async_test('reset_db', () => sdk.reset_db(), passOnVoid)
|
|
180
|
+
|
|
143
181
|
await sdk.logout()
|
|
144
182
|
await async_test<string, string>('test_authenticated - (logout invalidates jwt)', sdk.test_authenticated, { shouldError: true, onError: e => e === 'Unauthenticated' })
|
|
145
183
|
await sdk.authenticate(email, password)
|
|
@@ -319,8 +357,11 @@ const sub_organization_enduser_tests = async() => {
|
|
|
319
357
|
log_header("Sub Organizations (Enduser-Facing Tests)")
|
|
320
358
|
|
|
321
359
|
await enduserSDK.register({ email: 'root@tellescope.com', password })
|
|
360
|
+
await wait(undefined, 1000) // avoid rate limiting error
|
|
322
361
|
await subEnduserSDK.register({ email: 'sub@tellescope.com', password })
|
|
362
|
+
await wait(undefined, 1000) // avoid rate limiting error
|
|
323
363
|
await enduserSDK.authenticate('root@tellescope.com', password)
|
|
364
|
+
await wait(undefined, 1000) // avoid rate limiting error
|
|
324
365
|
await subEnduserSDK.authenticate('sub@tellescope.com', password)
|
|
325
366
|
|
|
326
367
|
assert(!enduserSDK.userInfo.organizationIds?.length, 'bad root organizationIds', 'root auth org ids')
|
|
@@ -4085,8 +4126,10 @@ export const self_serve_appointment_booking_tests = async () => {
|
|
|
4085
4126
|
|
|
4086
4127
|
const e1 = await sdk.api.endusers.createOne({ email: 'sebass+ny@tellescope.com', state: 'NY' })
|
|
4087
4128
|
const e2 = await sdk.api.endusers.createOne({ email: 'sebass+ca@tellescope.com', state: 'CA' })
|
|
4129
|
+
const e3 = await sdk.api.endusers.createOne({ email: 'sebass+3@tellescope.com' })
|
|
4088
4130
|
await sdk.api.endusers.set_password({ id: e1.id, password })
|
|
4089
4131
|
await sdk.api.endusers.set_password({ id: e2.id, password })
|
|
4132
|
+
await sdk.api.endusers.set_password({ id: e3.id, password })
|
|
4090
4133
|
|
|
4091
4134
|
const event15min = await sdk.api.calendar_event_templates.createOne({
|
|
4092
4135
|
title: 'test 2', durationInMinutes: 15,
|
|
@@ -4098,6 +4141,12 @@ export const self_serve_appointment_booking_tests = async () => {
|
|
|
4098
4141
|
confirmationEmailDisabled: true,
|
|
4099
4142
|
confirmationSMSDisabled: true,
|
|
4100
4143
|
})
|
|
4144
|
+
const event30minGroup = await sdk.api.calendar_event_templates.createOne({
|
|
4145
|
+
title: 'test group', durationInMinutes: 30,
|
|
4146
|
+
confirmationEmailDisabled: true,
|
|
4147
|
+
confirmationSMSDisabled: true,
|
|
4148
|
+
enduserAttendeeLimit: 2,
|
|
4149
|
+
})
|
|
4101
4150
|
|
|
4102
4151
|
// ensure it doesn't match current day, to avoid errors on testing
|
|
4103
4152
|
const dayOfWeekStartingSundayIndexedByZero = (new Date().getDay() + 1) % 7
|
|
@@ -4135,6 +4184,12 @@ export const self_serve_appointment_booking_tests = async () => {
|
|
|
4135
4184
|
replaceObjectFields: true,
|
|
4136
4185
|
})
|
|
4137
4186
|
|
|
4187
|
+
const enduserSDK2 = new EnduserSession({ host, businessId })
|
|
4188
|
+
await enduserSDK2.authenticate('sebass+ca@tellescope.com', password).catch(console.error)
|
|
4189
|
+
|
|
4190
|
+
const enduserSDK3 = new EnduserSession({ host, businessId })
|
|
4191
|
+
await enduserSDK3.authenticate('sebass+3@tellescope.com', password).catch(console.error)
|
|
4192
|
+
|
|
4138
4193
|
// NY Enduser Tests
|
|
4139
4194
|
await enduserSDK.authenticate('sebass+ny@tellescope.com', password).catch(console.error)
|
|
4140
4195
|
await async_test(
|
|
@@ -4258,6 +4313,78 @@ export const self_serve_appointment_booking_tests = async () => {
|
|
|
4258
4313
|
handleAnyError
|
|
4259
4314
|
)
|
|
4260
4315
|
|
|
4316
|
+
// test group bookings
|
|
4317
|
+
await sdk.api.calendar_events.updateOne(conflict.id, { enduserAttendeeLimit: 2 })
|
|
4318
|
+
await async_test(
|
|
4319
|
+
'[group booking] different event type conflict as group still blocks availability',
|
|
4320
|
+
() => enduserSDK.api.calendar_events.get_appointment_availability({
|
|
4321
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4322
|
+
from: new Date(Date.now() - 10000),
|
|
4323
|
+
to: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
|
|
4324
|
+
}),
|
|
4325
|
+
{ onResult: r => r.availabilityBlocks.length === 2 },
|
|
4326
|
+
)
|
|
4327
|
+
await sdk.api.calendar_events.deleteOne(conflict.id)
|
|
4328
|
+
await async_test(
|
|
4329
|
+
'[group booking] availability',
|
|
4330
|
+
() => enduserSDK.api.calendar_events.get_appointment_availability({
|
|
4331
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4332
|
+
from: new Date(Date.now() - 10000),
|
|
4333
|
+
to: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
|
|
4334
|
+
}),
|
|
4335
|
+
{ onResult: r => r.availabilityBlocks.length === 3 },
|
|
4336
|
+
)
|
|
4337
|
+
const groupEvent = (await enduserSDK.api.calendar_events.book_appointment({
|
|
4338
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4339
|
+
startTime: new Date(nySlots.availabilityBlocks[1].startTimeInMS),
|
|
4340
|
+
userId: nySlots.availabilityBlocks[1].userId,
|
|
4341
|
+
})).createdEvent
|
|
4342
|
+
await async_test(
|
|
4343
|
+
'[group booking] more booking allowed',
|
|
4344
|
+
() => enduserSDK.api.calendar_events.get_appointment_availability({
|
|
4345
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4346
|
+
from: new Date(Date.now() - 10000),
|
|
4347
|
+
to: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
|
|
4348
|
+
}),
|
|
4349
|
+
{ onResult: r => r.availabilityBlocks.length === 3 },
|
|
4350
|
+
)
|
|
4351
|
+
await async_test(
|
|
4352
|
+
'[group booking] prevent double-book same-enduser',
|
|
4353
|
+
() => enduserSDK.api.calendar_events.book_appointment({
|
|
4354
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4355
|
+
startTime: new Date(nySlots.availabilityBlocks[1].startTimeInMS),
|
|
4356
|
+
userId: nySlots.availabilityBlocks[1].userId,
|
|
4357
|
+
}),
|
|
4358
|
+
handleAnyError
|
|
4359
|
+
)
|
|
4360
|
+
await async_test(
|
|
4361
|
+
'[group booking] allow other enduser to book',
|
|
4362
|
+
() => enduserSDK2.api.calendar_events.book_appointment({
|
|
4363
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4364
|
+
startTime: new Date(nySlots.availabilityBlocks[1].startTimeInMS),
|
|
4365
|
+
userId: nySlots.availabilityBlocks[1].userId,
|
|
4366
|
+
}),
|
|
4367
|
+
passOnAnyResult
|
|
4368
|
+
)
|
|
4369
|
+
await async_test(
|
|
4370
|
+
'[group booking] no more booking allowed',
|
|
4371
|
+
() => enduserSDK.api.calendar_events.get_appointment_availability({
|
|
4372
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4373
|
+
from: new Date(Date.now() - 10000),
|
|
4374
|
+
to: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
|
|
4375
|
+
}),
|
|
4376
|
+
{ onResult: r => r.availabilityBlocks.length === 2 },
|
|
4377
|
+
)
|
|
4378
|
+
await async_test(
|
|
4379
|
+
'[group booking] other enduser cant book over capacity',
|
|
4380
|
+
() => enduserSDK3.api.calendar_events.book_appointment({
|
|
4381
|
+
calendarEventTemplateId: event30minGroup.id,
|
|
4382
|
+
startTime: new Date(nySlots.availabilityBlocks[1].startTimeInMS),
|
|
4383
|
+
userId: nySlots.availabilityBlocks[1].userId,
|
|
4384
|
+
}),
|
|
4385
|
+
handleAnyError
|
|
4386
|
+
)
|
|
4387
|
+
|
|
4261
4388
|
// test 'multi' flag for booking multiple providers for a given patient
|
|
4262
4389
|
await sdk.api.users.updateOne(sdk.userInfo.id, {
|
|
4263
4390
|
weeklyAvailabilities: [
|
|
@@ -4341,11 +4468,13 @@ export const self_serve_appointment_booking_tests = async () => {
|
|
|
4341
4468
|
await Promise.all([
|
|
4342
4469
|
sdk.api.endusers.deleteOne(e1.id),
|
|
4343
4470
|
sdk.api.endusers.deleteOne(e2.id),
|
|
4471
|
+
sdk.api.endusers.deleteOne(e3.id),
|
|
4344
4472
|
sdk.api.calendar_event_templates.deleteOne(event30min.id),
|
|
4473
|
+
sdk.api.calendar_event_templates.deleteOne(event30minGroup.id),
|
|
4345
4474
|
sdk.api.calendar_event_templates.deleteOne(event15min.id),
|
|
4346
4475
|
sdk.api.calendar_events.deleteOne(bookedAppointment.id),
|
|
4347
|
-
sdk.api.calendar_events.deleteOne(conflict.id),
|
|
4348
4476
|
sdk.api.calendar_events.deleteOne(bookedMultiAppointment.id),
|
|
4477
|
+
sdk.api.calendar_events.deleteOne(groupEvent.id),
|
|
4349
4478
|
])
|
|
4350
4479
|
}
|
|
4351
4480
|
|
|
@@ -5954,6 +6083,8 @@ const validate_schema = () => {
|
|
|
5954
6083
|
endpoints.add(path)
|
|
5955
6084
|
}
|
|
5956
6085
|
}
|
|
6086
|
+
|
|
6087
|
+
console.log("Schema validated")
|
|
5957
6088
|
}
|
|
5958
6089
|
|
|
5959
6090
|
const test_weighted_round_robin = async () => {
|
|
@@ -6519,8 +6650,8 @@ export const ticket_reminder_tests = async () => {
|
|
|
6519
6650
|
&& t.nextReminderInMS !== -1
|
|
6520
6651
|
&& t.reminders?.filter(r => r.didRemind)?.length === 1
|
|
6521
6652
|
),
|
|
6522
|
-
|
|
6523
|
-
|
|
6653
|
+
10,
|
|
6654
|
+
500,
|
|
6524
6655
|
),
|
|
6525
6656
|
passOnAnyResult
|
|
6526
6657
|
)
|
|
@@ -6620,6 +6751,7 @@ const test_send_with_template = async () => {
|
|
|
6620
6751
|
}
|
|
6621
6752
|
|
|
6622
6753
|
const delete_user_tests = async () => {
|
|
6754
|
+
log_header("Delete user tests")
|
|
6623
6755
|
// delete if previous test failed and user still exists
|
|
6624
6756
|
const existing = await sdk.api.users.getSome({ filter: { email: 'deleteme@tellescope.com'}})
|
|
6625
6757
|
if (existing[0]?.email === 'deleteme@tellescope.com') {
|
|
@@ -6644,6 +6776,369 @@ const delete_user_tests = async () => {
|
|
|
6644
6776
|
createdUserSDK.test_authenticated,
|
|
6645
6777
|
handleAnyError
|
|
6646
6778
|
)
|
|
6779
|
+
|
|
6780
|
+
const enduser = await sdk.api.endusers.createOne({ })
|
|
6781
|
+
const { authToken: enduserAuthToken } = await sdk.api.endusers.generate_auth_token({ id: enduser.id })
|
|
6782
|
+
const enduserSDK = new EnduserSession({ host, businessId, authToken: enduserAuthToken })
|
|
6783
|
+
|
|
6784
|
+
await async_test(
|
|
6785
|
+
"Enduser Authenticated",
|
|
6786
|
+
() => enduserSDK.api.endusers.getSome(),
|
|
6787
|
+
passOnAnyResult
|
|
6788
|
+
)
|
|
6789
|
+
|
|
6790
|
+
await sdk.api.endusers.deleteOne(enduser.id)
|
|
6791
|
+
await wait(undefined, 250)
|
|
6792
|
+
await async_test(
|
|
6793
|
+
"Enduser De-authenticated after deletion",
|
|
6794
|
+
() => enduserSDK.api.endusers.getSome(),
|
|
6795
|
+
handleAnyError
|
|
6796
|
+
)
|
|
6797
|
+
}
|
|
6798
|
+
|
|
6799
|
+
const sdkMfaApiKeyUserId = '6525a43e1e75f0350d62afc4'
|
|
6800
|
+
const lockout_tests = async () => {
|
|
6801
|
+
log_header("Lockout tests")
|
|
6802
|
+
|
|
6803
|
+
await async_test(
|
|
6804
|
+
"API Key is authenticated",
|
|
6805
|
+
sdkMfaApiKey.test_authenticated,
|
|
6806
|
+
passOnAnyResult,
|
|
6807
|
+
)
|
|
6808
|
+
await async_test(
|
|
6809
|
+
"API Key lock to future date",
|
|
6810
|
+
() => sdk.api.users.updateOne(sdkMfaApiKeyUserId, { lockedOutUntil: 0 }),
|
|
6811
|
+
passOnAnyResult
|
|
6812
|
+
)
|
|
6813
|
+
await wait(undefined, 250)
|
|
6814
|
+
await async_test(
|
|
6815
|
+
"API Key is de-authenticated when locked",
|
|
6816
|
+
sdkMfaApiKey.test_authenticated,
|
|
6817
|
+
handleAnyError,
|
|
6818
|
+
)
|
|
6819
|
+
await async_test(
|
|
6820
|
+
"API Key unlock to -1",
|
|
6821
|
+
() => sdk.api.users.updateOne(sdkMfaApiKeyUserId, { lockedOutUntil: -1 }),
|
|
6822
|
+
passOnAnyResult
|
|
6823
|
+
)
|
|
6824
|
+
await async_test(
|
|
6825
|
+
"API Key is authenticated",
|
|
6826
|
+
sdkMfaApiKey.test_authenticated,
|
|
6827
|
+
passOnAnyResult,
|
|
6828
|
+
)
|
|
6829
|
+
|
|
6830
|
+
const nonAdminId = sdkNonAdmin.userInfo.id
|
|
6831
|
+
await async_test(
|
|
6832
|
+
"users cannot update own lock status",
|
|
6833
|
+
() => sdk.api.users.updateOne(sdk.userInfo.id, { lockedOutUntil: -1 }),
|
|
6834
|
+
handleAnyError,
|
|
6835
|
+
)
|
|
6836
|
+
await async_test(
|
|
6837
|
+
"non-admin can't lock out others",
|
|
6838
|
+
() => sdkNonAdmin.api.users.updateOne(sdk.userInfo.id, { lockedOutUntil: Date.now() }),
|
|
6839
|
+
handleAnyError
|
|
6840
|
+
)
|
|
6841
|
+
await async_test(
|
|
6842
|
+
"non-admin is authenticated",
|
|
6843
|
+
sdkNonAdmin.test_authenticated,
|
|
6844
|
+
passOnAnyResult,
|
|
6845
|
+
)
|
|
6846
|
+
await async_test(
|
|
6847
|
+
"admin unlock to -1",
|
|
6848
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: -1 }),
|
|
6849
|
+
passOnAnyResult,
|
|
6850
|
+
)
|
|
6851
|
+
await async_test(
|
|
6852
|
+
"non-admin is authenticated (-1)",
|
|
6853
|
+
sdkNonAdmin.test_authenticated,
|
|
6854
|
+
passOnAnyResult,
|
|
6855
|
+
)
|
|
6856
|
+
await async_test(
|
|
6857
|
+
"admin lock to past date",
|
|
6858
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: Date.now() - 1000 }),
|
|
6859
|
+
passOnAnyResult,
|
|
6860
|
+
)
|
|
6861
|
+
await async_test(
|
|
6862
|
+
"non-admin is authenticated (past date)",
|
|
6863
|
+
sdkNonAdmin.test_authenticated,
|
|
6864
|
+
passOnAnyResult,
|
|
6865
|
+
)
|
|
6866
|
+
|
|
6867
|
+
await async_test(
|
|
6868
|
+
"admin lock to 0 (indefinite)",
|
|
6869
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: 0 }),
|
|
6870
|
+
passOnAnyResult
|
|
6871
|
+
)
|
|
6872
|
+
await wait(undefined, 250)
|
|
6873
|
+
await async_test(
|
|
6874
|
+
"non-admin is de-authenticated when locked to 0",
|
|
6875
|
+
sdkNonAdmin.test_authenticated,
|
|
6876
|
+
handleAnyError,
|
|
6877
|
+
)
|
|
6878
|
+
await async_test(
|
|
6879
|
+
"non-admin can't authenciate when locked to 0",
|
|
6880
|
+
() => sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
6881
|
+
handleAnyError,
|
|
6882
|
+
)
|
|
6883
|
+
await async_test(
|
|
6884
|
+
"admin unlock to -1",
|
|
6885
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: -1 }),
|
|
6886
|
+
passOnAnyResult
|
|
6887
|
+
)
|
|
6888
|
+
await async_test(
|
|
6889
|
+
"non-admin can re authenciate when locked to 0",
|
|
6890
|
+
() => sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
6891
|
+
passOnAnyResult,
|
|
6892
|
+
)
|
|
6893
|
+
await async_test(
|
|
6894
|
+
"non-admin is authenticated",
|
|
6895
|
+
sdkNonAdmin.test_authenticated,
|
|
6896
|
+
passOnAnyResult,
|
|
6897
|
+
)
|
|
6898
|
+
|
|
6899
|
+
await async_test(
|
|
6900
|
+
"admin lock to future date",
|
|
6901
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: Date.now() + 10000 }),
|
|
6902
|
+
passOnAnyResult
|
|
6903
|
+
)
|
|
6904
|
+
await wait(undefined, 250)
|
|
6905
|
+
await async_test(
|
|
6906
|
+
"non-admin is de-authenticated when locked to future date",
|
|
6907
|
+
sdkNonAdmin.test_authenticated,
|
|
6908
|
+
handleAnyError,
|
|
6909
|
+
)
|
|
6910
|
+
await async_test(
|
|
6911
|
+
"non-admin can't authenciate when locked to future date",
|
|
6912
|
+
() => sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
6913
|
+
handleAnyError,
|
|
6914
|
+
)
|
|
6915
|
+
await async_test(
|
|
6916
|
+
"admin unlock to -1",
|
|
6917
|
+
() => sdk.api.users.updateOne(nonAdminId, { lockedOutUntil: -1 }),
|
|
6918
|
+
passOnAnyResult
|
|
6919
|
+
)
|
|
6920
|
+
await async_test(
|
|
6921
|
+
"non-admin can re authenciate when locked to future date",
|
|
6922
|
+
() => sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
6923
|
+
passOnAnyResult,
|
|
6924
|
+
)
|
|
6925
|
+
await async_test(
|
|
6926
|
+
"non-admin is authenticated",
|
|
6927
|
+
sdkNonAdmin.test_authenticated,
|
|
6928
|
+
passOnAnyResult,
|
|
6929
|
+
)
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6932
|
+
const sync_tests = async () => {
|
|
6933
|
+
log_header("Data Sync")
|
|
6934
|
+
|
|
6935
|
+
const from = new Date()
|
|
6936
|
+
|
|
6937
|
+
await async_test(
|
|
6938
|
+
"No new records, admin",
|
|
6939
|
+
() => sdk.sync({ from }),
|
|
6940
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6941
|
+
)
|
|
6942
|
+
await async_test(
|
|
6943
|
+
"No new records, non-admin",
|
|
6944
|
+
() => sdkNonAdmin.sync({ from }),
|
|
6945
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6946
|
+
)
|
|
6947
|
+
|
|
6948
|
+
const e = await sdk.api.endusers.createOne({ })
|
|
6949
|
+
await wait(undefined, 100)
|
|
6950
|
+
await async_test(
|
|
6951
|
+
"Enduser create, admin",
|
|
6952
|
+
() => sdk.sync({ from }),
|
|
6953
|
+
{ onResult: ({ results }) => (
|
|
6954
|
+
results.length === 1
|
|
6955
|
+
&& results[0].modelName === 'endusers'
|
|
6956
|
+
&& results[0].recordId === e.id
|
|
6957
|
+
&& results[0].data.includes(e.id)
|
|
6958
|
+
&& JSON.parse(results[0].data) // tests no error throwing
|
|
6959
|
+
)},
|
|
6960
|
+
)
|
|
6961
|
+
await async_test(
|
|
6962
|
+
"Enduser create, non-admin",
|
|
6963
|
+
() => sdkNonAdmin.sync({ from }),
|
|
6964
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6965
|
+
)
|
|
6966
|
+
await async_test(
|
|
6967
|
+
"Enduser create, sub organization",
|
|
6968
|
+
() => sdkSub.sync({ from }),
|
|
6969
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6970
|
+
)
|
|
6971
|
+
|
|
6972
|
+
await sdk.api.endusers.updateOne(e.id, { fname: "UPDATE_TEST"})
|
|
6973
|
+
await wait(undefined, 100)
|
|
6974
|
+
await async_test(
|
|
6975
|
+
"Enduser update, admin",
|
|
6976
|
+
() => sdk.sync({ from }),
|
|
6977
|
+
{ onResult: ({ results }) => (
|
|
6978
|
+
results.length === 1
|
|
6979
|
+
&& results[0].modelName === 'endusers'
|
|
6980
|
+
&& results[0].recordId === e.id
|
|
6981
|
+
&& results[0].data.includes("UPDATE_TEST")
|
|
6982
|
+
)},
|
|
6983
|
+
)
|
|
6984
|
+
await async_test(
|
|
6985
|
+
"Enduser update, non-admin",
|
|
6986
|
+
() => sdkNonAdmin.sync({ from }),
|
|
6987
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6988
|
+
)
|
|
6989
|
+
await async_test(
|
|
6990
|
+
"Enduser update, sub organization",
|
|
6991
|
+
() => sdkSub.sync({ from }),
|
|
6992
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
6993
|
+
)
|
|
6994
|
+
|
|
6995
|
+
const t = await sdk.api.tickets.createOne({ title: 'access test' })
|
|
6996
|
+
await wait(undefined, 100)
|
|
6997
|
+
await async_test(
|
|
6998
|
+
"Non-admin can't access ticket",
|
|
6999
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7000
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
7001
|
+
)
|
|
7002
|
+
|
|
7003
|
+
// creates a user notification which increments count/index
|
|
7004
|
+
sdk.api.tickets.updateOne(t.id, { owner: sdkNonAdmin.userInfo.id })
|
|
7005
|
+
await wait(undefined, 100)
|
|
7006
|
+
|
|
7007
|
+
await async_test(
|
|
7008
|
+
"Non-admin can access tickets on assignment",
|
|
7009
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7010
|
+
{ onResult: ({ results }) => results.length === 2 },
|
|
7011
|
+
)
|
|
7012
|
+
sdk.api.tickets.updateOne(t.id, { owner: '' })
|
|
7013
|
+
await wait(undefined, 100)
|
|
7014
|
+
await async_test(
|
|
7015
|
+
"Non-admin can't access tickets on unassignment",
|
|
7016
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7017
|
+
{ onResult: ({ results }) => results.length === 1 }, // still includes user notification
|
|
7018
|
+
)
|
|
7019
|
+
|
|
7020
|
+
await sdk.api.endusers.updateOne(e.id, { assignedTo: [sdkNonAdmin.userInfo.id] }, { replaceObjectFields: true })
|
|
7021
|
+
await wait(undefined, 100)
|
|
7022
|
+
await async_test(
|
|
7023
|
+
"Enduser update non-admin assignment, can access",
|
|
7024
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7025
|
+
{ onResult: ({ results }) => results.length === 2 }, // enduser and ticket user notification
|
|
7026
|
+
)
|
|
7027
|
+
|
|
7028
|
+
sdk.api.tickets.updateOne(t.id, { owner: '', enduserId: e.id })
|
|
7029
|
+
await wait(undefined, 100)
|
|
7030
|
+
await async_test(
|
|
7031
|
+
"Non-admin can access ticket (and enduser) after enduser assignment",
|
|
7032
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7033
|
+
{ onResult: ({ results }) => results.length === 3 },
|
|
7034
|
+
)
|
|
7035
|
+
|
|
7036
|
+
await sdk.api.endusers.updateOne(e.id, { assignedTo: [] }, { replaceObjectFields: true })
|
|
7037
|
+
await wait(undefined, 100)
|
|
7038
|
+
await async_test(
|
|
7039
|
+
"Enduser update non-admin assignment, revoked access to enduser and ticket",
|
|
7040
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7041
|
+
{ onResult: ({ results }) => results.length === 1 }, // still has user notification
|
|
7042
|
+
)
|
|
7043
|
+
|
|
7044
|
+
// enduser, ticket, and ticket assignment user_notification created
|
|
7045
|
+
await sdk.api.endusers.deleteOne(e.id)
|
|
7046
|
+
await wait(undefined, 100)
|
|
7047
|
+
await async_test(
|
|
7048
|
+
"Enduser delete, admin",
|
|
7049
|
+
() => sdk.sync({ from }),
|
|
7050
|
+
{ onResult: ({ results }) => (
|
|
7051
|
+
results.length === 3
|
|
7052
|
+
&& results[0].modelName === 'endusers'
|
|
7053
|
+
&& results[0].recordId === e.id
|
|
7054
|
+
&& results[0].data === 'deleted'
|
|
7055
|
+
)},
|
|
7056
|
+
)
|
|
7057
|
+
await async_test(
|
|
7058
|
+
"Enduser delete, non-admin",
|
|
7059
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7060
|
+
{ onResult: ({ results }) => results.length === 1 }, // still includes user notification
|
|
7061
|
+
)
|
|
7062
|
+
await async_test(
|
|
7063
|
+
"Enduser delete, sub organization",
|
|
7064
|
+
() => sdkSub.sync({ from }),
|
|
7065
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
7066
|
+
)
|
|
7067
|
+
|
|
7068
|
+
// bulk create test coverage
|
|
7069
|
+
const [e2] = (await sdk.api.endusers.createSome([{ }])).created
|
|
7070
|
+
await wait(undefined, 100)
|
|
7071
|
+
await async_test(
|
|
7072
|
+
"Bulk Enduser create, admin",
|
|
7073
|
+
() => sdk.sync({ from }),
|
|
7074
|
+
{ onResult: ({ results }) => (
|
|
7075
|
+
results.length === 4
|
|
7076
|
+
&& results[0].modelName === 'endusers'
|
|
7077
|
+
&& results[0].recordId === e2.id
|
|
7078
|
+
&& results[0].data.includes(e2.id)
|
|
7079
|
+
&& JSON.parse(results[0].data) // tests no error throwing
|
|
7080
|
+
)},
|
|
7081
|
+
)
|
|
7082
|
+
await async_test(
|
|
7083
|
+
"Bulk Enduser create, non-admin",
|
|
7084
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7085
|
+
{ onResult: ({ results }) => results.length === 1 }, // still includes user notification
|
|
7086
|
+
)
|
|
7087
|
+
await async_test(
|
|
7088
|
+
"Bulk Enduser create, sub organization",
|
|
7089
|
+
() => sdkSub.sync({ from }),
|
|
7090
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
7091
|
+
)
|
|
7092
|
+
|
|
7093
|
+
await sdk.api.endusers.deleteOne(e2.id)
|
|
7094
|
+
await wait(undefined, 100)
|
|
7095
|
+
await async_test(
|
|
7096
|
+
"Bulk Enduser delete, admin",
|
|
7097
|
+
() => sdk.sync({ from }),
|
|
7098
|
+
{ onResult: ({ results }) => (
|
|
7099
|
+
results.length === 4
|
|
7100
|
+
&& results[0].modelName === 'endusers'
|
|
7101
|
+
&& results[0].recordId === e2.id
|
|
7102
|
+
&& results[0].data === 'deleted'
|
|
7103
|
+
)},
|
|
7104
|
+
)
|
|
7105
|
+
await async_test(
|
|
7106
|
+
"Bulk Enduser delete, non-admin",
|
|
7107
|
+
() => sdkNonAdmin.sync({ from }),
|
|
7108
|
+
{ onResult: ({ results }) => results.length === 1 }, // still includes user notification
|
|
7109
|
+
)
|
|
7110
|
+
await async_test(
|
|
7111
|
+
"Bulk Enduser delete, sub organization",
|
|
7112
|
+
() => sdkSub.sync({ from }),
|
|
7113
|
+
{ onResult: ({ results }) => results.length === 0 },
|
|
7114
|
+
)
|
|
7115
|
+
}
|
|
7116
|
+
|
|
7117
|
+
// to cover potential vulernabilities with enduser public register endpoint
|
|
7118
|
+
const register_as_enduser_tests = async () => {
|
|
7119
|
+
log_header("Register as Enduser")
|
|
7120
|
+
|
|
7121
|
+
await async_test(
|
|
7122
|
+
"Enduser register",
|
|
7123
|
+
() => enduserSDK.register({ email: 'test@tellescope.com', password: 'testpassWord12345!' }),
|
|
7124
|
+
passOnAnyResult
|
|
7125
|
+
)
|
|
7126
|
+
await async_test(
|
|
7127
|
+
"Enduser register (rate limited)",
|
|
7128
|
+
() => enduserSDK.register({ email: 'test@tellescope.com', password: 'testpassWord12345!' }),
|
|
7129
|
+
{ shouldError: true, onError: e => e.message === "Too many requests" }
|
|
7130
|
+
)
|
|
7131
|
+
await wait(undefined, 1000)
|
|
7132
|
+
await async_test(
|
|
7133
|
+
"Enduser duplicate register (same response, no ability to enumerate contacts)",
|
|
7134
|
+
() => enduserSDK.register({ email: 'test@tellescope.com', password: 'testpassWord12345!' }),
|
|
7135
|
+
passOnAnyResult
|
|
7136
|
+
)
|
|
7137
|
+
|
|
7138
|
+
const enduser = await sdk.api.endusers.getOne({ email: 'test@tellescope.com'})
|
|
7139
|
+
if (enduser) {
|
|
7140
|
+
await sdk.api.endusers.deleteOne(enduser.id)
|
|
7141
|
+
}
|
|
6647
7142
|
}
|
|
6648
7143
|
|
|
6649
7144
|
(async () => {
|
|
@@ -6669,6 +7164,7 @@ const delete_user_tests = async () => {
|
|
|
6669
7164
|
sdkSubSub.authenticate(subSubUserEmail, password),
|
|
6670
7165
|
sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
6671
7166
|
])
|
|
7167
|
+
console.log("Authentication done")
|
|
6672
7168
|
|
|
6673
7169
|
// console.log(JSON.stringify(await sdk.bulk_load({ load: [{ model: 'users' }]}), null, 2))
|
|
6674
7170
|
|
|
@@ -6688,9 +7184,12 @@ const delete_user_tests = async () => {
|
|
|
6688
7184
|
await mfa_tests()
|
|
6689
7185
|
await setup_tests()
|
|
6690
7186
|
await multi_tenant_tests() // should come right after setup tests
|
|
7187
|
+
await register_as_enduser_tests()
|
|
7188
|
+
await sync_tests()
|
|
7189
|
+
await lockout_tests()
|
|
7190
|
+
await self_serve_appointment_booking_tests()
|
|
6691
7191
|
await delete_user_tests()
|
|
6692
7192
|
// await test_send_with_template()
|
|
6693
|
-
await self_serve_appointment_booking_tests()
|
|
6694
7193
|
await bulk_read_tests()
|
|
6695
7194
|
await ticket_reminder_tests()
|
|
6696
7195
|
await enduser_access_tags_tests()
|
package/test_generated.pdf
CHANGED
|
Binary file
|