@memberjunction/server 6.1.0-edge.5 → 6.1.0-edge.7
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/README.md +30 -11
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.js +2 -2
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
- package/dist/auth/exampleNewUserSubClass.js +9 -4
- package/dist/auth/exampleNewUserSubClass.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +2 -8
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +4 -12
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/auth/principals.d.ts +92 -0
- package/dist/auth/principals.d.ts.map +1 -0
- package/dist/auth/principals.js +193 -0
- package/dist/auth/principals.js.map +1 -0
- package/dist/config.d.ts +106 -12
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -4
- package/dist/config.js.map +1 -1
- package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.d.ts +30 -0
- package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.d.ts.map +1 -1
- package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.js +58 -5
- package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +7607 -6853
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +25141 -21645
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +152 -2
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +389 -10
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +26 -2
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/refusalExtensions.d.ts +52 -0
- package/dist/generic/refusalExtensions.d.ts.map +1 -0
- package/dist/generic/refusalExtensions.js +16 -0
- package/dist/generic/refusalExtensions.js.map +1 -0
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +131 -93
- package/dist/index.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +2 -12
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +20 -5
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +34 -5
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +64 -7
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -2
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -0
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -2
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +80 -4
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +13 -8
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +45 -8
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +11 -2
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +8 -4
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +2 -1
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +3 -18
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts +2 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +3 -16
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts +23 -0
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeSdpBrokerHandler.js +78 -0
- package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -0
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +2 -3
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/package.json +92 -91
- package/src/__tests__/EntityCRUDHandler.test.ts +18 -5
- package/src/__tests__/EntityRecordNameResolver.fieldSecurity.test.ts +118 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +20 -0
- package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +191 -0
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +81 -2
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +190 -3
- package/src/__tests__/ResolverBase.readableFieldsTransport.test.ts +106 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +114 -0
- package/src/__tests__/WidgetSessionService.test.ts +4 -1
- package/src/__tests__/generatedGraphQLSchema.structural.test.ts +46 -0
- package/src/__tests__/newUserRolesDefault.test.ts +81 -0
- package/src/__tests__/newUsers.test.ts +36 -14
- package/src/__tests__/principals.callSites.test.ts +112 -0
- package/src/__tests__/principals.logging.test.ts +160 -0
- package/src/__tests__/principals.test.ts +305 -0
- package/src/__tests__/resolverBase.fls.test.ts +483 -0
- package/src/__tests__/resolverBase.recordChangesFls.test.ts +358 -0
- package/src/__tests__/resolverBase.refusalExtensions.test.ts +101 -0
- package/src/__tests__/resolverBase.refusalMessage.test.ts +88 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +79 -11
- package/src/__tests__/visitorIdentity.resolve.test.ts +61 -0
- package/src/agentSessions/SessionJanitor.ts +2 -2
- package/src/auth/exampleNewUserSubClass.ts +9 -6
- package/src/auth/magicLink/MagicLinkService.ts +2 -8
- package/src/auth/newUsers.ts +7 -15
- package/src/auth/principals.ts +257 -0
- package/src/config.ts +44 -4
- package/src/entitySubclasses/MJEntityPermissionEntityServer.server.ts +65 -6
- package/src/generated/graphql-schemas/__mj.ts +18966 -16452
- package/src/generic/ResolverBase.ts +467 -9
- package/src/generic/RunViewResolver.ts +28 -2
- package/src/generic/refusalExtensions.ts +59 -0
- package/src/index.ts +154 -102
- package/src/realtimeWidget/WidgetSessionService.ts +2 -14
- package/src/realtimeWidget/visitorIdentity.ts +21 -6
- package/src/resolvers/EntityRecordNameResolver.ts +74 -8
- package/src/resolvers/FileCategoryResolver.ts +2 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -0
- package/src/resolvers/QuerySystemUserResolver.ts +1 -1
- package/src/resolvers/RealtimeClientSessionResolver.ts +128 -2
- package/src/resolvers/RemoteBrowserActionResolver.ts +47 -8
- package/src/resolvers/SyncRolesUsersResolver.ts +11 -2
- package/src/resolvers/UserViewResolver.ts +8 -4
- package/src/rest/EntityCRUDHandler.ts +3 -19
- package/src/rest/RESTEndpointHandler.ts +3 -17
- package/src/rest/RealtimeSdpBrokerHandler.ts +101 -0
- package/src/serverExtensionReservedRoots.ts +2 -3
- package/dist/resolvers/RingCentralTelephonyResolver.d.ts +0 -27
- package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +0 -1
- package/dist/resolvers/RingCentralTelephonyResolver.js +0 -87
- package/dist/resolvers/RingCentralTelephonyResolver.js.map +0 -1
- package/dist/resolvers/TeamsMeetingsResolver.d.ts +0 -28
- package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +0 -1
- package/dist/resolvers/TeamsMeetingsResolver.js +0 -91
- package/dist/resolvers/TeamsMeetingsResolver.js.map +0 -1
- package/dist/resolvers/TelephonyResolver.d.ts +0 -26
- package/dist/resolvers/TelephonyResolver.d.ts.map +0 -1
- package/dist/resolvers/TelephonyResolver.js +0 -86
- package/dist/resolvers/TelephonyResolver.js.map +0 -1
- package/dist/resolvers/VonageTelephonyResolver.d.ts +0 -26
- package/dist/resolvers/VonageTelephonyResolver.d.ts.map +0 -1
- package/dist/resolvers/VonageTelephonyResolver.js +0 -86
- package/dist/resolvers/VonageTelephonyResolver.js.map +0 -1
- package/dist/telephony/RingCentralTelephonyService.d.ts +0 -115
- package/dist/telephony/RingCentralTelephonyService.d.ts.map +0 -1
- package/dist/telephony/RingCentralTelephonyService.js +0 -262
- package/dist/telephony/RingCentralTelephonyService.js.map +0 -1
- package/dist/telephony/TeamsMeetingsRouter.d.ts +0 -40
- package/dist/telephony/TeamsMeetingsRouter.d.ts.map +0 -1
- package/dist/telephony/TeamsMeetingsRouter.js +0 -96
- package/dist/telephony/TeamsMeetingsRouter.js.map +0 -1
- package/dist/telephony/TeamsMeetingsService.d.ts +0 -113
- package/dist/telephony/TeamsMeetingsService.d.ts.map +0 -1
- package/dist/telephony/TeamsMeetingsService.js +0 -196
- package/dist/telephony/TeamsMeetingsService.js.map +0 -1
- package/dist/telephony/TwilioTelephonyRouter.d.ts +0 -36
- package/dist/telephony/TwilioTelephonyRouter.d.ts.map +0 -1
- package/dist/telephony/TwilioTelephonyRouter.js +0 -143
- package/dist/telephony/TwilioTelephonyRouter.js.map +0 -1
- package/dist/telephony/TwilioTelephonyService.d.ts +0 -95
- package/dist/telephony/TwilioTelephonyService.d.ts.map +0 -1
- package/dist/telephony/TwilioTelephonyService.js +0 -193
- package/dist/telephony/TwilioTelephonyService.js.map +0 -1
- package/dist/telephony/VonageTelephonyRouter.d.ts +0 -41
- package/dist/telephony/VonageTelephonyRouter.d.ts.map +0 -1
- package/dist/telephony/VonageTelephonyRouter.js +0 -201
- package/dist/telephony/VonageTelephonyRouter.js.map +0 -1
- package/dist/telephony/VonageTelephonyService.d.ts +0 -90
- package/dist/telephony/VonageTelephonyService.d.ts.map +0 -1
- package/dist/telephony/VonageTelephonyService.js +0 -191
- package/dist/telephony/VonageTelephonyService.js.map +0 -1
- package/dist/telephony/calendar-scheduler.d.ts +0 -67
- package/dist/telephony/calendar-scheduler.d.ts.map +0 -1
- package/dist/telephony/calendar-scheduler.js +0 -133
- package/dist/telephony/calendar-scheduler.js.map +0 -1
- package/dist/telephony/index.d.ts +0 -29
- package/dist/telephony/index.d.ts.map +0 -1
- package/dist/telephony/index.js +0 -38
- package/dist/telephony/index.js.map +0 -1
- package/dist/telephony/media-upgrade-router.d.ts +0 -47
- package/dist/telephony/media-upgrade-router.d.ts.map +0 -1
- package/dist/telephony/media-upgrade-router.js +0 -72
- package/dist/telephony/media-upgrade-router.js.map +0 -1
- package/dist/telephony/ringcentral-runtime.d.ts +0 -14
- package/dist/telephony/ringcentral-runtime.d.ts.map +0 -1
- package/dist/telephony/ringcentral-runtime.js +0 -18
- package/dist/telephony/ringcentral-runtime.js.map +0 -1
- package/dist/telephony/teams-meetings-runtime.d.ts +0 -16
- package/dist/telephony/teams-meetings-runtime.d.ts.map +0 -1
- package/dist/telephony/teams-meetings-runtime.js +0 -20
- package/dist/telephony/teams-meetings-runtime.js.map +0 -1
- package/dist/telephony/teamsAcsMediaRegistry.d.ts +0 -69
- package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +0 -1
- package/dist/telephony/teamsAcsMediaRegistry.js +0 -118
- package/dist/telephony/teamsAcsMediaRegistry.js.map +0 -1
- package/dist/telephony/telephony-runtime.d.ts +0 -14
- package/dist/telephony/telephony-runtime.d.ts.map +0 -1
- package/dist/telephony/telephony-runtime.js +0 -18
- package/dist/telephony/telephony-runtime.js.map +0 -1
- package/dist/telephony/twilioMediaRegistry.d.ts +0 -60
- package/dist/telephony/twilioMediaRegistry.d.ts.map +0 -1
- package/dist/telephony/twilioMediaRegistry.js +0 -106
- package/dist/telephony/twilioMediaRegistry.js.map +0 -1
- package/dist/telephony/vonage-runtime.d.ts +0 -14
- package/dist/telephony/vonage-runtime.d.ts.map +0 -1
- package/dist/telephony/vonage-runtime.js +0 -18
- package/dist/telephony/vonage-runtime.js.map +0 -1
- package/dist/telephony/vonageMediaRegistry.d.ts +0 -78
- package/dist/telephony/vonageMediaRegistry.d.ts.map +0 -1
- package/dist/telephony/vonageMediaRegistry.js +0 -158
- package/dist/telephony/vonageMediaRegistry.js.map +0 -1
- package/src/__tests__/media-upgrade-router.test.ts +0 -43
- package/src/__tests__/teams-meetings-service.test.ts +0 -65
- package/src/__tests__/teamsAcsMediaRegistry.test.ts +0 -82
- package/src/__tests__/twilio-telephony-service.test.ts +0 -23
- package/src/__tests__/twilioMediaRegistry.test.ts +0 -103
- package/src/__tests__/vonageMediaRegistry.test.ts +0 -180
- package/src/resolvers/RingCentralTelephonyResolver.ts +0 -64
- package/src/resolvers/TeamsMeetingsResolver.ts +0 -68
- package/src/resolvers/TelephonyResolver.ts +0 -63
- package/src/resolvers/VonageTelephonyResolver.ts +0 -63
- package/src/telephony/RingCentralTelephonyService.ts +0 -342
- package/src/telephony/TeamsMeetingsRouter.ts +0 -124
- package/src/telephony/TeamsMeetingsService.ts +0 -268
- package/src/telephony/TwilioTelephonyRouter.ts +0 -184
- package/src/telephony/TwilioTelephonyService.ts +0 -261
- package/src/telephony/VonageTelephonyRouter.ts +0 -239
- package/src/telephony/VonageTelephonyService.ts +0 -259
- package/src/telephony/calendar-scheduler.ts +0 -176
- package/src/telephony/index.ts +0 -43
- package/src/telephony/media-upgrade-router.ts +0 -79
- package/src/telephony/ringcentral-runtime.ts +0 -22
- package/src/telephony/teams-meetings-runtime.ts +0 -24
- package/src/telephony/teamsAcsMediaRegistry.ts +0 -152
- package/src/telephony/telephony-runtime.ts +0 -22
- package/src/telephony/twilioMediaRegistry.ts +0 -137
- package/src/telephony/vonage-runtime.ts +0 -22
- package/src/telephony/vonageMediaRegistry.ts +0 -200
package/src/config.ts
CHANGED
|
@@ -25,6 +25,14 @@ const userHandlingInfoSchema = z.object({
|
|
|
25
25
|
newUserRoles: z.array(z.string()).optional().default([]),
|
|
26
26
|
updateCacheWhenNotFound: z.boolean().optional().default(false),
|
|
27
27
|
updateCacheWhenNotFoundDelay: z.number().optional().default(30000),
|
|
28
|
+
/**
|
|
29
|
+
* The internal user whose context creates new user records. Matched against `User.Name` FIRST,
|
|
30
|
+
* then `User.Email` — so either spelling of an existing user resolves. On a stock database the
|
|
31
|
+
* system user is `Name='System'` / `Email='not.set@nowhere.com'`; both reach it.
|
|
32
|
+
*
|
|
33
|
+
* When unset, or when the value matches no user, resolution falls back to the system user and
|
|
34
|
+
* then to the lowest-ID active Owner. See `src/auth/principals.ts`.
|
|
35
|
+
*/
|
|
28
36
|
contextUserForNewUserCreation: z.string().optional().default(''),
|
|
29
37
|
CreateUserApplicationRecords: z.boolean().optional().default(false),
|
|
30
38
|
UserApplications: z.array(z.string()).optional().default([]),
|
|
@@ -328,7 +336,11 @@ const magicLinkSchema = z.object({
|
|
|
328
336
|
* from attaching a privileged role (e.g. Owner) to an external magic-link user.
|
|
329
337
|
*/
|
|
330
338
|
grantableRoleNames: z.array(z.string()).optional().default([]),
|
|
331
|
-
/**
|
|
339
|
+
/**
|
|
340
|
+
* The internal user whose context provisions magic-link users, matched against `User.Name` then
|
|
341
|
+
* `User.Email` (falls back to `userHandling.contextUserForNewUserCreation`, then to the system
|
|
342
|
+
* user, then to the lowest-ID active Owner).
|
|
343
|
+
*/
|
|
332
344
|
contextUserForProvisioning: z.string().optional(),
|
|
333
345
|
/**
|
|
334
346
|
* Guard against bolting an external magic-link role/app onto an EXISTING account
|
|
@@ -391,7 +403,10 @@ const widgetSchema = z.object({
|
|
|
391
403
|
rateLimitWindowMs: z.coerce.number().optional().default(60_000),
|
|
392
404
|
/** Server-wide default hard ceiling (minutes) on a voice session when an instance omits one (W4). */
|
|
393
405
|
voiceDefaultMaxSessionMinutes: z.coerce.number().optional().default(10),
|
|
394
|
-
/**
|
|
406
|
+
/**
|
|
407
|
+
* The internal user whose context READS widget config at mint time, matched against `User.Name`
|
|
408
|
+
* then `User.Email` (falls back to the system user, then the lowest-ID active Owner).
|
|
409
|
+
*/
|
|
395
410
|
contextUserForLookup: z.string().optional(),
|
|
396
411
|
/**
|
|
397
412
|
* Host-identity public keys (PEM), keyed by widget PublicKey, for the `host-identity` auth
|
|
@@ -524,11 +539,17 @@ const telephonySchema = z.object({
|
|
|
524
539
|
teams: teamsMeetingsSchema.optional(),
|
|
525
540
|
}).passthrough();
|
|
526
541
|
|
|
542
|
+
const realtimeSchema = z.object({
|
|
543
|
+
/** Master switch. When false (default), the WebRTC SDP broker router is not mounted. */
|
|
544
|
+
enabled: zodBooleanWithTransforms().default(false),
|
|
545
|
+
}).passthrough();
|
|
546
|
+
|
|
527
547
|
const configInfoSchema = z.object({
|
|
528
548
|
userHandling: userHandlingInfoSchema,
|
|
529
549
|
magicLink: magicLinkSchema.optional().default({}),
|
|
530
550
|
widget: widgetSchema.optional().default({}),
|
|
531
551
|
telephony: telephonySchema.optional().default({}),
|
|
552
|
+
realtime: realtimeSchema.optional().default({}),
|
|
532
553
|
databaseSettings: databaseSettingsInfoSchema,
|
|
533
554
|
viewingSystem: viewingSystemInfoSchema.optional(),
|
|
534
555
|
restApiOptions: restApiOptionsSchema.optional().default({}),
|
|
@@ -583,6 +604,7 @@ export type UserHandlingInfo = z.infer<typeof userHandlingInfoSchema>;
|
|
|
583
604
|
export type MagicLinkConfig = z.infer<typeof magicLinkSchema>;
|
|
584
605
|
export type WidgetConfig = z.infer<typeof widgetSchema>;
|
|
585
606
|
export type TelephonyConfig = z.infer<typeof telephonySchema>;
|
|
607
|
+
export type RealtimeConfig = z.infer<typeof realtimeSchema>;
|
|
586
608
|
export type TwilioTelephonyConfig = z.infer<typeof twilioTelephonySchema>;
|
|
587
609
|
export type VonageTelephonyConfig = z.infer<typeof vonageTelephonySchema>;
|
|
588
610
|
export type RingCentralTelephonyConfig = z.infer<typeof ringcentralTelephonySchema>;
|
|
@@ -648,10 +670,23 @@ export const DEFAULT_SERVER_CONFIG: Partial<ConfigInfo> = {
|
|
|
648
670
|
autoCreateNewUsers: true,
|
|
649
671
|
newUserLimitedToAuthorizedDomains: false,
|
|
650
672
|
newUserAuthorizedDomains: [],
|
|
651
|
-
|
|
673
|
+
// 'UI' ONLY, deliberately (issue #4260). Auto-provisioning is on by default above, with no
|
|
674
|
+
// domain restriction, so this list is the standing authority of anyone the configured IdP will
|
|
675
|
+
// issue a token for. On the baseline seed 'Developer' and 'Integration' hold unfiltered
|
|
676
|
+
// CanUpdate on ~439 of the database's ~446 entities, so defaulting every such identity into
|
|
677
|
+
// either grants broad data-plane access no host should hand out by default. (The MJ: Users
|
|
678
|
+
// escalation this list also used to guard against — writing your own Type to 'Owner' — is now
|
|
679
|
+
// closed at the entity layer regardless of role: see MJUserEntityServer in
|
|
680
|
+
// @memberjunction/core-entities-server.) 'UI' carries the end-user surface (conversations,
|
|
681
|
+
// views, dashboards, settings) and no write on MJ: Users. Hosts that need more grant it
|
|
682
|
+
// per-deployment.
|
|
683
|
+
newUserRoles: ['UI'],
|
|
652
684
|
updateCacheWhenNotFound: true,
|
|
653
685
|
updateCacheWhenNotFoundDelay: 5000,
|
|
654
|
-
|
|
686
|
+
// The seeded system user, named by `Name`. Its Email ('not.set@nowhere.com') resolves too —
|
|
687
|
+
// resolution tries both columns — but naming it this way keeps the default readable as what it
|
|
688
|
+
// is, rather than as an address nobody can receive mail at.
|
|
689
|
+
contextUserForNewUserCreation: 'System',
|
|
655
690
|
CreateUserApplicationRecords: true,
|
|
656
691
|
UserApplications: []
|
|
657
692
|
},
|
|
@@ -716,6 +751,11 @@ export const DEFAULT_SERVER_CONFIG: Partial<ConfigInfo> = {
|
|
|
716
751
|
maxConcurrentRuns: 3
|
|
717
752
|
},
|
|
718
753
|
|
|
754
|
+
// Realtime WebRTC SDP broker defaults (off by default)
|
|
755
|
+
realtime: {
|
|
756
|
+
enabled: parseBooleanEnv(process.env.MJ_REALTIME_ENABLED),
|
|
757
|
+
},
|
|
758
|
+
|
|
719
759
|
// Telemetry defaults — on unless the operator turns it off via MJ_TELEMETRY_ENABLED.
|
|
720
760
|
//
|
|
721
761
|
// The env read lives HERE rather than in telemetrySchema for the same reason as
|
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
2
|
-
import { BaseEntity, EntityDeleteOptions, EntitySaveOptions } from '@memberjunction/core';
|
|
1
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
2
|
+
import { BaseEntity, EntityDeleteOptions, EntitySaveOptions, IMetadataProvider } from '@memberjunction/core';
|
|
3
3
|
import { MJEntityPermissionEntity } from '@memberjunction/core-entities';
|
|
4
4
|
import { HttpPost } from '@memberjunction/network-utils';
|
|
5
|
+
import { ReconcileFieldPermissionsQuietly } from '@memberjunction/core-entities-server';
|
|
5
6
|
import { ___codeGenAPIPort, ___codeGenAPISubmissionDelay, ___codeGenAPIURL } from '../config.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Server-side only class that extends the entity permissions object to watch for changes to entity permissions, build a queue of entities that have been changed, and then from time to time, submit
|
|
9
10
|
* them to an API server that will execute the underlying permission changes at the database level.
|
|
10
|
-
*
|
|
11
|
+
*
|
|
12
|
+
* It is also the field-level-security lifecycle adapter for entity-permission changes. Snapshot
|
|
13
|
+
* initialization creates field-permission rows for the roles holding entity access AT THE TIME
|
|
14
|
+
* the flag is flipped; a role granted access afterwards has none, and on an enabled entity a
|
|
15
|
+
* field with no rows is denied — so that role would pass the entity gate and then see zero
|
|
16
|
+
* fields, which reads as a broken screen rather than a permissions gap. The reverse matters
|
|
17
|
+
* too: a role that loses entity access leaves rows that can no longer affect any decision.
|
|
18
|
+
*
|
|
19
|
+
* Both responsibilities live here because `ClassFactory` resolves ONE class per entity name.
|
|
20
|
+
* A second `@RegisterClass(BaseEntity, 'MJ: Entity Permissions')` in another package would not
|
|
21
|
+
* compose with this one — priority auto-increments by load order, so whichever loaded last
|
|
22
|
+
* would silently displace the other.
|
|
23
|
+
*
|
|
11
24
|
* This class is within the memberjunction/server package because it is closely coupled to other aspects of what
|
|
12
25
|
* happens in the server. That's why it is not in the core-entities-server package.
|
|
13
26
|
*/
|
|
@@ -88,19 +101,65 @@ export class MJEntityPermissionEntityServer extends MJEntityPermissionEntity {
|
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
|
|
91
|
-
override Save(options?: EntitySaveOptions): Promise<boolean> {
|
|
104
|
+
override async Save(options?: EntitySaveOptions): Promise<boolean> {
|
|
92
105
|
// simply queue up the entity ID
|
|
93
106
|
if (this.Dirty || options?.IgnoreDirtyState) MJEntityPermissionEntityServer.AddToQueue(this.EntityID);
|
|
94
107
|
|
|
95
|
-
|
|
108
|
+
// Capture before the save — afterwards nothing is dirty and the dirty check reads false.
|
|
109
|
+
const affectsFieldSecurity = this.affectsFieldPermissionRows();
|
|
110
|
+
|
|
111
|
+
if (!(await super.Save(options))) return false;
|
|
112
|
+
|
|
113
|
+
if (affectsFieldSecurity) await this.reconcileFieldPermissions(this.EntityID);
|
|
114
|
+
return true;
|
|
96
115
|
}
|
|
97
116
|
|
|
98
117
|
override async Delete(options: EntityDeleteOptions): Promise<boolean> {
|
|
118
|
+
// Capture before the delete — afterwards this record's EntityID is gone.
|
|
119
|
+
const targetEntityID = this.EntityID;
|
|
120
|
+
|
|
99
121
|
const success = await super.Delete(options);
|
|
100
122
|
|
|
101
123
|
// simply queue up the entity ID if the delete worked
|
|
102
|
-
if (success)
|
|
124
|
+
if (success) {
|
|
125
|
+
MJEntityPermissionEntityServer.AddToQueue(targetEntityID);
|
|
126
|
+
await this.reconcileFieldPermissions(targetEntityID);
|
|
127
|
+
}
|
|
103
128
|
|
|
104
129
|
return success;
|
|
105
130
|
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether this save can change which field-permission rows should exist.
|
|
134
|
+
*
|
|
135
|
+
* Only the access flags and the role matter — the field-permission delta keys off a role's
|
|
136
|
+
* effective entity-level access, so an edit to an RLS filter changes nothing here. A new
|
|
137
|
+
* record always counts, since it may be the grant that brings a role into scope.
|
|
138
|
+
*/
|
|
139
|
+
protected affectsFieldPermissionRows(): boolean {
|
|
140
|
+
if (!this.IsSaved) return true;
|
|
141
|
+
|
|
142
|
+
return ['Type', 'CanRead', 'CanUpdate', 'CanCreate', 'RoleID'].some(
|
|
143
|
+
(fieldName) => this.GetFieldByName(fieldName)?.Dirty === true
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Reconciles the target entity's field-permission rows, when that entity has field security
|
|
149
|
+
* switched on. The flag check keeps this free for the overwhelming majority of permission
|
|
150
|
+
* edits, which are on entities that never opted in.
|
|
151
|
+
*
|
|
152
|
+
* Runs AFTER the permission write commits, and failures are logged rather than thrown: the
|
|
153
|
+
* save that triggered it has already succeeded, so reporting it as failed would be wrong.
|
|
154
|
+
* Missing rows fail closed until the next reconciliation.
|
|
155
|
+
*/
|
|
156
|
+
protected async reconcileFieldPermissions(entityID: string): Promise<void> {
|
|
157
|
+
if (!entityID) return;
|
|
158
|
+
|
|
159
|
+
const provider = this.ProviderToUse as unknown as IMetadataProvider;
|
|
160
|
+
const entityInfo = provider?.Entities?.find((e) => UUIDsEqual(e.ID, entityID));
|
|
161
|
+
if (!entityInfo?.EnableFieldLevelSecurity) return;
|
|
162
|
+
|
|
163
|
+
await ReconcileFieldPermissionsQuietly(entityInfo, provider, this.ContextCurrentUser);
|
|
164
|
+
}
|
|
106
165
|
}
|