@live-change/access-control-service 0.8.118 → 0.8.120
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/invite.js +173 -44
- package/package.json +3 -3
package/invite.js
CHANGED
|
@@ -2,6 +2,7 @@ import App from '@live-change/framework'
|
|
|
2
2
|
const app = App.app()
|
|
3
3
|
import definition from './definition.js'
|
|
4
4
|
const config = definition.config
|
|
5
|
+
import pluralize from 'pluralize'
|
|
5
6
|
|
|
6
7
|
const inviteMessageActionByObjectType = config.inviteMessageActionByObjectType ?? {}
|
|
7
8
|
|
|
@@ -190,6 +191,9 @@ definition.action({
|
|
|
190
191
|
}
|
|
191
192
|
})
|
|
192
193
|
|
|
194
|
+
import task from '@live-change/task-service/task.ts' // need to import taks.js to avoid circular dependency
|
|
195
|
+
|
|
196
|
+
|
|
193
197
|
for(const contactType of config.contactTypes) {
|
|
194
198
|
|
|
195
199
|
const contactTypeUpperCaseName = contactType[0].toUpperCase() + contactType.slice(1)
|
|
@@ -206,6 +210,52 @@ for(const contactType of config.contactTypes) {
|
|
|
206
210
|
}
|
|
207
211
|
}
|
|
208
212
|
|
|
213
|
+
async function doInvite(contact, objectType, object, invitationData, emit, trigger = app.trigger) {
|
|
214
|
+
const contactData = await app.viewGet('get' + contactTypeUName, { [contactType]: contact })
|
|
215
|
+
if(contactData?.user) { // user exists
|
|
216
|
+
const { user } = contactData
|
|
217
|
+
await trigger({ type: 'notify' }, {
|
|
218
|
+
sessionOrUserType: 'user_User',
|
|
219
|
+
sessionOrUser: user,
|
|
220
|
+
notificationType: 'accessControl_Invitation',
|
|
221
|
+
objectType,
|
|
222
|
+
object,
|
|
223
|
+
...invitationData, id: undefined
|
|
224
|
+
})
|
|
225
|
+
emit({
|
|
226
|
+
type: 'userInvited',
|
|
227
|
+
user,
|
|
228
|
+
objectType, object,
|
|
229
|
+
...invitationData, id: undefined
|
|
230
|
+
})
|
|
231
|
+
return 'userInvited'
|
|
232
|
+
} else {
|
|
233
|
+
// Authenticate with message because we will create account later
|
|
234
|
+
const messageData = {
|
|
235
|
+
objectType, object,
|
|
236
|
+
...invitationData, id: undefined,
|
|
237
|
+
action: inviteMessageActionByObjectType[objectType] ?? 'inviteWithMessage'
|
|
238
|
+
}
|
|
239
|
+
await trigger({ type: 'authenticateWithMessage' }, {
|
|
240
|
+
contactType,
|
|
241
|
+
contact,
|
|
242
|
+
messageData,
|
|
243
|
+
action: 'inviteWithMessage',
|
|
244
|
+
actionProperties: { objectType, object },
|
|
245
|
+
targetPage: { name: 'accessControl:invitationAccepted', params: { objectType, object } },
|
|
246
|
+
fallbackPage: { name: 'accessControl:invitationFallback', params: { objectType, object } }
|
|
247
|
+
})
|
|
248
|
+
emit({
|
|
249
|
+
type: 'contactInvited',
|
|
250
|
+
contactType: contactTypeName + '_' + contactTypeUName,
|
|
251
|
+
contact,
|
|
252
|
+
objectType, object,
|
|
253
|
+
...invitationData, id: undefined
|
|
254
|
+
})
|
|
255
|
+
return 'contactInvited'
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
209
259
|
definition.action({
|
|
210
260
|
name: 'invite' + contactTypeUpperCaseName,
|
|
211
261
|
waitForEvents: true,
|
|
@@ -221,9 +271,9 @@ for(const contactType of config.contactTypes) {
|
|
|
221
271
|
...contactTypeProperties,
|
|
222
272
|
...invitationProperties
|
|
223
273
|
},
|
|
224
|
-
access: (params, { client, context, visibilityTest
|
|
274
|
+
access: (params, { client, context, visibilityTest}) =>
|
|
225
275
|
visibilityTest || access.clientCanInvite(client, params),
|
|
226
|
-
async execute(params, { client, service }, emit) {
|
|
276
|
+
async execute(params, { client, service, trigger }, emit) {
|
|
227
277
|
const { [contactTypeName]: contact } = params
|
|
228
278
|
const { objectType, object } = params
|
|
229
279
|
const { roles } = params
|
|
@@ -236,52 +286,131 @@ for(const contactType of config.contactTypes) {
|
|
|
236
286
|
}
|
|
237
287
|
|
|
238
288
|
const [ fromType, from ] = client.user ? ['user_User', client.user] : ['session_Session', client.session]
|
|
239
|
-
const invitationData = { fromType, from }
|
|
289
|
+
const invitationData = { fromType, from, roles }
|
|
290
|
+
for(const propertyName in invitationProperties) invitationData[propertyName] = params[propertyName]
|
|
291
|
+
await doInvite(contact, objectType, object, invitationData, emit, trigger)
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
const inviteOneTask = task({
|
|
296
|
+
name: "invite" + contactTypeUpperCaseName,
|
|
297
|
+
properties: {
|
|
298
|
+
objectType: {
|
|
299
|
+
type: String,
|
|
300
|
+
validation: ['nonEmpty']
|
|
301
|
+
},
|
|
302
|
+
object: {
|
|
303
|
+
type: String,
|
|
304
|
+
validation: ['nonEmpty']
|
|
305
|
+
},
|
|
306
|
+
fromType: {
|
|
307
|
+
type: String,
|
|
308
|
+
validation: ['nonEmpty']
|
|
309
|
+
},
|
|
310
|
+
from: {
|
|
311
|
+
type: String,
|
|
312
|
+
validation: ['nonEmpty']
|
|
313
|
+
},
|
|
314
|
+
...contactTypeProperties,
|
|
315
|
+
...invitationProperties
|
|
316
|
+
},
|
|
317
|
+
maxRetries: 1,
|
|
318
|
+
async execute(params, { service, task }, emit) {
|
|
319
|
+
const { [contactTypeName]: contact } = params
|
|
320
|
+
const { objectType, object } = params
|
|
321
|
+
const { roles } = params
|
|
322
|
+
const { fromType, from } = params
|
|
323
|
+
const invitationData = { fromType, from, roles }
|
|
324
|
+
return await doInvite(contact, objectType, object, invitationData, emit, trigger)
|
|
325
|
+
}
|
|
326
|
+
}, definition)
|
|
327
|
+
|
|
328
|
+
const inviteManyTask = task({
|
|
329
|
+
name: "inviteMany" + contactTypeUpperCaseName,
|
|
330
|
+
properties: {
|
|
331
|
+
objectType: {
|
|
332
|
+
type: String,
|
|
333
|
+
validation: ['nonEmpty']
|
|
334
|
+
},
|
|
335
|
+
object: {
|
|
336
|
+
type: String,
|
|
337
|
+
validation: ['nonEmpty']
|
|
338
|
+
},
|
|
339
|
+
fromType: {
|
|
340
|
+
type: String,
|
|
341
|
+
validation: ['nonEmpty']
|
|
342
|
+
},
|
|
343
|
+
from: {
|
|
344
|
+
type: String,
|
|
345
|
+
validation: ['nonEmpty']
|
|
346
|
+
},
|
|
347
|
+
...invitationProperties,
|
|
348
|
+
contacts: {
|
|
349
|
+
type: Array,
|
|
350
|
+
of: {
|
|
351
|
+
type: Object,
|
|
352
|
+
properties: contactTypeProperties
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
async execute(params, { service, task }, emit) {
|
|
357
|
+
const { objectType, object } = params
|
|
358
|
+
const { roles } = params
|
|
359
|
+
const { fromType, from } = params
|
|
360
|
+
const invitationData = { fromType, from, roles }
|
|
240
361
|
for(const propertyName in invitationProperties) invitationData[propertyName] = params[propertyName]
|
|
362
|
+
for(const contact of params.contacts) {
|
|
363
|
+
try {
|
|
364
|
+
await doInvite(contact[contactTypeName], objectType, object, invitationData, emit, trigger)
|
|
365
|
+
} catch(e) {
|
|
366
|
+
// ignore errors
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}, definition)
|
|
241
371
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
})
|
|
261
|
-
} else {
|
|
262
|
-
// Authenticate with message because we will create account later
|
|
263
|
-
const messageData = {
|
|
264
|
-
objectType, object,
|
|
265
|
-
...invitationData, id: undefined,
|
|
266
|
-
action: inviteMessageActionByObjectType[objectType] ?? 'inviteWithMessage',
|
|
372
|
+
definition.action({
|
|
373
|
+
name: 'inviteMany' + pluralize(contactTypeUpperCaseName),
|
|
374
|
+
waitForEvents: true,
|
|
375
|
+
properties: {
|
|
376
|
+
objectType: {
|
|
377
|
+
type: String,
|
|
378
|
+
validation: ['nonEmpty']
|
|
379
|
+
},
|
|
380
|
+
object: {
|
|
381
|
+
type: String,
|
|
382
|
+
validation: ['nonEmpty']
|
|
383
|
+
},
|
|
384
|
+
...invitationProperties,
|
|
385
|
+
contacts: {
|
|
386
|
+
type: Array,
|
|
387
|
+
of: {
|
|
388
|
+
type: Object,
|
|
389
|
+
properties: contactTypeProperties
|
|
267
390
|
}
|
|
268
|
-
await service.trigger({ type: 'authenticateWithMessage' }, {
|
|
269
|
-
contactType,
|
|
270
|
-
contact,
|
|
271
|
-
messageData,
|
|
272
|
-
action: 'inviteWithMessage',
|
|
273
|
-
actionProperties: { objectType, object },
|
|
274
|
-
targetPage: { name: 'accessControl:invitationAccepted', params: { objectType, object } },
|
|
275
|
-
fallbackPage: { name: 'accessControl:invitationFallback', params: { objectType, object } }
|
|
276
|
-
})
|
|
277
|
-
emit({
|
|
278
|
-
type: 'contactInvited',
|
|
279
|
-
contactType: contactTypeName + '_' + contactTypeUName,
|
|
280
|
-
contact,
|
|
281
|
-
objectType, object,
|
|
282
|
-
...invitationData, id: undefined
|
|
283
|
-
})
|
|
284
391
|
}
|
|
392
|
+
},
|
|
393
|
+
access: (params, { client, context, visibilityTest}) =>
|
|
394
|
+
visibilityTest || access.clientCanInvite(client, params),
|
|
395
|
+
async execute(params, { client, service, trigger, command }, emit) {
|
|
396
|
+
const { [contactTypeName]: contact } = params
|
|
397
|
+
const { objectType, object } = params
|
|
398
|
+
|
|
399
|
+
const myRoles = await access.getClientObjectRoles(client, { objectType, object }, true)
|
|
400
|
+
if(!myRoles.includes('admin')) {
|
|
401
|
+
for(const requestedRole of roles) {
|
|
402
|
+
if(!myRoles.includes(requestedRole)) throw 'notAuthorized'
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const [ fromType, from ] = client.user ? ['user_User', client.user] : ['session_Session', client.session]
|
|
407
|
+
|
|
408
|
+
await inviteManyTask.start({
|
|
409
|
+
...params,
|
|
410
|
+
fromType, from,
|
|
411
|
+
ownerType: objectType,
|
|
412
|
+
owner: object,
|
|
413
|
+
}, 'action', command.id )
|
|
285
414
|
}
|
|
286
415
|
})
|
|
287
416
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/access-control-service",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.120",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"url": "https://www.viamage.com/"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@live-change/framework": "^0.8.
|
|
24
|
+
"@live-change/framework": "^0.8.120"
|
|
25
25
|
},
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "adf31fd8365df0655d88293f96a93734058d3dd4",
|
|
27
27
|
"type": "module"
|
|
28
28
|
}
|