@7365admin1/core 3.32.2-staging.66 → 3.32.2-staging.67

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.
@@ -0,0 +1,45 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ Let camera authorization understand engagements, and resolve it against the
6
+ right organisation.
7
+
8
+ Three defects in the same decision, fixed together because they are the same
9
+ question: "may this person reach this site, and on whose behalf?"
10
+
11
+ **1. An engagement was not an entitlement.** The product routes a service
12
+ provider - a security agency, a property management agency - to a customer's
13
+ site through an ACTIVE `customer.sites` record (`{org: provider, siteOrg: owner,
14
+ site}`). 227 of those are active on staging, 53 of them cross-organisation. It
15
+ is the same list the web apps' own site switcher is drawn from
16
+ (`useCustomerSite().getAll()`). No camera authorization code read it, so a guard
17
+ whose agency is contracted at a site was refused the cameras of the site the
18
+ switcher had just offered them. Measured on staging: **11 people reach a site
19
+ holding an active IP camera by this route and no other, 7 of them on wildcard
20
+ `owner` / `Super Admin` roles** - and across all 200 sites the figure is 125
21
+ people, 43 of them on wildcard roles. Nobody loses access; the change is
22
+ additive.
23
+
24
+ **2. `site.org` does not exist.** `authorizeSite` and `authorizeCamera`
25
+ projected `{org: 1}` and tested `site?.org`. All 200 site documents carry
26
+ `orgId`; not one carries `org`. So the org-level branch of the rule - the branch
27
+ for the 90 membership rows (56 people) that carry no `siteId` - could never
28
+ match. It reads `orgId` now, with `org` kept as a fallback. This WIDENS access,
29
+ so it was measured before it was enabled: on staging it admits **0** additional
30
+ people to a site holding a camera, and 14 across all 200 sites.
31
+
32
+ **3. Permissions resolved against an arbitrary organisation.**
33
+ `getUserPermissions({user, org: memberships[0]?.org})` took whichever membership
34
+ Mongo returned first, which for the 22 people who belong to more than one
35
+ organisation is a coin toss - it could read the permissions of an organisation
36
+ that has nothing to do with the site being asked about. It now resolves against
37
+ the membership that actually granted access.
38
+
39
+ Also splits `entitleSite` (may this person reach this site) out of
40
+ `authorizeSite` (that, plus the permission this particular use needs), so a
41
+ plain read of a site's own camera list can be scoped without also being gated on
42
+ a permission that would strand people who are legitimately at the site.
43
+
44
+ No response field changed. No route changed. No device is contacted by any of
45
+ this.
package/dist/index.d.ts CHANGED
@@ -2654,23 +2654,53 @@ declare const CAMERA_VIEW_PERMISSIONS: string[];
2654
2654
  declare const CAMERA_PTZ_PERMISSIONS: string[];
2655
2655
  /** `*` is the estate's wildcard permission and is honoured everywhere else too. */
2656
2656
  declare function hasAnyPermission(permissions: unknown, allowed: Array<string>): boolean;
2657
+ /** One row of `members`, as much of it as an entitlement decision needs. */
2658
+ type CameraMembership = {
2659
+ siteId?: unknown;
2660
+ org?: unknown;
2661
+ };
2657
2662
  /**
2658
- * May this caller reach this camera?
2663
+ * WHICH membership lets this caller reach this site, or `null` for none.
2664
+ *
2665
+ * Three sources, in order of how directly they say "this person works here":
2659
2666
  *
2660
- * The id comes from the URL, so it is an untrusted input and is never the thing
2661
- * that decides. What decides is the caller's membership: the camera's SITE must
2662
- * be one they are a member of, or for a membership recorded at org level, with
2663
- * no site on it the camera's site must belong to that org.
2667
+ * 1. **A membership at the site itself** (`members.siteId`). 277 of the 367 live
2668
+ * membership rows are recorded this way.
2669
+ * 2. **A membership at the site's OWNING organisation, with no site on it**
2670
+ * an org-wide role. 90 rows, 56 people, are recorded this way.
2671
+ * 3. **An engagement** — an ACTIVE `customer.sites` row saying one of the
2672
+ * caller's organisations is contracted to serve this site. This is how the
2673
+ * product routes a security agency to a property manager's site, and it is
2674
+ * the list the web apps' own site switcher is built from
2675
+ * (`useCustomerSite().getAll()` in the Security app's layout). Nothing in the
2676
+ * camera path read it before, so a guard whose agency is engaged at a site
2677
+ * was refused a camera the switcher had just offered them.
2678
+ *
2679
+ * The membership is RETURNED, not just a yes/no, because the caller's
2680
+ * permissions must then be resolved against the organisation that actually
2681
+ * granted access — see `getUserPermissions` in the service. Resolving them
2682
+ * against an arbitrary row (`memberships[0]`) is wrong for the 22 people who
2683
+ * belong to more than one organisation.
2664
2684
  *
2665
2685
  * Ids are compared as strings so an ObjectId and its hex form match.
2666
2686
  */
2687
+ declare function cameraGrant(params: {
2688
+ cameraSite?: unknown;
2689
+ cameraOrg?: unknown;
2690
+ memberships: Array<CameraMembership>;
2691
+ /**
2692
+ * The caller's organisations that hold an ACTIVE engagement to THIS site.
2693
+ * The query that fills it is already scoped to the site, so membership of one
2694
+ * of these organisations is the whole test here.
2695
+ */
2696
+ engagedOrgs?: Set<string>;
2697
+ }): CameraMembership | null;
2698
+ /** `cameraGrant` as a yes/no, for the places that do not need to know which. */
2667
2699
  declare function isCameraEntitled(params: {
2668
2700
  cameraSite?: unknown;
2669
2701
  cameraOrg?: unknown;
2670
- memberships: Array<{
2671
- siteId?: unknown;
2672
- org?: unknown;
2673
- }>;
2702
+ memberships: Array<CameraMembership>;
2703
+ engagedOrgs?: Set<string>;
2674
2704
  }): boolean;
2675
2705
  /**
2676
2706
  * Why this camera cannot serve a picture, or `null` when it can.
@@ -3361,6 +3391,18 @@ declare function useCameraViewService(): {
3361
3391
  userId?: string;
3362
3392
  permissions: Array<string>;
3363
3393
  }) => Promise<bson.Document>;
3394
+ entitleSite: (params: {
3395
+ siteId: string;
3396
+ userId?: string;
3397
+ }) => Promise<{
3398
+ site: mongodb.WithId<bson.Document> | null;
3399
+ siteObjectId: ObjectId;
3400
+ db: Db;
3401
+ memberships: (CameraMembership & {
3402
+ org?: ObjectId | undefined;
3403
+ })[];
3404
+ grant: CameraMembership;
3405
+ }>;
3364
3406
  authorizeSite: (params: {
3365
3407
  siteId: string;
3366
3408
  userId?: string;
@@ -3373,7 +3415,7 @@ declare function useCameraViewService(): {
3373
3415
  }) => Promise<{
3374
3416
  site: mongodb.WithId<bson.Document> | null;
3375
3417
  siteObjectId: ObjectId;
3376
- db: mongodb.Db;
3418
+ db: Db;
3377
3419
  }>;
3378
3420
  testCameraAddress: (params: {
3379
3421
  siteId: string;
@@ -9333,4 +9375,4 @@ declare function useNotificationController(): {
9333
9375
  add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
9334
9376
  };
9335
9377
 
9336
- export { ANPRMode, AccessTypeProps, AppServiceType, AssignCardConfig, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, CAMERA_ANPR_PERMISSIONS, CAMERA_CAPABILITIES, CAMERA_CAPABILITY_REASONS, CAMERA_NOT_PATROL_OR_CCTV, CAMERA_PTZ_PERMISSIONS, CAMERA_REQUEST_TIMEOUT_MS, CAMERA_RTSP_TIMEOUT_MS, CAMERA_SETUP_PERMISSIONS, CAMERA_SNAPSHOT_CACHE_SECONDS, CAMERA_SNAPSHOT_MAX_BYTES, CAMERA_TEST_MIN_INTERVAL_SECONDS, CAMERA_TEST_ROUND_LIMIT, CAMERA_TEST_ROUND_SECONDS, CAMERA_TYPE_ANPR, CAMERA_TYPE_IP, CAMERA_VIEW_PERMISSIONS, CLOCK_DRIFT_WARN_SECONDS, CURRENT_TIME_ENDPOINT, Camera, CameraAddressInput, CameraCapability, CameraCapabilityContext, CameraCapabilityDescriptor, CameraCapabilityEntry, CameraCapabilityReason, CameraCapabilityState, CameraCapabilityTrace, CameraDevice, CameraTestStatus, CameraTransport, CameraType, DEVICE_STATUS, DOBStatus, DayOfWeek, DeviceHttpTarget, DeviceProbeResult, DynamicFormFields, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GuestSort, GuestStatus, HID_PERMISSION_CATEGORIES, IAccessCard, IAccessCardTransaction, MAX_CAMERA_CHANNEL, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MCustomer, MCustomerSite, MDocumentManagement, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MHidSitePermissions, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MNotification, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, NotificationAppSlug, NotificationModule, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PATROL_CCTV_CAMERA_FILTER, PERSON_TYPES, PStatus, PTZ_ALLOWED_ACTIONS, PTZ_ALLOWED_CODES, Period, PersonStatus, PersonType, PersonTypes, PostOrder, PostSort, PostStatus, QrTagProps, ResidentAppModuleKey, SOFTWARE_VERSION_ENDPOINT, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionType, TAccessMngmntSettings, TActionStatus, TAddress, TAffectedEntities, TAffectedInjured, TAppServiceType, TApprovedBy, TApprover, TAttendance, TAttendanceCheckIn, TAttendanceCheckOut, TAttendanceCheckTime, TAttendanceLocation, TAttendanceSettings, TAttendanceSettingsGetBySite, TAuthorities, TAuthoritiesCalled, TBidPreloved, TBilling, TBillingConfiguration, TBillingItem, TBuilding, TBuildingLevel, TBuildingUnit, TBulletinBoard, TBulletinVideo, TCamera, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoIdentity, THidAmicoReader, THidPermissionAssignment, THidPermissionCategory, THidSitePermissions, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TNotification, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPlaceOfIncident, TPlates, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoTier, TRANSPORT_DEVICE_HTTP, TRANSPORT_RELAY_PLAYER, TRANSPORT_RTSP_FRAME, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationMetadata, TVerificationMetadataV2, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UseAccessManagementRepo, UserStatus, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, attendanceSchema, attendanceSettingsSchema, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, cameraBaseUrl, cameraCapabilitiesFor, cameraDevices, cameraHealthSummary, cameraManagePermissions, cameraTransports, chatPrelovedEvents, chatSchema, clampPtzSpeed, clockDriftSeconds, createManpowerRemarksDaily, customerSchema, deriveCameraHost, describeCameraCapabilities, designationsSchema, deviceControlEnabled, deviceHttpEnabled, deviceHttpTargets, deviceHttpTimeoutMs, deviceProbeTtlSeconds, events_namespace_collection, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, ffmpegFrameArgs, ffmpegPath, formatCapabilityTrace, formatDahuaDate, guests_namespace_collection, hasAnyCapability, hasAnyPermission, incidentReport, incidentReportLog, incidents_namespace_collection, isCameraEntitled, isPatrolCctvCamera, isRelayPlayerUrl, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, mapWithLimit, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, occurrence_book_namespace_collection, online_forms_namespace_collection, orgSchema, overnight_parking_requests_namespace_collection, parseCameraChannel, parseCameraHost, parseDahuaFind, parseDeviceTime, parseSoftwareVersion, promoCodeSchema, ptzEndpoint, publicCameraFields, registerCameraTransport, relayForRecorder, remarksSchema, resetCameraTransports, residentAppModuleKeys, residentFormEntry, resolutionRefusalReason, resolveCamera, resolveDeviceHttp, robotSchema, rtspUrl, schema, schemaAppSlugNotification, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCreateNotification, schemaCustomerSite, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoConfiguration, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSiteIdParams, schemaHidAmicoSync, schemaHidAmicoUserImageParams, schemaHidAmicoVisitorQr, schemaHidPermissionCandidateQuery, schemaIncidentReport, schemaListNotification, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaNotification, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPlate, schemaPost, schemaPostFavorite, schemaServiceProvider, schemaServiceProviderBilling, schemaSignNfcPatrolLog, schemaSiteCamera, schemaSiteFacility, schemaSiteFacilityBooking, schemaStatementOfAccount, schemaSubcategoryPreloved, schemaUnitBilling, schemaUpdateBidPreloved, schemaUpdateBuildingLevel, schemaUpdateBulletinBoard, schemaUpdateBulletinVideo, schemaUpdateCategoryPreloved, schemaUpdateChatPreloved, schemaUpdateDocumentManagement, schemaUpdateEntryPassSettings, schemaUpdateEventManagement, schemaUpdateFolderManagement, schemaUpdateFormEntry, schemaUpdateGuestManagement, schemaUpdateHidAmicoIdentity, schemaUpdateHidAmicoReader, schemaUpdateHidSitePermissions, schemaUpdateIncidentReport, schemaUpdateNotification, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, sessionSchema, shiftSchema, siteSchema, site_people_namespace_collection, snapshotEndpoint, snapshotRefusalReason, updateRemarksStatusEod, updateRemarksisAcknowledged, updateSiteSchema, useAccessManagementController, useAddressRepo, useAttendanceController, useAttendanceRepository, useAttendanceSettingsController, useAttendanceSettingsRepository, useAttendanceSettingsService, useAuthController, useAuthControllerV2, useAuthService, useAuthServiceV2, useBidPrelovedController, useBidPrelovedRepo, useBidPrelovedService, useBuildingController, useBuildingLevelController, useBuildingLevelRepo, useBuildingLevelService, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useBulletinBoardController, useBulletinBoardRepo, useBulletinBoardService, useBulletinVideoController, useBulletinVideoRepo, useBulletinVideoService, useCameraViewController, useCameraViewService, useCategoryPrelovedController, useCategoryPrelovedRepo, useChannelPrelovedController, useChannelPrelovedRepo, useChatController, useChatPrelovedController, useChatPrelovedRepo, useChatPrelovedService, useChatRepo, useCounterModel, useCounterRepo, useCustomerController, useCustomerRepo, useCustomerSiteController, useCustomerSiteRepo, useCustomerSiteService, useDahuaService, useDashboardController, useDashboardRepo, useDocumentManagementController, useDocumentManagementRepo, useDocumentManagementService, useEntryPassSettingsController, useEntryPassSettingsRepo, useEventManagementController, useEventManagementRepo, useEventManagementService, useFeedbackController, useFeedbackRepo, useFeedbackService, useFileController, useFileRepo, useFileService, useFormEntryController, useFormEntryRepo, useGuestManagementController, useGuestManagementRepo, useGuestManagementService, useHidAmicoController, useHidAmicoRepo, useHidAmicoService, useHrmLabsAttendanceCtrl, useHrmLabsAttendanceSrvc, useIncidentReportController, useIncidentReportRepo, useIncidentReportService, useInvoiceController, useInvoiceModel, useInvoiceRepo, useManpowerDesignationCtrl, useManpowerDesignationRepo, useManpowerMonitoringCtrl, useManpowerMonitoringRepo, useManpowerMonitoringSrvc, useManpowerRemarkCtrl, useManpowerRemarksRepo, useManpowerSitesCtrl, useManpowerSitesRepo, useManpowerSitesSrvc, useMemberController, useMemberRepo, useMemberService, useNewDashboardController, useNewDashboardRepo, useNfcPatrolLogController, useNfcPatrolLogRepo, useNfcPatrolLogService, useNfcPatrolRouteController, useNfcPatrolRouteRepo, useNfcPatrolRouteService, useNfcPatrolSettingsController, useNfcPatrolSettingsRepository, useNfcPatrolSettingsService, useNfcPatrolTagController, useNfcPatrolTagRepo, useNfcPatrolTagService, useNotificationController, useNotificationRepo, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolLogController, usePatrolLogRepo, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePostFavoriteController, usePostFavoriteRepo, usePostFavoriteService, usePostPrelovedController, usePostPrelovedRepo, usePriceController, usePriceModel, usePriceRepo, usePromoCodeController, usePromoCodeRepo, useRedDotPaymentController, useRedDotPaymentRepo, useRedDotPaymentSvc, useRobotController, useRobotRepo, useRobotService, useRoleController, useRoleControllerV2, useRoleRepo, useRoleRepoV2, useRoleServiceV2, useServiceProviderBillingController, useServiceProviderBillingRepo, useServiceProviderBillingService, useServiceProviderController, useServiceProviderRepo, useSessionRepo, useSiteBillingConfigurationController, useSiteBillingConfigurationRepo, useSiteBillingItemController, useSiteBillingItemRepo, useSiteCameraController, useSiteCameraRepo, useSiteCameraService, useSiteController, useSiteFacilityBookingController, useSiteFacilityBookingRepo, useSiteFacilityBookingService, useSiteFacilityController, useSiteFacilityRepo, useSiteFacilityService, useSiteRepo, useSiteService, useSiteUnitBillingController, useSiteUnitBillingRepo, useSiteUnitBillingService, useStatementOfAccountController, useStatementOfAccountRepo, useSubcategoryPrelovedController, useSubcategoryPrelovedRepo, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useUserController, useUserControllerV2, useUserRepo, useUserRepoV2, useUserService, useUserServiceV2, useVehicleController, useVehicleRepo, useVehicleService, useVerificationController, useVerificationControllerV2, useVerificationRepo, useVerificationRepoV2, useVerificationService, useVerificationServiceV2, useVisitorTransactionController, useVisitorTransactionRepo, useVisitorTransactionService, useWorkOrderController, useWorkOrderRepo, useWorkOrderService, userSchema, vehicleSchema, vehicles_namespace_collection, visitorPersonRepo, visitorPersonService, visitorType, visitors_namespace_collection, wallConfig, workOrderSchema, work_orders2_namespace_collection, work_orders_namespace_collection };
9378
+ export { ANPRMode, AccessTypeProps, AppServiceType, AssignCardConfig, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, CAMERA_ANPR_PERMISSIONS, CAMERA_CAPABILITIES, CAMERA_CAPABILITY_REASONS, CAMERA_NOT_PATROL_OR_CCTV, CAMERA_PTZ_PERMISSIONS, CAMERA_REQUEST_TIMEOUT_MS, CAMERA_RTSP_TIMEOUT_MS, CAMERA_SETUP_PERMISSIONS, CAMERA_SNAPSHOT_CACHE_SECONDS, CAMERA_SNAPSHOT_MAX_BYTES, CAMERA_TEST_MIN_INTERVAL_SECONDS, CAMERA_TEST_ROUND_LIMIT, CAMERA_TEST_ROUND_SECONDS, CAMERA_TYPE_ANPR, CAMERA_TYPE_IP, CAMERA_VIEW_PERMISSIONS, CLOCK_DRIFT_WARN_SECONDS, CURRENT_TIME_ENDPOINT, Camera, CameraAddressInput, CameraCapability, CameraCapabilityContext, CameraCapabilityDescriptor, CameraCapabilityEntry, CameraCapabilityReason, CameraCapabilityState, CameraCapabilityTrace, CameraDevice, CameraMembership, CameraTestStatus, CameraTransport, CameraType, DEVICE_STATUS, DOBStatus, DayOfWeek, DeviceHttpTarget, DeviceProbeResult, DynamicFormFields, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GuestSort, GuestStatus, HID_PERMISSION_CATEGORIES, IAccessCard, IAccessCardTransaction, MAX_CAMERA_CHANNEL, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MCustomer, MCustomerSite, MDocumentManagement, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MHidSitePermissions, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MNotification, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, NotificationAppSlug, NotificationModule, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PATROL_CCTV_CAMERA_FILTER, PERSON_TYPES, PStatus, PTZ_ALLOWED_ACTIONS, PTZ_ALLOWED_CODES, Period, PersonStatus, PersonType, PersonTypes, PostOrder, PostSort, PostStatus, QrTagProps, ResidentAppModuleKey, SOFTWARE_VERSION_ENDPOINT, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionType, TAccessMngmntSettings, TActionStatus, TAddress, TAffectedEntities, TAffectedInjured, TAppServiceType, TApprovedBy, TApprover, TAttendance, TAttendanceCheckIn, TAttendanceCheckOut, TAttendanceCheckTime, TAttendanceLocation, TAttendanceSettings, TAttendanceSettingsGetBySite, TAuthorities, TAuthoritiesCalled, TBidPreloved, TBilling, TBillingConfiguration, TBillingItem, TBuilding, TBuildingLevel, TBuildingUnit, TBulletinBoard, TBulletinVideo, TCamera, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoIdentity, THidAmicoReader, THidPermissionAssignment, THidPermissionCategory, THidSitePermissions, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TNotification, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPlaceOfIncident, TPlates, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoTier, TRANSPORT_DEVICE_HTTP, TRANSPORT_RELAY_PLAYER, TRANSPORT_RTSP_FRAME, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationMetadata, TVerificationMetadataV2, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UseAccessManagementRepo, UserStatus, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, attendanceSchema, attendanceSettingsSchema, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, cameraBaseUrl, cameraCapabilitiesFor, cameraDevices, cameraGrant, cameraHealthSummary, cameraManagePermissions, cameraTransports, chatPrelovedEvents, chatSchema, clampPtzSpeed, clockDriftSeconds, createManpowerRemarksDaily, customerSchema, deriveCameraHost, describeCameraCapabilities, designationsSchema, deviceControlEnabled, deviceHttpEnabled, deviceHttpTargets, deviceHttpTimeoutMs, deviceProbeTtlSeconds, events_namespace_collection, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, ffmpegFrameArgs, ffmpegPath, formatCapabilityTrace, formatDahuaDate, guests_namespace_collection, hasAnyCapability, hasAnyPermission, incidentReport, incidentReportLog, incidents_namespace_collection, isCameraEntitled, isPatrolCctvCamera, isRelayPlayerUrl, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, mapWithLimit, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, occurrence_book_namespace_collection, online_forms_namespace_collection, orgSchema, overnight_parking_requests_namespace_collection, parseCameraChannel, parseCameraHost, parseDahuaFind, parseDeviceTime, parseSoftwareVersion, promoCodeSchema, ptzEndpoint, publicCameraFields, registerCameraTransport, relayForRecorder, remarksSchema, resetCameraTransports, residentAppModuleKeys, residentFormEntry, resolutionRefusalReason, resolveCamera, resolveDeviceHttp, robotSchema, rtspUrl, schema, schemaAppSlugNotification, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCreateNotification, schemaCustomerSite, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoConfiguration, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSiteIdParams, schemaHidAmicoSync, schemaHidAmicoUserImageParams, schemaHidAmicoVisitorQr, schemaHidPermissionCandidateQuery, schemaIncidentReport, schemaListNotification, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaNotification, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPlate, schemaPost, schemaPostFavorite, schemaServiceProvider, schemaServiceProviderBilling, schemaSignNfcPatrolLog, schemaSiteCamera, schemaSiteFacility, schemaSiteFacilityBooking, schemaStatementOfAccount, schemaSubcategoryPreloved, schemaUnitBilling, schemaUpdateBidPreloved, schemaUpdateBuildingLevel, schemaUpdateBulletinBoard, schemaUpdateBulletinVideo, schemaUpdateCategoryPreloved, schemaUpdateChatPreloved, schemaUpdateDocumentManagement, schemaUpdateEntryPassSettings, schemaUpdateEventManagement, schemaUpdateFolderManagement, schemaUpdateFormEntry, schemaUpdateGuestManagement, schemaUpdateHidAmicoIdentity, schemaUpdateHidAmicoReader, schemaUpdateHidSitePermissions, schemaUpdateIncidentReport, schemaUpdateNotification, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, sessionSchema, shiftSchema, siteSchema, site_people_namespace_collection, snapshotEndpoint, snapshotRefusalReason, updateRemarksStatusEod, updateRemarksisAcknowledged, updateSiteSchema, useAccessManagementController, useAddressRepo, useAttendanceController, useAttendanceRepository, useAttendanceSettingsController, useAttendanceSettingsRepository, useAttendanceSettingsService, useAuthController, useAuthControllerV2, useAuthService, useAuthServiceV2, useBidPrelovedController, useBidPrelovedRepo, useBidPrelovedService, useBuildingController, useBuildingLevelController, useBuildingLevelRepo, useBuildingLevelService, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useBulletinBoardController, useBulletinBoardRepo, useBulletinBoardService, useBulletinVideoController, useBulletinVideoRepo, useBulletinVideoService, useCameraViewController, useCameraViewService, useCategoryPrelovedController, useCategoryPrelovedRepo, useChannelPrelovedController, useChannelPrelovedRepo, useChatController, useChatPrelovedController, useChatPrelovedRepo, useChatPrelovedService, useChatRepo, useCounterModel, useCounterRepo, useCustomerController, useCustomerRepo, useCustomerSiteController, useCustomerSiteRepo, useCustomerSiteService, useDahuaService, useDashboardController, useDashboardRepo, useDocumentManagementController, useDocumentManagementRepo, useDocumentManagementService, useEntryPassSettingsController, useEntryPassSettingsRepo, useEventManagementController, useEventManagementRepo, useEventManagementService, useFeedbackController, useFeedbackRepo, useFeedbackService, useFileController, useFileRepo, useFileService, useFormEntryController, useFormEntryRepo, useGuestManagementController, useGuestManagementRepo, useGuestManagementService, useHidAmicoController, useHidAmicoRepo, useHidAmicoService, useHrmLabsAttendanceCtrl, useHrmLabsAttendanceSrvc, useIncidentReportController, useIncidentReportRepo, useIncidentReportService, useInvoiceController, useInvoiceModel, useInvoiceRepo, useManpowerDesignationCtrl, useManpowerDesignationRepo, useManpowerMonitoringCtrl, useManpowerMonitoringRepo, useManpowerMonitoringSrvc, useManpowerRemarkCtrl, useManpowerRemarksRepo, useManpowerSitesCtrl, useManpowerSitesRepo, useManpowerSitesSrvc, useMemberController, useMemberRepo, useMemberService, useNewDashboardController, useNewDashboardRepo, useNfcPatrolLogController, useNfcPatrolLogRepo, useNfcPatrolLogService, useNfcPatrolRouteController, useNfcPatrolRouteRepo, useNfcPatrolRouteService, useNfcPatrolSettingsController, useNfcPatrolSettingsRepository, useNfcPatrolSettingsService, useNfcPatrolTagController, useNfcPatrolTagRepo, useNfcPatrolTagService, useNotificationController, useNotificationRepo, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolLogController, usePatrolLogRepo, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePostFavoriteController, usePostFavoriteRepo, usePostFavoriteService, usePostPrelovedController, usePostPrelovedRepo, usePriceController, usePriceModel, usePriceRepo, usePromoCodeController, usePromoCodeRepo, useRedDotPaymentController, useRedDotPaymentRepo, useRedDotPaymentSvc, useRobotController, useRobotRepo, useRobotService, useRoleController, useRoleControllerV2, useRoleRepo, useRoleRepoV2, useRoleServiceV2, useServiceProviderBillingController, useServiceProviderBillingRepo, useServiceProviderBillingService, useServiceProviderController, useServiceProviderRepo, useSessionRepo, useSiteBillingConfigurationController, useSiteBillingConfigurationRepo, useSiteBillingItemController, useSiteBillingItemRepo, useSiteCameraController, useSiteCameraRepo, useSiteCameraService, useSiteController, useSiteFacilityBookingController, useSiteFacilityBookingRepo, useSiteFacilityBookingService, useSiteFacilityController, useSiteFacilityRepo, useSiteFacilityService, useSiteRepo, useSiteService, useSiteUnitBillingController, useSiteUnitBillingRepo, useSiteUnitBillingService, useStatementOfAccountController, useStatementOfAccountRepo, useSubcategoryPrelovedController, useSubcategoryPrelovedRepo, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useUserController, useUserControllerV2, useUserRepo, useUserRepoV2, useUserService, useUserServiceV2, useVehicleController, useVehicleRepo, useVehicleService, useVerificationController, useVerificationControllerV2, useVerificationRepo, useVerificationRepoV2, useVerificationService, useVerificationServiceV2, useVisitorTransactionController, useVisitorTransactionRepo, useVisitorTransactionService, useWorkOrderController, useWorkOrderRepo, useWorkOrderService, userSchema, vehicleSchema, vehicles_namespace_collection, visitorPersonRepo, visitorPersonService, visitorType, visitors_namespace_collection, wallConfig, workOrderSchema, work_orders2_namespace_collection, work_orders_namespace_collection };
package/dist/index.js CHANGED
@@ -6070,6 +6070,7 @@ __export(src_exports, {
6070
6070
  cameraBaseUrl: () => cameraBaseUrl,
6071
6071
  cameraCapabilitiesFor: () => cameraCapabilitiesFor,
6072
6072
  cameraDevices: () => cameraDevices,
6073
+ cameraGrant: () => cameraGrant,
6073
6074
  cameraHealthSummary: () => cameraHealthSummary,
6074
6075
  cameraManagePermissions: () => cameraManagePermissions,
6075
6076
  cameraTransports: () => cameraTransports,
@@ -32332,18 +32333,28 @@ function hasAnyPermission(permissions, allowed) {
32332
32333
  (permission) => permission === "*" || allowed.includes(permission)
32333
32334
  );
32334
32335
  }
32335
- function isCameraEntitled(params) {
32336
+ function cameraGrant(params) {
32336
32337
  const site = idOf(params.cameraSite);
32337
32338
  const org = idOf(params.cameraOrg);
32338
32339
  if (!site)
32339
- return false;
32340
- return params.memberships.some((membership) => {
32341
- const memberSite = idOf(membership.siteId);
32342
- if (memberSite)
32343
- return memberSite === site;
32344
- const memberOrg = idOf(membership.org);
32345
- return Boolean(memberOrg && org && memberOrg === org);
32346
- });
32340
+ return null;
32341
+ const atSite = params.memberships.find(
32342
+ (membership) => idOf(membership.siteId) === site
32343
+ );
32344
+ if (atSite)
32345
+ return atSite;
32346
+ const atOrg = org ? params.memberships.find(
32347
+ (membership) => !idOf(membership.siteId) && idOf(membership.org) === org
32348
+ ) : void 0;
32349
+ if (atOrg)
32350
+ return atOrg;
32351
+ const engaged = params.engagedOrgs?.size ? params.memberships.find(
32352
+ (membership) => params.engagedOrgs.has(idOf(membership.org))
32353
+ ) : void 0;
32354
+ return engaged ?? null;
32355
+ }
32356
+ function isCameraEntitled(params) {
32357
+ return Boolean(cameraGrant(params));
32347
32358
  }
32348
32359
  function idOf(value) {
32349
32360
  if (!value)
@@ -33650,6 +33661,39 @@ function useCameraViewService() {
33650
33661
  import_node_server_utils94.logger.info(`Camera capabilities ${label} (x${count}): ${line}`);
33651
33662
  }
33652
33663
  }
33664
+ async function resolveSiteAccess(params) {
33665
+ const memberships = await params.db.collection("members").find({ user: new import_mongodb56.ObjectId(params.userId), status: { $ne: "deleted" } }).project({ siteId: 1, org: 1, role: 1 }).toArray();
33666
+ const memberOrgIds = [
33667
+ ...new Map(
33668
+ memberships.filter((membership) => membership.org).map((membership) => [String(membership.org), membership.org])
33669
+ ).values()
33670
+ ];
33671
+ const engagedOrgs = /* @__PURE__ */ new Set();
33672
+ if (memberOrgIds.length > 0) {
33673
+ const engagements = await params.db.collection("customer.sites").find({
33674
+ org: { $in: memberOrgIds },
33675
+ site: params.siteObjectId,
33676
+ status: "active"
33677
+ }).project({ org: 1 }).toArray();
33678
+ for (const engagement of engagements) {
33679
+ engagedOrgs.add(String(engagement.org));
33680
+ }
33681
+ }
33682
+ const grant = cameraGrant({
33683
+ cameraSite: params.siteObjectId,
33684
+ // `orgId` is the real field; `org` is kept as a fallback only.
33685
+ cameraOrg: params.site?.orgId ?? params.site?.org,
33686
+ memberships,
33687
+ engagedOrgs
33688
+ });
33689
+ return { memberships, grant };
33690
+ }
33691
+ async function permissionsForGrant(userId, grant, memberships) {
33692
+ return getUserPermissions({
33693
+ user: userId,
33694
+ org: grant?.org ?? memberships[0]?.org
33695
+ });
33696
+ }
33653
33697
  async function authorizeCamera(params) {
33654
33698
  if (!params.userId || !import_mongodb56.ObjectId.isValid(params.userId)) {
33655
33699
  throw new import_node_server_utils94.UnauthorizedError("Not signed in.");
@@ -33666,19 +33710,20 @@ function useCameraViewService() {
33666
33710
  if (!isPatrolCctvCamera(camera)) {
33667
33711
  throw new import_node_server_utils94.NotFoundError(CAMERA_NOT_PATROL_OR_CCTV);
33668
33712
  }
33669
- const memberships = await db.collection("members").find({ user: new import_mongodb56.ObjectId(params.userId), status: { $ne: "deleted" } }).project({ siteId: 1, org: 1, role: 1 }).toArray();
33670
- const site = camera.site ? await db.collection("sites").findOne({ _id: camera.site }, { projection: { org: 1 } }) : null;
33671
- const entitled = isCameraEntitled({
33672
- cameraSite: camera.site,
33673
- cameraOrg: site?.org,
33674
- memberships
33713
+ const site = camera.site ? await db.collection("sites").findOne({ _id: camera.site }, { projection: { orgId: 1, org: 1 } }) : null;
33714
+ const { memberships, grant } = await resolveSiteAccess({
33715
+ db,
33716
+ userId: params.userId,
33717
+ siteObjectId: camera.site,
33718
+ site
33675
33719
  });
33676
- if (!entitled)
33720
+ if (!grant)
33677
33721
  throw new import_node_server_utils94.NotFoundError("Camera not found.");
33678
- const permissions = await getUserPermissions({
33679
- user: params.userId,
33680
- org: memberships[0]?.org
33681
- });
33722
+ const permissions = await permissionsForGrant(
33723
+ params.userId,
33724
+ grant,
33725
+ memberships
33726
+ );
33682
33727
  if (!hasAnyPermission(permissions, params.permissions)) {
33683
33728
  throw new import_node_server_utils94.UnauthorizedError(
33684
33729
  "You do not have permission to use this camera."
@@ -33786,7 +33831,7 @@ function useCameraViewService() {
33786
33831
  socket.on("error", () => done(false));
33787
33832
  });
33788
33833
  }
33789
- async function authorizeSite(params) {
33834
+ async function entitleSite(params) {
33790
33835
  if (!params.userId || !import_mongodb56.ObjectId.isValid(params.userId)) {
33791
33836
  throw new import_node_server_utils94.UnauthorizedError("Not signed in.");
33792
33837
  }
@@ -33797,19 +33842,27 @@ function useCameraViewService() {
33797
33842
  if (!db)
33798
33843
  throw new Error("Unable to connect to server.");
33799
33844
  const siteObjectId = new import_mongodb56.ObjectId(params.siteId);
33800
- const site = await db.collection("sites").findOne({ _id: siteObjectId }, { projection: { org: 1, name: 1 } });
33801
- const memberships = await db.collection("members").find({ user: new import_mongodb56.ObjectId(params.userId), status: { $ne: "deleted" } }).project({ siteId: 1, org: 1, role: 1 }).toArray();
33802
- const entitled = Boolean(site) && isCameraEntitled({
33803
- cameraSite: siteObjectId,
33804
- cameraOrg: site?.org,
33805
- memberships
33806
- });
33807
- if (!entitled)
33845
+ const site = await db.collection("sites").findOne(
33846
+ { _id: siteObjectId },
33847
+ { projection: { orgId: 1, org: 1, name: 1 } }
33848
+ );
33849
+ const { memberships, grant } = site ? await resolveSiteAccess({
33850
+ db,
33851
+ userId: params.userId,
33852
+ siteObjectId,
33853
+ site
33854
+ }) : { memberships: [], grant: null };
33855
+ if (!grant)
33808
33856
  throw new import_node_server_utils94.NotFoundError("Site not found.");
33809
- const permissions = await getUserPermissions({
33810
- user: params.userId,
33811
- org: memberships[0]?.org
33812
- });
33857
+ return { site, siteObjectId, db, memberships, grant };
33858
+ }
33859
+ async function authorizeSite(params) {
33860
+ const { site, siteObjectId, db, memberships, grant } = await entitleSite(params);
33861
+ const permissions = await permissionsForGrant(
33862
+ params.userId,
33863
+ grant,
33864
+ memberships
33865
+ );
33813
33866
  const required = params.permissions ?? CAMERA_VIEW_PERMISSIONS;
33814
33867
  if (!hasAnyPermission(permissions, required)) {
33815
33868
  throw new import_node_server_utils94.UnauthorizedError(
@@ -34147,6 +34200,7 @@ function useCameraViewService() {
34147
34200
  }
34148
34201
  return {
34149
34202
  authorizeCamera,
34203
+ entitleSite,
34150
34204
  authorizeSite,
34151
34205
  testCameraAddress,
34152
34206
  getSnapshot,
@@ -76086,6 +76140,7 @@ function useNotificationController() {
76086
76140
  cameraBaseUrl,
76087
76141
  cameraCapabilitiesFor,
76088
76142
  cameraDevices,
76143
+ cameraGrant,
76089
76144
  cameraHealthSummary,
76090
76145
  cameraManagePermissions,
76091
76146
  cameraTransports,