@7365admin1/core 3.72.1-staging.318 → 3.72.1-staging.319

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,5 @@
1
+ ---
2
+ "@7365admin1/core": minor
3
+ ---
4
+
5
+ Recorded footage for CCTV cameras: `RELAY_PLAYBACK` capability (`CAMERA_PLAYBACK_RELAYS` + referenced signing key), `getPlayback` signs a 120-second link to the camera relay's recorder playback for a past window of up to 30 minutes, gated by site reach and the new `cctv-mgmt:view-recordings` permission.
package/dist/index.d.ts CHANGED
@@ -4890,6 +4890,7 @@ type CameraCapabilityState = "supported" | "unsupported" | "unknown";
4890
4890
  declare const TRANSPORT_RELAY_PLAYER = "RELAY_PLAYER";
4891
4891
  declare const TRANSPORT_RTSP_FRAME = "RTSP_FRAME";
4892
4892
  declare const TRANSPORT_DEVICE_HTTP = "DEVICE_HTTP";
4893
+ declare const TRANSPORT_RELAY_PLAYBACK = "RELAY_PLAYBACK";
4893
4894
  /**
4894
4895
  * Machine-readable reasons, each with the one sentence a UI may show.
4895
4896
  *
@@ -4911,6 +4912,7 @@ declare const CAMERA_CAPABILITY_REASONS: {
4911
4912
  readonly "not-a-relay-player-url": "This camera's address is not a live-video page address.";
4912
4913
  readonly "no-recorder-configured": "No recorder is configured for this camera's relay.";
4913
4914
  readonly "no-channel-in-address": "This camera's address has no channel, so we cannot tell which stream it is.";
4915
+ readonly "relay-playback-not-configured": "Recorded footage is not set up for this camera's video service yet.";
4914
4916
  readonly "device-http-not-configured": "No direct connection to this camera's recorder is configured on this server.";
4915
4917
  readonly "device-http-disabled": "Direct camera access is switched off on this server.";
4916
4918
  readonly "device-http-unreachable": "The camera's own control interface did not answer.";
@@ -4957,9 +4959,9 @@ type DeviceHttpTarget = {
4957
4959
  timeoutMs: number;
4958
4960
  probeTtlSeconds: number;
4959
4961
  };
4960
- type Env = Record<string, string | undefined>;
4962
+ type Env$1 = Record<string, string | undefined>;
4961
4963
  /** Both flags are opt-IN. An unset or misspelt value is OFF, never on. */
4962
- declare function deviceHttpEnabled(source?: Env): boolean;
4964
+ declare function deviceHttpEnabled(source?: Env$1): boolean;
4963
4965
  /**
4964
4966
  * The mutating switch, and it is deliberately separate from the one above.
4965
4967
  *
@@ -4969,8 +4971,8 @@ declare function deviceHttpEnabled(source?: Env): boolean;
4969
4971
  *
4970
4972
  * It also cannot be on by itself: control requires device access as well.
4971
4973
  */
4972
- declare function deviceControlEnabled(source?: Env): boolean;
4973
- declare function deviceHttpTimeoutMs(source?: Env): number;
4974
+ declare function deviceControlEnabled(source?: Env$1): boolean;
4975
+ declare function deviceHttpTimeoutMs(source?: Env$1): number;
4974
4976
  /**
4975
4977
  * How long a capability probe is trusted for.
4976
4978
  *
@@ -4979,7 +4981,7 @@ declare function deviceHttpTimeoutMs(source?: Env): number;
4979
4981
  * installer visits, not when a guard looks at a screen. A short TTL here buys
4980
4982
  * nothing and spends requests against a device with a 3-failures lockout.
4981
4983
  */
4982
- declare function deviceProbeTtlSeconds(source?: Env): number;
4984
+ declare function deviceProbeTtlSeconds(source?: Env$1): number;
4983
4985
  /**
4984
4986
  * `CAMERA_DEVICE_HTTP` — a JSON object keyed by relay authority:
4985
4987
  *
@@ -4998,7 +5000,7 @@ declare function deviceProbeTtlSeconds(source?: Env): number;
4998
5000
  * A malformed variable yields no targets at all — the same posture as
4999
5001
  * `cameraDevices()`, and far better than a half-parsed device map.
5000
5002
  */
5001
- declare function deviceHttpTargets(source?: Env): {
5003
+ declare function deviceHttpTargets(source?: Env$1): {
5002
5004
  targets: Record<string, DeviceHttpTarget>;
5003
5005
  errors: Array<string>;
5004
5006
  };
@@ -5033,6 +5035,8 @@ type CameraCapabilityContext = {
5033
5035
  deviceHttp?: DeviceHttpTarget | null;
5034
5036
  /** A CACHED probe. `null`/absent means "never asked" → `unknown`, not `no`. */
5035
5037
  probe?: DeviceProbeResult | null;
5038
+ /** Relays set up for recorded footage (`playbackRelays()`): authority → key. */
5039
+ playbackRelays?: Record<string, string>;
5036
5040
  };
5037
5041
  type Decision = {
5038
5042
  state: CameraCapabilityState;
@@ -5119,6 +5123,7 @@ declare function cameraCapabilitiesFor(params: {
5119
5123
  probe?: DeviceProbeResult | null;
5120
5124
  rtspDevices?: Record<string, CameraDevice>;
5121
5125
  deviceHttpTargets?: Record<string, DeviceHttpTarget>;
5126
+ playbackRelays?: Record<string, string>;
5122
5127
  }): {
5123
5128
  capabilities: CameraCapabilityDescriptor;
5124
5129
  trace: CameraCapabilityTrace;
@@ -5128,6 +5133,54 @@ declare function hasAnyCapability(descriptor: CameraCapabilityDescriptor): boole
5128
5133
  /** Kept for the wall's log line: `liveVideo=RELAY_PLAYER stillFrame=RTSP_FRAME …`. */
5129
5134
  declare function formatCapabilityTrace(trace: CameraCapabilityTrace): string;
5130
5135
 
5136
+ /**
5137
+ * Recorded footage through the camera's own video relay.
5138
+ *
5139
+ * The recorders' web interfaces are closed (only RTSP 554 answers), so the
5140
+ * recordings path in `camera-device-http.service.ts` cannot run. The relay can:
5141
+ * it already holds the recorder connection for live view, and plays the
5142
+ * recorder's own RTSP playback for a link this server signs. This file decides
5143
+ * whether a relay is set up for that and signs the link; it contacts nothing.
5144
+ *
5145
+ * Configuration, keyed by relay authority like `CAMERA_DEVICE_HTTP`:
5146
+ *
5147
+ * ```
5148
+ * CAMERA_PLAYBACK_RELAYS={"the-loft.iservice365.org":{"keyRef":"PLAYBACK_SIGNING_KEY"}}
5149
+ * PLAYBACK_SIGNING_KEY=<random, 32+ characters; the SAME value is set on that relay>
5150
+ * ```
5151
+ *
5152
+ * The key is referenced by name, never embedded, so the JSON can be reviewed.
5153
+ */
5154
+ /** Who may watch recorded footage. `*` (full access) passes too. */
5155
+ declare const CAMERA_RECORDINGS_PERMISSIONS: string[];
5156
+ declare const PLAYBACK_MAX_WINDOW_SECONDS: number;
5157
+ declare const PLAYBACK_LINK_SECONDS = 120;
5158
+ type Env = Record<string, string | undefined>;
5159
+ /** Relay authority → signing key, for the relays that are fully set up. */
5160
+ declare function playbackRelays(source?: Env): Record<string, string>;
5161
+ /** Why this window cannot be played, or `null`. */
5162
+ declare function playbackWindowRefusal(start: Date, end: Date, now?: Date): string | null;
5163
+ /**
5164
+ * The signed player link for one camera and window, or `null` when the
5165
+ * camera's address is not a relay page with a channel.
5166
+ *
5167
+ * Signature: HMAC-SHA256(key, `channel|start|end|exp`), unix seconds, hex —
5168
+ * checked by the relay's `playback.js`.
5169
+ */
5170
+ declare function signPlaybackLink(params: {
5171
+ host: string;
5172
+ key: string;
5173
+ start: Date;
5174
+ end: Date;
5175
+ now?: Date;
5176
+ }): {
5177
+ playerUrl: string;
5178
+ streamUrl: string;
5179
+ start: string;
5180
+ end: string;
5181
+ expiresAt: string;
5182
+ } | null;
5183
+
5131
5184
  /**
5132
5185
  * A client with ~150 cameras cannot be onboarded one two-field modal at a time,
5133
5186
  * and this is the whole reason this file exists.
@@ -5283,6 +5336,18 @@ declare function useCameraViewService(): {
5283
5336
  userId?: string;
5284
5337
  permissions: Array<string>;
5285
5338
  }) => Promise<bson.Document>;
5339
+ getPlayback: (params: {
5340
+ cameraId: string;
5341
+ userId?: string;
5342
+ start: Date;
5343
+ end: Date;
5344
+ }) => Promise<{
5345
+ playerUrl: string;
5346
+ streamUrl: string;
5347
+ start: string;
5348
+ end: string;
5349
+ expiresAt: string;
5350
+ }>;
5286
5351
  entitleSite: (params: {
5287
5352
  siteId: string;
5288
5353
  userId?: string;
@@ -5465,6 +5530,7 @@ declare function useCameraViewController(): {
5465
5530
  snapshot: (req: Request, res: Response, next: NextFunction) => Promise<void>;
5466
5531
  capture: (req: Request, res: Response, next: NextFunction) => Promise<void>;
5467
5532
  status: (req: Request, res: Response, next: NextFunction) => Promise<void>;
5533
+ playback: (req: Request, res: Response, next: NextFunction) => Promise<void>;
5468
5534
  ptz: (req: Request, res: Response, next: NextFunction) => Promise<void>;
5469
5535
  capabilities: (_req: Request, res: Response) => Promise<void>;
5470
5536
  wall: (req: Request, res: Response, next: NextFunction) => Promise<void>;
@@ -15265,4 +15331,4 @@ declare function usePersonalEmergencyChainController(): {
15265
15331
  update: (req: Request, res: Response, next: NextFunction) => Promise<void>;
15266
15332
  };
15267
15333
 
15268
- export { ANPRMode, APP_BASE_URLS, AUDIT_VALUE_MAX_LENGTH, AccessTypeProps, AppKey, AppServiceType, AssignCardConfig, BULK_CAMERA_COLUMNS, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCameraAccepted, BulkCameraOutcome, BulkCameraPlan, BulkCameraResult, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, CAMERA_ANPR_PERMISSIONS, CAMERA_CAPABILITIES, CAMERA_CAPABILITY_REASONS, CAMERA_MANAGE_ANY_PERMISSIONS, CAMERA_NOT_PATROL_OR_CCTV, CAMERA_NO_SUB_STREAM_TTL_SECONDS, 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, CLIENT_ACTIONS, CLOCK_DRIFT_WARN_SECONDS, CONSOLE_AUDIT_LABELS, CONSOLE_PERMISSIONS, CONTRACTOR_TYPE_LABELS, CROSS_CLIENT_GRANT, CURRENT_TIME_ENDPOINT, Camera, CameraAddressInput, CameraCapability, CameraCapabilityContext, CameraCapabilityDescriptor, CameraCapabilityEntry, CameraCapabilityReason, CameraCapabilityState, CameraCapabilityTrace, CameraDevice, CameraFrame, CameraMembership, CameraStream, CameraTestStatus, CameraTransport, CameraType, ConsoleAuditAction, ConsoleAuditTarget, ConsoleGrant, DEFAULT_RING_SECONDS, DEFAULT_SITE_TIMEZONE, DEVICE_STATUS, DOBStatus, DUPLICATE_TERMS_VERSION_MESSAGE, DayOfWeek, DeviceHttpTarget, DeviceProbeResult, DynamicFormFields, E164, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GOVERNED_MODULES, GuestSort, GuestStatus, HID_CARD_VALUE_FACTOR, HID_PERMISSION_CATEGORIES, HID_UINT32_MAX, HID_UINT64_MAX, HidRawUint64, IAccessCard, IAccessCardTransaction, InviteActor, LIVE_ROLE, MANAGE_SITE_MODULES, MAX_BULK_CAMERA_ROWS, MAX_CAMERA_CHANNEL, MAX_CAMERA_NAME_LENGTH, MAX_PERSONAL_EMERGENCY_CONTACTS, MAX_RING_SECONDS, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MConsoleAudit, MCustomer, MCustomerSite, MDocumentManagement, MEMBER_TYPES, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MHidSipAccount, MHidSitePermissions, MIN_RING_SECONDS, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MNotification, MNotificationPreference, MODULE_GATE_MODE_DEFAULT, MODULE_LIST_GATE_DEFAULT, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolEmail, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPersonalEmergencyChain, MPlatformTerms, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MSubscriptionPlan, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, NOTIFICATION_CATEGORIES, NOTIFICATION_CHANNELS, NOTIFICATION_CHANNEL_LABELS, NOTIFICATION_NAMESPACE, NOTIFY_ACCESS_FILTER_DEFAULT, NotificationAppSlug, NotificationCategory, NotificationChannel, NotificationModule, NotificationPreferenceView, NotificationService, ORG_MARKETPLACE_VENDOR_FIELD, ORG_OWNER_REPAIR_CLAIM_STALE_MS, ORG_OWNER_REPAIR_CLAIM_TAKEN_REASON, ORG_OWNER_REPAIR_DEFAULT, ORG_OWNER_REPAIR_OFF_REASON, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PATROL_CCTV_CAMERA_FILTER, PATROL_EMAIL_MAX_LOGS, PATROL_EMAIL_MAX_PER_HOUR, PATROL_EMAIL_MAX_RECIPIENTS, PERSON_TYPES, PLATFORM_STAFF_MEMBER_TYPE, PLATFORM_STAFF_ROLE_TYPE, PROPERTY_MANAGEMENT_MEMBER_TYPES, PStatus, PTZ_ALLOWED_ACTIONS, PTZ_ALLOWED_CODES, Period, PersonStatus, PersonType, PersonTypes, PlatformTermsStatus, PostOrder, PostSort, PostStatus, QrTagProps, REALTIME_MAX_FANOUT, ResidentAppModuleKey, SELF_SERVICE_RESEND_COOLDOWN_MS, SELF_SIGNUP_PLATFORM, SELF_SIGNUP_STATUS, SELF_SIGNUP_TYPES, SERVICE_PROVIDER_INVITE_LABELS, SERVICE_PROVIDER_INVITE_TRANSITIONS, SERVICE_PROVIDER_SIGN_IN_SUBJECT, SERVICE_PROVIDER_SIGN_IN_TYPE, SERVICE_PROVIDER_SIGN_UP_SUBJECT, SERVICE_PROVIDER_SIGN_UP_TYPE, SOFTWARE_VERSION_ENDPOINT, ServiceProviderInviteAction, ServiceProviderInviteDecision, ServiceProviderInviteFacts, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionBillingMode, 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, TCameraHealthClaim, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TConsoleAudit, TConsoleAuditQuery, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TCustomerSitePropertyField, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoGatewayJob, THidAmicoIdentity, THidAmicoPhysicalCard, THidAmicoReader, THidPermissionAssignment, THidPermissionCategory, THidPermissionUserBinding, THidPhysicalCardInput, THidPhysicalCardType$1 as THidPhysicalCardType, THidSipAccount, THidSitePermissions, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberModulesDeps, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TModuleAccess, TModuleGateMode, TModuleImpact, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TNotification, TNotificationPreference, TNotificationPreferenceOff, TNotifyAccessContext, TNotifyAccessMode, TNotifyAccessReport, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOrgModulesDeps, TOrgOwnerRepairClaim, TOrgOwnerRepairDeps, TOrgOwnerRepairInput, TOrgOwnerRepairPayload, TOrgOwnerRepairPlan, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolEmail, TPatrolEmailCreatedBy, TPatrolEmailLogRef, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPersonalEmergencyChain, TPersonalEmergencyContact, TPlaceOfIncident, TPlates, TPlatformTerms, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoCurrencyInput, TPromoTier, TRANSPORT_DEVICE_HTTP, TRANSPORT_RELAY_PLAYER, TRANSPORT_RTSP_FRAME, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRolePermissionHistoryEntry, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TSelfServiceEmailOccasion, TSelfServiceEmailRecord, TSelfServiceResendDecision, TSelfServiceResendFacts, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteDayBounds, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteModulesDeps, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TSubscriptionPlan, TSubscriptionPlanApplication, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationCode, TVerificationEvent, TVerificationMetadata, TVerificationMetadataV2, TVerificationOnboarding, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UNSTORED_COLUMNS, UseAccessManagementRepo, UserStatus, VERIFICATION_OPEN_STATUSES, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, allowedPlanApplications, attendanceSchema, attendanceSettingsSchema, buildSelfServiceEmailContext, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, callerAccountApproved, callerId, cameraBaseUrl, cameraCapabilitiesFor, cameraDevices, cameraGrant, cameraHealthClaim, cameraHealthSummary, cameraListClearConfirmation, cameraManagePermissions, cameraProbeCacheKey, cameraTransports, canManageSiteModules, canRevokeRefreshTokenFamily, categoriesForPermissions, categorySupportsChannel, chatPrelovedEvents, chatSchema, claimReadsAsStale, clampPtzSpeed, clockDriftSeconds, consoleRoleAllows, consoleRoleAllowsAll, consoleSpellings, console_audit_namespace_collection, createManpowerRemarksDaily, customerSchema, customerSitePropertyFields, decideSelfServiceResend, decideServiceProviderInvite, decodeHidPacsCard, deniedModules, deriveBulletinStatus, deriveCameraHost, describeCameraCapabilities, designationsSchema, deviceControlEnabled, deviceHttpEnabled, deviceHttpTargets, deviceHttpTimeoutMs, deviceProbeTtlSeconds, documentExpiryFilter, documents_namespace_collection, emitNotificationCreated, emptyPersonalEmergencyChain, encodeHidPacsCard, entitledSiteScope, events_namespace_collection, expandModules, expiredBulletinSweepFilter, expiredVehicleSweepFilter, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, ffmpegFrameArgs, ffmpegPath, filterByAccess, formatCapabilityTrace, formatDahuaDate, getIO, getSessionIdFromRequest, grabWithSubStreamFallback, guests_namespace_collection, hasAnyCapability, hasAnyPermission, hasOrgInvitation, hasOrgOwnership, hasOrgSiteReach, hidRawUint64, holdsRole, incidentReport, incidentReportLog, incidents_namespace_collection, invitationOffersRole, isCameraEntitled, isDuplicateMemberError, isDuplicateVersionError, isLikelySelfServiceEmail, isPatrolCctvCamera, isPlatformOwner, isPromoCodeExpired, isRelayPlayerUrl, isSafeRelativePath, isSuperAdmin, isTermsCurrent, isValidTimezone, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, mapWithLimit, maskNric, memberModulesHandlers, moduleDeniedForCaller, moduleGateEnforceKeys, moduleGateMode, moduleImpact, moduleListGateOn, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, normalizeAcceptedTerms, normalizeHidCardValue, notificationAccessReport, notificationCategory, notificationCategoryLabel, notificationEvents, notificationRoom, notifyAccessMode, occasionForStatus, occurrence_book_namespace_collection, online_forms_namespace_collection, orgLevelRoles, orgModulesHandlers, orgOwnerRepairHandlers, orgOwnerRepairOn, orgQualifiesForOwnerRepair, orgSchema, overnight_parking_requests_namespace_collection, parseCameraChannel, parseCameraHost, parseDahuaFind, parseDeviceTime, parseHidJsonLossless, parsePromoExpiry, parseSoftwareVersion, pickAuditFields, pickCustomerSiteProperties, planBulkCameraImport, planOrgOwnerRepair, platform_terms_namespace_collection, promoCodeRefusal, promoCodeSchema, promoCodeStatusSchema, promoCodeUpdate, promoCodeUpdateSchema, ptzEndpoint, publicCameraFields, readsAsApprovedAccount, recordConsoleAction, refuseServiceProviderInviteAction, registerCameraTransport, relayForRecorder, remarksSchema, renderPagePdf, requireConsolePermission, requirePlatformStaff, resetCameraTransports, residentAppModuleKeys, residentAppModulesSchema, residentFormEntry, resolutionRefusalReason, resolveCamera, resolveDeviceHttp, resolveHidPhysicalCardValue, resolveInviteActor, resolveSiteTimezone, resolveStaffRole, robotSchema, rtspUrl, schema, schemaAppSlugNotification, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaConsoleAudit, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCreateNotification, schemaCustomerSite, schemaDiscoverHidAmicoReader, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoAccessLogQuery, schemaHidAmicoAssignUserCard, schemaHidAmicoConfiguration, schemaHidAmicoEnrollUserCard, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoMonitor, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoOperatingMode, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoReaderUserQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSiteIdParams, schemaHidAmicoSync, schemaHidAmicoUserCardIdParams, schemaHidAmicoUserCardParams, schemaHidAmicoUserImageParams, schemaHidAmicoUserImageUploadQuery, schemaHidAmicoUserPassword, schemaHidAmicoUserPasswordParams, schemaHidAmicoUserPin, schemaHidAmicoUserPinParams, schemaHidAmicoVisitorImageParams, schemaHidAmicoVisitorImageUploadQuery, schemaHidAmicoVisitorQr, schemaHidPermissionCandidateQuery, schemaHidPermissionScopeQuery, schemaHidSipAccountRequest, schemaIncidentReport, schemaListNotification, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaNotification, schemaNotificationPreference, schemaNotificationPreferenceOff, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolEmail, schemaPatrolEmailCreatedBy, schemaPatrolEmailLogRef, schemaPatrolEmailQuery, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPersonalEmergencyContact, schemaPlate, schemaPlatformTerms, schemaPost, schemaPostFavorite, schemaResendPatrolEmail, schemaResidentSelfSignUp, schemaSelfServiceVisitor, schemaSendPatrolEmail, 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, schemaUpdateNotificationPreference, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePersonalEmergencyChain, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, selectHealthTargets, selfServiceEmailSubject, serviceProviderInviteLabel, sessionSchema, setIO, shiftSchema, siteDayBounds, siteModulesHandlers, siteSchema, site_people_namespace_collection, snapshotEndpoint, snapshotRefusalReason, staffMayBypass, stringifyHidJson, stripFacialImageMetadata, subscriptionPlanSchema, summariseBulkCameraPlan, toExpiryDate, 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, useConsoleAuditController, useConsoleAuditRepo, 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, useNotificationPreferenceController, useNotificationPreferenceRepo, useNotificationPreferenceService, useNotificationRepo, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgOwnerRepairRepo, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolEmailController, usePatrolEmailRepo, usePatrolEmailService, usePatrolLogController, usePatrolLogRepo, usePatrolLogService, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePersonalEmergencyChainController, usePersonalEmergencyChainRepo, usePersonalEmergencyChainService, usePlatformTermsController, usePlatformTermsRepo, usePlatformTermsService, 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, useServiceProviderInviteController, useServiceProviderInviteService, 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, useSubscriptionPlanController, useSubscriptionPlanRepo, 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 };
15334
+ export { ANPRMode, APP_BASE_URLS, AUDIT_VALUE_MAX_LENGTH, AccessTypeProps, AppKey, AppServiceType, AssignCardConfig, BULK_CAMERA_COLUMNS, BidStatus, BidType, BuildingLevelStatus, BuildingStatus, BulkCameraAccepted, BulkCameraOutcome, BulkCameraPlan, BulkCameraResult, BulkCardUpdate, BulletinOrder, BulletinRecipient, BulletinSort, BulletinStatus, BulletinVideoOrder, BulletinVideoSort, CAMERA_ANPR_PERMISSIONS, CAMERA_CAPABILITIES, CAMERA_CAPABILITY_REASONS, CAMERA_MANAGE_ANY_PERMISSIONS, CAMERA_NOT_PATROL_OR_CCTV, CAMERA_NO_SUB_STREAM_TTL_SECONDS, CAMERA_PTZ_PERMISSIONS, CAMERA_RECORDINGS_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, CLIENT_ACTIONS, CLOCK_DRIFT_WARN_SECONDS, CONSOLE_AUDIT_LABELS, CONSOLE_PERMISSIONS, CONTRACTOR_TYPE_LABELS, CROSS_CLIENT_GRANT, CURRENT_TIME_ENDPOINT, Camera, CameraAddressInput, CameraCapability, CameraCapabilityContext, CameraCapabilityDescriptor, CameraCapabilityEntry, CameraCapabilityReason, CameraCapabilityState, CameraCapabilityTrace, CameraDevice, CameraFrame, CameraMembership, CameraStream, CameraTestStatus, CameraTransport, CameraType, ConsoleAuditAction, ConsoleAuditTarget, ConsoleGrant, DEFAULT_RING_SECONDS, DEFAULT_SITE_TIMEZONE, DEVICE_STATUS, DOBStatus, DUPLICATE_TERMS_VERSION_MESSAGE, DayOfWeek, DeviceHttpTarget, DeviceProbeResult, DynamicFormFields, E164, EAccessCardTypes, EAccessCardUserTypes, EmailSender, EntryOrder, EntrySort, EventOrder, EventSort, EventStatus, EventType, FacilitySort, FacilityStatus, FormEntryStatus, GOVERNED_MODULES, GuestSort, GuestStatus, HID_CARD_VALUE_FACTOR, HID_PERMISSION_CATEGORIES, HID_UINT32_MAX, HID_UINT64_MAX, HidRawUint64, IAccessCard, IAccessCardTransaction, InviteActor, LIVE_ROLE, MANAGE_SITE_MODULES, MAX_BULK_CAMERA_ROWS, MAX_CAMERA_CHANNEL, MAX_CAMERA_NAME_LENGTH, MAX_PERSONAL_EMERGENCY_CONTACTS, MAX_RING_SECONDS, MAccessCard, MAccessCardTransaction, MAddress, MAttendance, MAttendanceSettings, MBidPreloved, MBillingConfiguration, MBillingItem, MBuilding, MBuildingLevel, MBuildingUnit, MBulletinBoard, MBulletinVideo, MCategoryPreloved, MChannelPreloved, MChat, MChatPreloved, MConsoleAudit, MCustomer, MCustomerSite, MDocumentManagement, MEMBER_TYPES, MEntryPassSettings, MEventManagement, MFeedback, MFile, MFormEntry, MGuestManagement, MHidAmicoEvent, MHidAmicoIdentity, MHidAmicoReader, MHidSipAccount, MHidSitePermissions, MIN_RING_SECONDS, MIncidentReport, MManpowerDesignations, MManpowerMonitoring, MManpowerRemarks, MManpowerSites, MMember, MNfcPatrolLog, MNfcPatrolRoute, MNfcPatrolSettings, MNfcPatrolSettingsUpdate, MNfcPatrolTag, MNotification, MNotificationPreference, MODULE_GATE_MODE_DEFAULT, MODULE_LIST_GATE_DEFAULT, MOccurrenceBook, MOccurrenceEntry, MOccurrenceSubject, MOnlineForm, MOrg, MOvernightParkingApprovalHours, MOvernightParkingRequest, MPatrolEmail, MPatrolLog, MPatrolQuestion, MPatrolRoute, MPerson, MPersonalEmergencyChain, MPlatformTerms, MPost, MPostFavorite, MPromoCode, MRobot, MRole, MRoleV2, MServiceProvider, MServiceProviderBilling, MSession, MSite, MSiteCamera, MSiteFacility, MSiteFacilityBooking, MStatementOfAccount, MSubcategoryPreloved, MSubscription, MSubscriptionPlan, MUnitBilling, MUser, MVehicle, MVehicleTransaction, MVerification, MVerificationV2, MVisitorTransaction, MWorkOrder, NOTIFICATION_CATEGORIES, NOTIFICATION_CHANNELS, NOTIFICATION_CHANNEL_LABELS, NOTIFICATION_NAMESPACE, NOTIFY_ACCESS_FILTER_DEFAULT, NotificationAppSlug, NotificationCategory, NotificationChannel, NotificationModule, NotificationPreferenceView, NotificationService, ORG_MARKETPLACE_VENDOR_FIELD, ORG_OWNER_REPAIR_CLAIM_STALE_MS, ORG_OWNER_REPAIR_CLAIM_TAKEN_REASON, ORG_OWNER_REPAIR_DEFAULT, ORG_OWNER_REPAIR_OFF_REASON, OrgNature, OvernightParkingRequestSort, OvernightParkingRequestStatus, PATROL_CCTV_CAMERA_FILTER, PATROL_EMAIL_MAX_LOGS, PATROL_EMAIL_MAX_PER_HOUR, PATROL_EMAIL_MAX_RECIPIENTS, PERSON_TYPES, PLATFORM_STAFF_MEMBER_TYPE, PLATFORM_STAFF_ROLE_TYPE, PLAYBACK_LINK_SECONDS, PLAYBACK_MAX_WINDOW_SECONDS, PROPERTY_MANAGEMENT_MEMBER_TYPES, PStatus, PTZ_ALLOWED_ACTIONS, PTZ_ALLOWED_CODES, Period, PersonStatus, PersonType, PersonTypes, PlatformTermsStatus, PostOrder, PostSort, PostStatus, QrTagProps, REALTIME_MAX_FANOUT, ResidentAppModuleKey, SELF_SERVICE_RESEND_COOLDOWN_MS, SELF_SIGNUP_PLATFORM, SELF_SIGNUP_STATUS, SELF_SIGNUP_TYPES, SERVICE_PROVIDER_INVITE_LABELS, SERVICE_PROVIDER_INVITE_TRANSITIONS, SERVICE_PROVIDER_SIGN_IN_SUBJECT, SERVICE_PROVIDER_SIGN_IN_TYPE, SERVICE_PROVIDER_SIGN_UP_SUBJECT, SERVICE_PROVIDER_SIGN_UP_TYPE, SOFTWARE_VERSION_ENDPOINT, ServiceProviderInviteAction, ServiceProviderInviteDecision, ServiceProviderInviteFacts, SiteAddress, SiteCategories, SiteStatus, SortFields, SortOrder, Status, SubjectOrder, SubjectSort, SubscriptionBillingMode, 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, TCameraHealthClaim, TCategoryPreloved, TChannelPreloved, TChat, TChatPreloved, TCheckPoint$1 as TCheckPoint, TComplaintInfo, TComplaintReceivedTo, TConsoleAudit, TConsoleAuditQuery, TCounter, TCreateNfcPatrolLog, TCustomer, TCustomerSite, TCustomerSitePropertyField, TDayNumber, TDaySchedule, TDefaultAccessCard, TDesignations, TDocs, TDocumentCreate, TDocumentManagement, TEntryPassSettings, TEventManagement, TFeedback, TFeedbackMetadata, TFeedbackUpdate, TFeedbackUpdateCategory, TFeedbackUpdateServiceProvider, TFeedbackUpdateStatus, TFeedbackUpdateToCompleted, TFile, TFiles, TFolderUpdate, TFormEntry, TGetAttendancesByUserQuery, TGetAttendancesQuery, TGuestManagement, THidAmicoEvent, THidAmicoGatewayJob, THidAmicoIdentity, THidAmicoPhysicalCard, THidAmicoReader, THidPermissionAssignment, THidPermissionCategory, THidPermissionUserBinding, THidPhysicalCardInput, THidPhysicalCardType$1 as THidPhysicalCardType, THidSipAccount, THidSitePermissions, TIncidentInformation, TIncidentReport, TIncidentTypeAndTime, TInvoice, TKeyRef, TManpowerDesignations, TManpowerDesignationsUpdate, TManpowerMonitoring, TManpowerMonitoringUpdate, TManpowerRemarks, TManpowerRemarksStatusUpdate, TManpowerRemarksUpdate, TManpowerSearchFilter, TManpowerSites, TMember, TMemberModulesDeps, TMemberUpdateStatus, TMessagePreloved, TMiniRole, TModuleAccess, TModuleGateMode, TModuleImpact, TNfcPatrolLog, TNfcPatrolRoute, TNfcPatrolRouteEdit, TNfcPatrolSettings, TNfcPatrolSettingsGetBySite, TNfcPatrolSettingsUpdate, TNfcPatrolTag, TNfcPatrolTagConfigureReset, TNfcPatrolTagEdit, TNfcPatrolTagUpdateData, TNotification, TNotificationPreference, TNotificationPreferenceOff, TNotifyAccessContext, TNotifyAccessMode, TNotifyAccessReport, TOccurrenceBook, TOccurrenceEntry, TOccurrenceSubject, TOnlineForm, TOrg, TOrgModulesDeps, TOrgOwnerRepairClaim, TOrgOwnerRepairDeps, TOrgOwnerRepairInput, TOrgOwnerRepairPayload, TOrgOwnerRepairPlan, TOvernightParkingApprovalHours, TOvernightParkingRequest, TPatrolEmail, TPatrolEmailCreatedBy, TPatrolEmailLogRef, TPatrolLog, TPatrolQuestion, TPatrolRoute, TPerson, TPersonalEmergencyChain, TPersonalEmergencyContact, TPlaceOfIncident, TPlates, TPlatformTerms, TPost, TPostFavorite, TPrice, TPriceType, TPromoCode, TPromoCurrencyInput, TPromoTier, TRANSPORT_DEVICE_HTTP, TRANSPORT_RELAY_PLAYBACK, TRANSPORT_RELAY_PLAYER, TRANSPORT_RTSP_FRAME, TRecipientOfComplaint, TRemarks, TResident, TResidentAppModules, TRobot, TRobotMetadata, TRole, TRolePermissionHistoryEntry, TRoleV2, TRoute, TSOABillingItem, TSOAStatus, TSelfServiceEmailOccasion, TSelfServiceEmailRecord, TSelfServiceResendDecision, TSelfServiceResendFacts, TServiceProvider, TServiceProviderBilling, TSession, TSessionCreate, TShifts, TSignNfcPatrolLog, TSite, TSiteCamera, TSiteDayBounds, TSiteFacility, TSiteFacilityBooking, TSiteInfo, TSiteInformation, TSiteMetadata, TSiteModulesDeps, TSiteUpdateBlock, TStatementOfAccount, TSubcategoryPreloved, TSubmissionForm, TSubscription, TSubscriptionPlan, TSubscriptionPlanApplication, TUnitBilling, TUnits, TUpdateFormEntry, TUpdateName, TUser, TUserCreate, TVehicle, TVehicleTransaction, TVehicleUpdate, TVerification, TVerificationCode, TVerificationEvent, TVerificationMetadata, TVerificationMetadataV2, TVerificationOnboarding, TVerificationV2, TVisitorTransaction, TWorkOrder, TWorkOrderMetadata, TWorkOrderUpdate, TWorkOrderUpdateStatus, TWorkOrderUpdateToCompleted, TanyoneDamageToProperty, UNSTORED_COLUMNS, UseAccessManagementRepo, UserStatus, VERIFICATION_OPEN_STATUSES, VehicleCategory, VehicleOrder, VehicleSort, VehicleStatus, VehicleType, VerificationLinkType, VerificationStatus, VerificationSubjectType, VerificationType, VisitorSort, VisitorStatus, addressSchema, allowedFieldsSite, allowedNatures, allowedPlanApplications, attendanceSchema, attendanceSettingsSchema, buildSelfServiceEmailContext, building_level_namespace_collection, building_units_namespace_collection, buildings_namespace_collection, bulletin_boards_namespace_collection, callerAccountApproved, callerId, cameraBaseUrl, cameraCapabilitiesFor, cameraDevices, cameraGrant, cameraHealthClaim, cameraHealthSummary, cameraListClearConfirmation, cameraManagePermissions, cameraProbeCacheKey, cameraTransports, canManageSiteModules, canRevokeRefreshTokenFamily, categoriesForPermissions, categorySupportsChannel, chatPrelovedEvents, chatSchema, claimReadsAsStale, clampPtzSpeed, clockDriftSeconds, consoleRoleAllows, consoleRoleAllowsAll, consoleSpellings, console_audit_namespace_collection, createManpowerRemarksDaily, customerSchema, customerSitePropertyFields, decideSelfServiceResend, decideServiceProviderInvite, decodeHidPacsCard, deniedModules, deriveBulletinStatus, deriveCameraHost, describeCameraCapabilities, designationsSchema, deviceControlEnabled, deviceHttpEnabled, deviceHttpTargets, deviceHttpTimeoutMs, deviceProbeTtlSeconds, documentExpiryFilter, documents_namespace_collection, emitNotificationCreated, emptyPersonalEmergencyChain, encodeHidPacsCard, entitledSiteScope, events_namespace_collection, expandModules, expiredBulletinSweepFilter, expiredVehicleSweepFilter, facility_bookings_namespace_collection, feedbackSchema, feedbacks2_namespace_collection, feedbacks_namespace_collection, ffmpegFrameArgs, ffmpegPath, filterByAccess, formatCapabilityTrace, formatDahuaDate, getIO, getSessionIdFromRequest, grabWithSubStreamFallback, guests_namespace_collection, hasAnyCapability, hasAnyPermission, hasOrgInvitation, hasOrgOwnership, hasOrgSiteReach, hidRawUint64, holdsRole, incidentReport, incidentReportLog, incidents_namespace_collection, invitationOffersRole, isCameraEntitled, isDuplicateMemberError, isDuplicateVersionError, isLikelySelfServiceEmail, isPatrolCctvCamera, isPlatformOwner, isPromoCodeExpired, isRelayPlayerUrl, isSafeRelativePath, isSuperAdmin, isTermsCurrent, isValidTimezone, logCamera, manpowerDesignationsSchema, manpowerEvents, manpowerMonitoringSchema, manpowerRemarksSchema, manpowerSitesSchema, mapWithLimit, maskNric, memberModulesHandlers, moduleDeniedForCaller, moduleGateEnforceKeys, moduleGateMode, moduleImpact, moduleListGateOn, nfcPatrolSettingsSchema, nfcPatrolSettingsSchemaUpdate, normalizeAcceptedTerms, normalizeHidCardValue, notificationAccessReport, notificationCategory, notificationCategoryLabel, notificationEvents, notificationRoom, notifyAccessMode, occasionForStatus, occurrence_book_namespace_collection, online_forms_namespace_collection, orgLevelRoles, orgModulesHandlers, orgOwnerRepairHandlers, orgOwnerRepairOn, orgQualifiesForOwnerRepair, orgSchema, overnight_parking_requests_namespace_collection, parseCameraChannel, parseCameraHost, parseDahuaFind, parseDeviceTime, parseHidJsonLossless, parsePromoExpiry, parseSoftwareVersion, pickAuditFields, pickCustomerSiteProperties, planBulkCameraImport, planOrgOwnerRepair, platform_terms_namespace_collection, playbackRelays, playbackWindowRefusal, promoCodeRefusal, promoCodeSchema, promoCodeStatusSchema, promoCodeUpdate, promoCodeUpdateSchema, ptzEndpoint, publicCameraFields, readsAsApprovedAccount, recordConsoleAction, refuseServiceProviderInviteAction, registerCameraTransport, relayForRecorder, remarksSchema, renderPagePdf, requireConsolePermission, requirePlatformStaff, resetCameraTransports, residentAppModuleKeys, residentAppModulesSchema, residentFormEntry, resolutionRefusalReason, resolveCamera, resolveDeviceHttp, resolveHidPhysicalCardValue, resolveInviteActor, resolveSiteTimezone, resolveStaffRole, robotSchema, rtspUrl, schema, schemaAppSlugNotification, schemaApprovedBy, schemaApprover, schemaBidPreloved, schemaBilling, schemaBillingConfiguration, schemaBillingItem, schemaBuilding, schemaBuildingLevel, schemaBuildingUnit, schemaBuildingUpdateOptions, schemaBulletinBoard, schemaBulletinVideo, schemaCategoryPreloved, schemaChannelPreloved, schemaChatPreloved, schemaConsoleAudit, schemaCreateHidAmicoIdentity, schemaCreateNfcPatrolLog, schemaCreateNotification, schemaCustomerSite, schemaDiscoverHidAmicoReader, schemaDocumentManagement, schemaEntryPassSettings, schemaEventManagement, schemaFiles, schemaFormEntry, schemaGuestManagement, schemaHidAmicoAccessLogQuery, schemaHidAmicoAssignUserCard, schemaHidAmicoConfiguration, schemaHidAmicoEnrollUserCard, schemaHidAmicoEvent, schemaHidAmicoExecuteActions, schemaHidAmicoIdentity, schemaHidAmicoIdentityIdParams, schemaHidAmicoIdentityQuery, schemaHidAmicoIntercomCall, schemaHidAmicoLogQuery, schemaHidAmicoMonitor, schemaHidAmicoNotificationParams, schemaHidAmicoObjectOperation, schemaHidAmicoOperatingMode, schemaHidAmicoReader, schemaHidAmicoReaderIdParams, schemaHidAmicoReaderListQuery, schemaHidAmicoReaderUserQuery, schemaHidAmicoSetConfiguration, schemaHidAmicoSiteIdParams, schemaHidAmicoSync, schemaHidAmicoUserCardIdParams, schemaHidAmicoUserCardParams, schemaHidAmicoUserImageParams, schemaHidAmicoUserImageUploadQuery, schemaHidAmicoUserPassword, schemaHidAmicoUserPasswordParams, schemaHidAmicoUserPin, schemaHidAmicoUserPinParams, schemaHidAmicoVisitorImageParams, schemaHidAmicoVisitorImageUploadQuery, schemaHidAmicoVisitorQr, schemaHidPermissionCandidateQuery, schemaHidPermissionScopeQuery, schemaHidSipAccountRequest, schemaIncidentReport, schemaListNotification, schemaMultipleDocumentManagement, schemaNfcPatrolLog, schemaNfcPatrolRoute, schemaNfcPatrolTag, schemaNfcPatrolTagUpdateData, schemaNotification, schemaNotificationPreference, schemaNotificationPreferenceOff, schemaOccurrenceBook, schemaOccurrenceEntry, schemaOccurrenceSubject, schemaOnlineForm, schemaOvernightParkingApprovalHours, schemaOvernightParkingRequest, schemaPatrolEmail, schemaPatrolEmailCreatedBy, schemaPatrolEmailLogRef, schemaPatrolEmailQuery, schemaPatrolLog, schemaPatrolQuestion, schemaPatrolRoute, schemaPerson, schemaPersonalEmergencyContact, schemaPlate, schemaPlatformTerms, schemaPost, schemaPostFavorite, schemaResendPatrolEmail, schemaResidentSelfSignUp, schemaSelfServiceVisitor, schemaSendPatrolEmail, 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, schemaUpdateNotificationPreference, schemaUpdateOccurrenceBook, schemaUpdateOccurrenceEntry, schemaUpdateOccurrenceSubject, schemaUpdateOnlineForm, schemaUpdateOptions, schemaUpdateOvernightParkingRequest, schemaUpdatePatrolLog, schemaUpdatePatrolQuestion, schemaUpdatePatrolRoute, schemaUpdatePerson, schemaUpdatePersonalEmergencyChain, schemaUpdatePost, schemaUpdatePostFavorite, schemaUpdateServiceProviderBilling, schemaUpdateSiteBillingConfiguration, schemaUpdateSiteBillingItem, schemaUpdateSiteCamera, schemaUpdateSiteFacility, schemaUpdateSiteFacilityBooking, schemaUpdateSiteUnitBilling, schemaUpdateStatementOfAccount, schemaUpdateSubcategoryPreloved, schemaUpdateVisTrans, schemaVehicleTransaction, schemaVisitorTransaction, schemeCamera, schemeLogCamera, selectHealthTargets, selfServiceEmailSubject, serviceProviderInviteLabel, sessionSchema, setIO, shiftSchema, signPlaybackLink, siteDayBounds, siteModulesHandlers, siteSchema, site_people_namespace_collection, snapshotEndpoint, snapshotRefusalReason, staffMayBypass, stringifyHidJson, stripFacialImageMetadata, subscriptionPlanSchema, summariseBulkCameraPlan, toExpiryDate, 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, useConsoleAuditController, useConsoleAuditRepo, 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, useNotificationPreferenceController, useNotificationPreferenceRepo, useNotificationPreferenceService, useNotificationRepo, useOccurrenceBookController, useOccurrenceBookRepo, useOccurrenceBookService, useOccurrenceEntryController, useOccurrenceEntryRepo, useOccurrenceEntryService, useOccurrenceSubjectController, useOccurrenceSubjectRepo, useOccurrenceSubjectService, useOnlineFormController, useOnlineFormRepo, useOrgController, useOrgControllerV2, useOrgOwnerRepairRepo, useOrgRepo, useOvernightParkingController, useOvernightParkingRepo, useOvernightParkingRequestController, useOvernightParkingRequestRepo, useOvernightParkingRequestService, usePatrolEmailController, usePatrolEmailRepo, usePatrolEmailService, usePatrolLogController, usePatrolLogRepo, usePatrolLogService, usePatrolQuestionController, usePatrolQuestionRepo, usePatrolRouteController, usePatrolRouteRepo, usePersonController, usePersonRepo, usePersonalEmergencyChainController, usePersonalEmergencyChainRepo, usePersonalEmergencyChainService, usePlatformTermsController, usePlatformTermsRepo, usePlatformTermsService, 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, useServiceProviderInviteController, useServiceProviderInviteService, 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, useSubscriptionPlanController, useSubscriptionPlanRepo, 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
@@ -53,6 +53,7 @@ __export(src_exports, {
53
53
  CAMERA_NOT_PATROL_OR_CCTV: () => CAMERA_NOT_PATROL_OR_CCTV,
54
54
  CAMERA_NO_SUB_STREAM_TTL_SECONDS: () => CAMERA_NO_SUB_STREAM_TTL_SECONDS,
55
55
  CAMERA_PTZ_PERMISSIONS: () => CAMERA_PTZ_PERMISSIONS,
56
+ CAMERA_RECORDINGS_PERMISSIONS: () => CAMERA_RECORDINGS_PERMISSIONS,
56
57
  CAMERA_REQUEST_TIMEOUT_MS: () => CAMERA_REQUEST_TIMEOUT_MS,
57
58
  CAMERA_RTSP_TIMEOUT_MS: () => CAMERA_RTSP_TIMEOUT_MS,
58
59
  CAMERA_SETUP_PERMISSIONS: () => CAMERA_SETUP_PERMISSIONS,
@@ -218,6 +219,8 @@ __export(src_exports, {
218
219
  PERSON_TYPES: () => PERSON_TYPES,
219
220
  PLATFORM_STAFF_MEMBER_TYPE: () => PLATFORM_STAFF_MEMBER_TYPE,
220
221
  PLATFORM_STAFF_ROLE_TYPE: () => PLATFORM_STAFF_ROLE_TYPE,
222
+ PLAYBACK_LINK_SECONDS: () => PLAYBACK_LINK_SECONDS,
223
+ PLAYBACK_MAX_WINDOW_SECONDS: () => PLAYBACK_MAX_WINDOW_SECONDS,
221
224
  PROPERTY_MANAGEMENT_MEMBER_TYPES: () => PROPERTY_MANAGEMENT_MEMBER_TYPES,
222
225
  PStatus: () => PStatus,
223
226
  PTZ_ALLOWED_ACTIONS: () => PTZ_ALLOWED_ACTIONS,
@@ -251,6 +254,7 @@ __export(src_exports, {
251
254
  SubscriptionBillingMode: () => SubscriptionBillingMode,
252
255
  SubscriptionType: () => SubscriptionType,
253
256
  TRANSPORT_DEVICE_HTTP: () => TRANSPORT_DEVICE_HTTP,
257
+ TRANSPORT_RELAY_PLAYBACK: () => TRANSPORT_RELAY_PLAYBACK,
254
258
  TRANSPORT_RELAY_PLAYER: () => TRANSPORT_RELAY_PLAYER,
255
259
  TRANSPORT_RTSP_FRAME: () => TRANSPORT_RTSP_FRAME,
256
260
  UNSTORED_COLUMNS: () => UNSTORED_COLUMNS,
@@ -410,6 +414,8 @@ __export(src_exports, {
410
414
  planBulkCameraImport: () => planBulkCameraImport,
411
415
  planOrgOwnerRepair: () => planOrgOwnerRepair,
412
416
  platform_terms_namespace_collection: () => platform_terms_namespace_collection,
417
+ playbackRelays: () => playbackRelays,
418
+ playbackWindowRefusal: () => playbackWindowRefusal,
413
419
  promoCodeRefusal: () => promoCodeRefusal,
414
420
  promoCodeSchema: () => promoCodeSchema,
415
421
  promoCodeStatusSchema: () => promoCodeStatusSchema,
@@ -597,6 +603,7 @@ __export(src_exports, {
597
603
  sessionSchema: () => sessionSchema,
598
604
  setIO: () => setIO,
599
605
  shiftSchema: () => shiftSchema,
606
+ signPlaybackLink: () => signPlaybackLink,
600
607
  siteDayBounds: () => siteDayBounds,
601
608
  siteModulesHandlers: () => siteModulesHandlers,
602
609
  siteSchema: () => siteSchema,
@@ -22023,6 +22030,69 @@ function entitledSiteScope(params) {
22023
22030
  return Array.from(sites);
22024
22031
  }
22025
22032
 
22033
+ // src/utils/camera-playback.util.ts
22034
+ var import_node_crypto2 = require("crypto");
22035
+ var CAMERA_RECORDINGS_PERMISSIONS = ["cctv-mgmt:view-recordings"];
22036
+ var PLAYBACK_MAX_WINDOW_SECONDS = 30 * 60;
22037
+ var PLAYBACK_LINK_SECONDS = 120;
22038
+ function playbackRelays(source = process.env) {
22039
+ let parsed;
22040
+ try {
22041
+ parsed = JSON.parse(source.CAMERA_PLAYBACK_RELAYS || "{}");
22042
+ } catch {
22043
+ return {};
22044
+ }
22045
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
22046
+ return {};
22047
+ const relays = {};
22048
+ for (const [authority, value] of Object.entries(parsed)) {
22049
+ const ref = String(value?.keyRef ?? "").trim();
22050
+ if (!/^[A-Z][A-Z0-9_]*$/.test(ref))
22051
+ continue;
22052
+ const key = source[ref] ?? "";
22053
+ if (key.length < 32)
22054
+ continue;
22055
+ relays[authority.trim().toLowerCase()] = key;
22056
+ }
22057
+ return relays;
22058
+ }
22059
+ function playbackWindowRefusal(start, end, now = /* @__PURE__ */ new Date()) {
22060
+ const s = start.getTime();
22061
+ const e = end.getTime();
22062
+ if (!Number.isFinite(s) || !Number.isFinite(e))
22063
+ return "Choose a start and end time.";
22064
+ if (e <= s)
22065
+ return "The end time must be after the start time.";
22066
+ if (e - s > PLAYBACK_MAX_WINDOW_SECONDS * 1e3)
22067
+ return "A recording can be up to 30 minutes long.";
22068
+ if (e > now.getTime())
22069
+ return "Recorded footage can only be played for a time that has already passed.";
22070
+ return null;
22071
+ }
22072
+ function signPlaybackLink(params) {
22073
+ const parsed = parseCameraHost(params.host);
22074
+ if (!parsed || parsed.channel === null)
22075
+ return null;
22076
+ const start = Math.floor(params.start.getTime() / 1e3);
22077
+ const end = Math.floor(params.end.getTime() / 1e3);
22078
+ const exp = Math.floor((params.now ?? /* @__PURE__ */ new Date()).getTime() / 1e3) + PLAYBACK_LINK_SECONDS;
22079
+ const channel = String(parsed.channel);
22080
+ const sig = (0, import_node_crypto2.createHmac)("sha256", params.key).update(`${channel}|${start}|${end}|${exp}`).digest("hex");
22081
+ const query2 = new URLSearchParams({
22082
+ start: String(start),
22083
+ end: String(end),
22084
+ exp: String(exp),
22085
+ sig
22086
+ }).toString();
22087
+ return {
22088
+ playerUrl: `https://${parsed.authority}/playback/${channel}?${query2}`,
22089
+ streamUrl: `wss://${parsed.authority}/api/playback/${channel}?${query2}`,
22090
+ start: new Date(start * 1e3).toISOString(),
22091
+ end: new Date(end * 1e3).toISOString(),
22092
+ expiresAt: new Date(exp * 1e3).toISOString()
22093
+ };
22094
+ }
22095
+
22026
22096
  // src/utils/camera-capability.util.ts
22027
22097
  var CAMERA_CAPABILITIES = [
22028
22098
  "liveVideo",
@@ -22038,6 +22108,7 @@ var CAMERA_CAPABILITIES = [
22038
22108
  var TRANSPORT_RELAY_PLAYER = "RELAY_PLAYER";
22039
22109
  var TRANSPORT_RTSP_FRAME = "RTSP_FRAME";
22040
22110
  var TRANSPORT_DEVICE_HTTP = "DEVICE_HTTP";
22111
+ var TRANSPORT_RELAY_PLAYBACK = "RELAY_PLAYBACK";
22041
22112
  var CAMERA_CAPABILITY_REASONS = {
22042
22113
  /* The record itself */
22043
22114
  "not-patrol-cctv-camera": CAMERA_NOT_PATROL_OR_CCTV,
@@ -22049,6 +22120,8 @@ var CAMERA_CAPABILITY_REASONS = {
22049
22120
  /* RTSP_FRAME */
22050
22121
  "no-recorder-configured": "No recorder is configured for this camera's relay.",
22051
22122
  "no-channel-in-address": "This camera's address has no channel, so we cannot tell which stream it is.",
22123
+ /* RELAY_PLAYBACK */
22124
+ "relay-playback-not-configured": "Recorded footage is not set up for this camera's video service yet.",
22052
22125
  /* DEVICE_HTTP */
22053
22126
  "device-http-not-configured": "No direct connection to this camera's recorder is configured on this server.",
22054
22127
  "device-http-disabled": "Direct camera access is switched off on this server.",
@@ -22241,6 +22314,23 @@ var rtspFrameTransport = {
22241
22314
  return YES;
22242
22315
  }
22243
22316
  };
22317
+ var relayPlaybackTransport = {
22318
+ id: TRANSPORT_RELAY_PLAYBACK,
22319
+ provides: ["playback"],
22320
+ evaluate(_capability, ctx) {
22321
+ const refusal = recordRefusal(ctx.camera);
22322
+ if (refusal)
22323
+ return no(refusal);
22324
+ if (!isRelayPlayerUrl(ctx.camera?.host))
22325
+ return no("not-a-relay-player-url");
22326
+ const parsed = parseCameraHost(ctx.camera?.host ?? "");
22327
+ if (!parsed || parsed.channel === null)
22328
+ return no("no-channel-in-address");
22329
+ if (!ctx.playbackRelays?.[parsed.authority])
22330
+ return no("relay-playback-not-configured");
22331
+ return YES;
22332
+ }
22333
+ };
22244
22334
  var deviceHttpTransport = {
22245
22335
  id: TRANSPORT_DEVICE_HTTP,
22246
22336
  provides: [
@@ -22283,6 +22373,7 @@ var deviceHttpTransport = {
22283
22373
  var transports2 = [
22284
22374
  relayPlayerTransport,
22285
22375
  rtspFrameTransport,
22376
+ relayPlaybackTransport,
22286
22377
  deviceHttpTransport
22287
22378
  ];
22288
22379
  function cameraTransports() {
@@ -22297,7 +22388,12 @@ function registerCameraTransport(transport) {
22297
22388
  }
22298
22389
  function resetCameraTransports() {
22299
22390
  transports2.length = 0;
22300
- transports2.push(relayPlayerTransport, rtspFrameTransport, deviceHttpTransport);
22391
+ transports2.push(
22392
+ relayPlayerTransport,
22393
+ rtspFrameTransport,
22394
+ relayPlaybackTransport,
22395
+ deviceHttpTransport
22396
+ );
22301
22397
  }
22302
22398
  function describeCameraCapabilities(ctx, registry = cameraTransports()) {
22303
22399
  const capabilities = {};
@@ -22350,7 +22446,8 @@ function cameraCapabilitiesFor(params) {
22350
22446
  camera: params.camera,
22351
22447
  rtspDevices,
22352
22448
  deviceHttp: resolveDeviceHttp(params.camera?.host, targets),
22353
- probe: params.probe ?? null
22449
+ probe: params.probe ?? null,
22450
+ playbackRelays: params.playbackRelays ?? playbackRelays()
22354
22451
  });
22355
22452
  }
22356
22453
  function hasAnyCapability(descriptor) {
@@ -22365,7 +22462,7 @@ function formatCapabilityTrace(trace) {
22365
22462
  }
22366
22463
 
22367
22464
  // src/services/camera-device-http.service.ts
22368
- var import_node_crypto2 = require("crypto");
22465
+ var import_node_crypto3 = require("crypto");
22369
22466
  var DIGEST_UNAUTHORIZED = 401;
22370
22467
  var DIGEST_FORBIDDEN = 403;
22371
22468
  function parseDigestChallenge(header) {
@@ -22381,7 +22478,7 @@ function parseDigestChallenge(header) {
22381
22478
  return out;
22382
22479
  }
22383
22480
  function md5(input) {
22384
- return (0, import_node_crypto2.createHash)("md5").update(input, "utf8").digest("hex");
22481
+ return (0, import_node_crypto3.createHash)("md5").update(input, "utf8").digest("hex");
22385
22482
  }
22386
22483
  function buildDigestAuthorization(params) {
22387
22484
  const realm = params.challenge.realm ?? "";
@@ -22390,7 +22487,7 @@ function buildDigestAuthorization(params) {
22390
22487
  const algorithm = (params.challenge.algorithm ?? "MD5").toUpperCase();
22391
22488
  const qop = pickQop(params.challenge.qop);
22392
22489
  const nc = params.nc ?? "00000001";
22393
- const cnonce = params.cnonce ?? (0, import_node_crypto2.randomBytes)(8).toString("hex");
22490
+ const cnonce = params.cnonce ?? (0, import_node_crypto3.randomBytes)(8).toString("hex");
22394
22491
  let ha1 = md5(`${params.username}:${realm}:${params.password}`);
22395
22492
  if (algorithm === "MD5-SESS")
22396
22493
  ha1 = md5(`${ha1}:${nonce}:${cnonce}`);
@@ -23047,6 +23144,7 @@ function useCameraViewService() {
23047
23144
  });
23048
23145
  const ptzEnabled = process.env.CAMERA_PTZ_ENABLED === "true";
23049
23146
  const httpTargets = deviceHttpTargets();
23147
+ const playbackKeys = playbackRelays();
23050
23148
  for (const problem of httpTargets.errors) {
23051
23149
  import_node_server_utils64.logger.info(`Camera device configuration ignored: ${problem}`);
23052
23150
  }
@@ -23083,7 +23181,8 @@ function useCameraViewService() {
23083
23181
  return cameraCapabilitiesFor({
23084
23182
  camera,
23085
23183
  probe,
23086
- deviceHttpTargets: httpTargets.targets
23184
+ deviceHttpTargets: httpTargets.targets,
23185
+ playbackRelays: playbackKeys
23087
23186
  });
23088
23187
  }
23089
23188
  function logCapabilitySelection(label, traces) {
@@ -23692,8 +23791,41 @@ function useCameraViewService() {
23692
23791
  return cannot(grabFailureMessage(error));
23693
23792
  }
23694
23793
  }
23794
+ async function getPlayback(params) {
23795
+ let camera;
23796
+ try {
23797
+ camera = await authorizeCamera({
23798
+ cameraId: params.cameraId,
23799
+ userId: params.userId,
23800
+ permissions: CAMERA_RECORDINGS_PERMISSIONS
23801
+ });
23802
+ } catch (error) {
23803
+ if (error instanceof import_node_server_utils64.UnauthorizedError && params.userId && import_mongodb50.ObjectId.isValid(params.userId)) {
23804
+ throw new import_node_server_utils64.AppError("You do not have permission to watch recorded footage.", 403);
23805
+ }
23806
+ throw error;
23807
+ }
23808
+ const refusal = playbackWindowRefusal(params.start, params.end);
23809
+ if (refusal)
23810
+ throw new import_node_server_utils64.BadRequestError(refusal);
23811
+ const { capabilities } = capabilitiesOf(camera, null);
23812
+ const authority = parseCameraHost(camera.host ?? "")?.authority ?? "";
23813
+ const key = playbackKeys[authority];
23814
+ const link = capabilities.playback.state === "supported" && key ? signPlaybackLink({ host: camera.host, key, start: params.start, end: params.end }) : null;
23815
+ if (!link) {
23816
+ throw new import_node_server_utils64.AppError(
23817
+ capabilities.playback.detail ?? "Recorded footage is not set up for this camera yet.",
23818
+ 409
23819
+ );
23820
+ }
23821
+ import_node_server_utils64.logger.info(
23822
+ `Camera playback issued: user=${params.userId} camera=${params.cameraId} start=${link.start} end=${link.end}`
23823
+ );
23824
+ return link;
23825
+ }
23695
23826
  return {
23696
23827
  authorizeCamera,
23828
+ getPlayback,
23697
23829
  entitleSite,
23698
23830
  authorizeSite,
23699
23831
  testCameraAddress,
@@ -40008,6 +40140,7 @@ function useCameraViewController() {
40008
40140
  getSnapshot,
40009
40141
  captureSnapshot,
40010
40142
  getStatus,
40143
+ getPlayback,
40011
40144
  getSiteWall,
40012
40145
  getSiteHealth,
40013
40146
  movePtz,
@@ -40047,6 +40180,28 @@ function useCameraViewController() {
40047
40180
  next(error);
40048
40181
  }
40049
40182
  }
40183
+ async function playback(req, res, next) {
40184
+ const { error, value } = import_joi59.default.object({
40185
+ start: import_joi59.default.date().iso().required(),
40186
+ end: import_joi59.default.date().iso().required()
40187
+ }).unknown(false).validate(req.query ?? {});
40188
+ if (error) {
40189
+ next(new import_node_server_utils124.BadRequestError("Choose a start and end time for the recording."));
40190
+ return;
40191
+ }
40192
+ try {
40193
+ const link = await getPlayback({
40194
+ cameraId: String(req.params.id ?? ""),
40195
+ userId: callerId5(req),
40196
+ start: value.start,
40197
+ end: value.end
40198
+ });
40199
+ res.setHeader("Cache-Control", "no-store");
40200
+ res.json(link);
40201
+ } catch (err) {
40202
+ next(err);
40203
+ }
40204
+ }
40050
40205
  async function status(req, res, next) {
40051
40206
  try {
40052
40207
  const result = await getStatus({
@@ -40154,7 +40309,7 @@ function useCameraViewController() {
40154
40309
  }
40155
40310
  });
40156
40311
  }
40157
- return { snapshot, capture, status, ptz, capabilities, wall, health, test };
40312
+ return { snapshot, capture, status, playback, ptz, capabilities, wall, health, test };
40158
40313
  }
40159
40314
 
40160
40315
  // src/services/customer-site.service.ts
@@ -44209,7 +44364,7 @@ function MHidSipAccount(value) {
44209
44364
  }
44210
44365
 
44211
44366
  // src/utils/hid-access.util.ts
44212
- var import_node_crypto3 = __toESM(require("crypto"));
44367
+ var import_node_crypto4 = __toESM(require("crypto"));
44213
44368
  var HID_MAX_FACIAL_IMAGE_BYTES = 1024 * 1024;
44214
44369
  function isSupportedHidFacialImage(image) {
44215
44370
  if (!image.length || image.length >= HID_MAX_FACIAL_IMAGE_BYTES)
@@ -44317,15 +44472,15 @@ function sanitizeHidPayload(value) {
44317
44472
  );
44318
44473
  }
44319
44474
  function hashHidCallbackToken(token) {
44320
- return import_node_crypto3.default.createHash("sha256").update(token).digest("hex");
44475
+ return import_node_crypto4.default.createHash("sha256").update(token).digest("hex");
44321
44476
  }
44322
44477
  function createHidCallbackToken() {
44323
- return import_node_crypto3.default.randomBytes(24).toString("base64url");
44478
+ return import_node_crypto4.default.randomBytes(24).toString("base64url");
44324
44479
  }
44325
44480
  function verifyHidCallbackToken(token, expectedHash) {
44326
44481
  const actual = Buffer.from(hashHidCallbackToken(token), "hex");
44327
44482
  const expected = Buffer.from(String(expectedHash || ""), "hex");
44328
- return actual.length === expected.length && actual.length > 0 && import_node_crypto3.default.timingSafeEqual(actual, expected);
44483
+ return actual.length === expected.length && actual.length > 0 && import_node_crypto4.default.timingSafeEqual(actual, expected);
44329
44484
  }
44330
44485
  function hidCallbackAllowsMissingDeviceId(type) {
44331
44486
  return type === "device_is_alive" || type === "secbox";
@@ -45568,7 +45723,7 @@ function resolveHidPhysicalCardValue(input) {
45568
45723
  }
45569
45724
 
45570
45725
  // src/utils/hid-json.util.ts
45571
- var import_node_crypto4 = __toESM(require("crypto"));
45726
+ var import_node_crypto5 = __toESM(require("crypto"));
45572
45727
  var UINT64_MAX = 2n ** 64n - 1n;
45573
45728
  var RAW_UINT64_KEY = "__hidRawUint64";
45574
45729
  function hidRawUint64(value) {
@@ -45622,7 +45777,7 @@ function parseHidJsonLossless(value) {
45622
45777
  return JSON.parse(output);
45623
45778
  }
45624
45779
  function stringifyHidJson(value) {
45625
- const marker = `__HID_UINT64_${import_node_crypto4.default.randomBytes(16).toString("hex")}_`;
45780
+ const marker = `__HID_UINT64_${import_node_crypto5.default.randomBytes(16).toString("hex")}_`;
45626
45781
  const rawValues = [];
45627
45782
  const serialized = JSON.stringify(value, (_key, nested) => {
45628
45783
  if (nested && typeof nested === "object" && Object.keys(nested).length === 1 && typeof nested[RAW_UINT64_KEY] === "string") {
@@ -92259,6 +92414,7 @@ function usePersonalEmergencyChainController() {
92259
92414
  CAMERA_NOT_PATROL_OR_CCTV,
92260
92415
  CAMERA_NO_SUB_STREAM_TTL_SECONDS,
92261
92416
  CAMERA_PTZ_PERMISSIONS,
92417
+ CAMERA_RECORDINGS_PERMISSIONS,
92262
92418
  CAMERA_REQUEST_TIMEOUT_MS,
92263
92419
  CAMERA_RTSP_TIMEOUT_MS,
92264
92420
  CAMERA_SETUP_PERMISSIONS,
@@ -92424,6 +92580,8 @@ function usePersonalEmergencyChainController() {
92424
92580
  PERSON_TYPES,
92425
92581
  PLATFORM_STAFF_MEMBER_TYPE,
92426
92582
  PLATFORM_STAFF_ROLE_TYPE,
92583
+ PLAYBACK_LINK_SECONDS,
92584
+ PLAYBACK_MAX_WINDOW_SECONDS,
92427
92585
  PROPERTY_MANAGEMENT_MEMBER_TYPES,
92428
92586
  PStatus,
92429
92587
  PTZ_ALLOWED_ACTIONS,
@@ -92457,6 +92615,7 @@ function usePersonalEmergencyChainController() {
92457
92615
  SubscriptionBillingMode,
92458
92616
  SubscriptionType,
92459
92617
  TRANSPORT_DEVICE_HTTP,
92618
+ TRANSPORT_RELAY_PLAYBACK,
92460
92619
  TRANSPORT_RELAY_PLAYER,
92461
92620
  TRANSPORT_RTSP_FRAME,
92462
92621
  UNSTORED_COLUMNS,
@@ -92616,6 +92775,8 @@ function usePersonalEmergencyChainController() {
92616
92775
  planBulkCameraImport,
92617
92776
  planOrgOwnerRepair,
92618
92777
  platform_terms_namespace_collection,
92778
+ playbackRelays,
92779
+ playbackWindowRefusal,
92619
92780
  promoCodeRefusal,
92620
92781
  promoCodeSchema,
92621
92782
  promoCodeStatusSchema,
@@ -92803,6 +92964,7 @@ function usePersonalEmergencyChainController() {
92803
92964
  sessionSchema,
92804
92965
  setIO,
92805
92966
  shiftSchema,
92967
+ signPlaybackLink,
92806
92968
  siteDayBounds,
92807
92969
  siteModulesHandlers,
92808
92970
  siteSchema,