diff --git a/sdk/package-lock.json b/sdk/package-lock.json index a7c40515d..79cadca96 100644 --- a/sdk/package-lock.json +++ b/sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/sdk", - "version": "0.5.57", + "version": "0.5.58", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@scrypted/sdk", - "version": "0.5.57", + "version": "0.5.58", "license": "ISC", "dependencies": { "@babel/preset-typescript": "^7.27.1", diff --git a/sdk/package.json b/sdk/package.json index 3eaf4a7eb..50f895887 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,11 +1,12 @@ { "name": "@scrypted/sdk", - "version": "0.5.57", + "version": "0.5.58", "description": "", "main": "dist/src/index.js", "exports": { ".": "./dist/src/index.js", "./acl": "./dist/src/acl.js", + "./promise-debounce": "./dist/src/promise-debounce.js", "./storage-settings": "./dist/src/storage-settings.js", "./settings-mixin": "./dist/src/settings-mixin.js" }, diff --git a/sdk/src/acl.ts b/sdk/src/acl.ts index 492bd2720..b0ede1492 100644 --- a/sdk/src/acl.ts +++ b/sdk/src/acl.ts @@ -1,4 +1,5 @@ -import { EventDetails, ScryptedDeviceAccessControl, ScryptedInterface, ScryptedInterfaceDescriptors, ScryptedUserAccessControl } from "."; +import sdk, { EventDetails, ScryptedDeviceAccessControl, ScryptedInterface, ScryptedInterfaceDescriptors, ScryptedUser, ScryptedUserAccessControl } from "."; +import { createCachingMapPromiseDebouncer } from './promise-debounce'; export function addAccessControlsForInterface(id: string, ...scryptedInterfaces: ScryptedInterface[]): ScryptedDeviceAccessControl { const methods = scryptedInterfaces.map(scryptedInterface => ScryptedInterfaceDescriptors[scryptedInterface]?.methods || []).flat(); @@ -117,4 +118,35 @@ export class AccessControls { return true; } -} \ No newline at end of file +} + + +const accessControls = createCachingMapPromiseDebouncer(60 * 1000); + +export async function checkUserId(id: string, userId: string) { + const user = sdk.systemManager.getDeviceById(userId); + if (!user || !user.interfaces?.includes(ScryptedInterface.ScryptedUser)) { + // console.error('Error delivering notification, invalid user id:', userId); + return; + } + + if (!sdk.systemManager.getDeviceById(id)) + return; + + try { + const acl = await accessControls(userId, async () => { + const acls = await user.getScryptedUserAccessControl(); + const acl = acls ? new AccessControls(acls) : undefined; + return acl; + }); + if (acl?.shouldRejectDevice(id)) { + return; + } + } + catch (e) { + // console.error('Error delivering notification, ACL check failed.', e); + return; + } + + return user; +} diff --git a/sdk/src/promise-debounce.ts b/sdk/src/promise-debounce.ts new file mode 100644 index 000000000..a48b4c3c3 --- /dev/null +++ b/sdk/src/promise-debounce.ts @@ -0,0 +1,14 @@ +export function createCachingMapPromiseDebouncer(duration: number) { + const map = new Map>(); + + return (key: any, func: () => Promise): Promise => { + const keyStr = JSON.stringify(key); + let value = map.get(keyStr); + if (!value) { + value = func(); + map.set(keyStr, value); + setTimeout(() => map.delete(keyStr), duration); + } + return value; + } +} diff --git a/sdk/types/package-lock.json b/sdk/types/package-lock.json index a4e613777..6b56e197a 100644 --- a/sdk/types/package-lock.json +++ b/sdk/types/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/types", - "version": "0.5.53", + "version": "0.5.54", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@scrypted/types", - "version": "0.5.53", + "version": "0.5.54", "license": "ISC", "dependencies": { "openai": "^6.1.0" diff --git a/sdk/types/package.json b/sdk/types/package.json index 37ea9ff80..b61285f17 100644 --- a/sdk/types/package.json +++ b/sdk/types/package.json @@ -1,6 +1,6 @@ { "name": "@scrypted/types", - "version": "0.5.53", + "version": "0.5.54", "description": "", "main": "dist/index.js", "author": "", diff --git a/sdk/types/scrypted_python/scrypted_sdk/types.py b/sdk/types/scrypted_python/scrypted_sdk/types.py index 1d7e958cc..3b99e3fcb 100644 --- a/sdk/types/scrypted_python/scrypted_sdk/types.py +++ b/sdk/types/scrypted_python/scrypted_sdk/types.py @@ -1131,7 +1131,7 @@ class TamperState(TypedDict): pass -TYPES_VERSION = "0.5.53" +TYPES_VERSION = "0.5.54" class AirPurifier: