{"version":3,"file":"index.cjs","names":["z"],"sources":["../src/constants.ts","../src/auth.ts","../src/config.ts","../src/accessory.ts","../src/platform.ts","../src/index.ts"],"sourcesContent":["/**\n * The npm package name / Homebridge plugin identifier.\n */\nexport const PLUGIN_NAME = 'homebridge-http-motion-sensor';\n\n/**\n * The Homebridge platform identifier in config.json.\n */\nexport const PLATFORM_NAME = 'HttpMotionSensorPlatform';\n","import { createHash, timingSafeEqual } from 'crypto';\nimport type { IncomingMessage } from 'http';\n\nimport type { SensorAuthConfig } from './config.ts';\n\nfunction secureCompare(expected: string, actual: string): boolean {\n    const expectedDigest = createHash('sha256').update(expected).digest();\n    const actualDigest = createHash('sha256').update(actual).digest();\n    return timingSafeEqual(expectedDigest, actualDigest);\n}\n\nfunction getAuthorizationHeader(request: IncomingMessage): string | undefined {\n    const value = request.headers.authorization;\n\n    if (value === undefined) {\n        return undefined;\n    }\n\n    if (Array.isArray(value)) {\n        return value[0];\n    }\n\n    return value;\n}\n\nfunction validateBearerAuth(request: IncomingMessage, token: string): boolean {\n    const authorization = getAuthorizationHeader(request);\n    if (!authorization) {\n        return false;\n    }\n\n    const bearerPrefix = /^bearer\\s+/i;\n    if (!bearerPrefix.test(authorization)) {\n        return false;\n    }\n\n    const providedToken = authorization.replace(bearerPrefix, '');\n    return secureCompare(token, providedToken);\n}\n\nfunction validateBasicAuth(request: IncomingMessage, username: string, password: string): boolean {\n    const authorization = getAuthorizationHeader(request);\n    if (!authorization) {\n        return false;\n    }\n\n    const basicPrefix = /^basic\\s+/i;\n    if (!basicPrefix.test(authorization)) {\n        return false;\n    }\n\n    const encoded = authorization.replace(basicPrefix, '');\n    let decoded: string;\n\n    try {\n        decoded = Buffer.from(encoded, 'base64').toString('utf8');\n    } catch {\n        return false;\n    }\n\n    const separatorIndex = decoded.indexOf(':');\n    if (separatorIndex === -1) {\n        return false;\n    }\n\n    const providedUsername = decoded.slice(0, separatorIndex);\n    const providedPassword = decoded.slice(separatorIndex + 1);\n\n    const usernameMatch = secureCompare(username, providedUsername);\n    const passwordMatch = secureCompare(password, providedPassword);\n    return usernameMatch && passwordMatch;\n}\n\nfunction validateHeaderAuth(request: IncomingMessage, headerName: string, headerValue: string): boolean {\n    const headerKey = headerName.toLowerCase();\n    const raw = request.headers[headerKey];\n\n    if (typeof raw === 'string') {\n        return secureCompare(headerValue, raw);\n    }\n\n    if (Array.isArray(raw) && raw.length > 0) {\n        return secureCompare(headerValue, raw[0] ?? '');\n    }\n\n    return false;\n}\n\nexport function isAuthEnabled(auth: SensorAuthConfig | undefined): auth is SensorAuthConfig {\n    return auth !== undefined;\n}\n\nexport function getAuthStatusMessage(auth: SensorAuthConfig | undefined): string {\n    if (!auth) {\n        return 'disabled';\n    }\n\n    switch (auth.mode) {\n        case 'bearer':\n            return 'bearer';\n        case 'basic':\n            return 'basic';\n        case 'header':\n            return `header (${auth.header_name})`;\n    }\n}\n\nexport function validateInboundAuth(request: IncomingMessage, auth: SensorAuthConfig): boolean {\n    switch (auth.mode) {\n        case 'bearer':\n            return validateBearerAuth(request, auth.token);\n        case 'basic':\n            return validateBasicAuth(request, auth.username, auth.password);\n        case 'header':\n            return validateHeaderAuth(request, auth.header_name, auth.header_value);\n    }\n}\n","import type { API, PlatformConfig } from 'homebridge';\nimport { z } from 'zod';\n\nimport { PLUGIN_NAME } from './constants.ts';\n\nexport const DEFAULT_RESET_TIMEOUT_SECONDS = 11;\n\n/** @deprecated Use getMotionResetMs(sensor) instead */\nexport const MOTION_RESET_MS = DEFAULT_RESET_TIMEOUT_SECONDS * 1000;\n\nconst repeaterEntrySchema = z.object({\n    host: z.string().min(1, 'Host is required'),\n    port: z.coerce.number().int().min(1).max(65535, 'Port must be between 1 and 65535'),\n    path: z.string().min(1, 'Path is required'),\n    auth: z.string().optional(),\n});\n\nconst bearerAuthSchema = z.object({\n    mode: z.literal('bearer'),\n    token: z.string().min(1, 'Bearer token is required'),\n});\n\nconst basicAuthSchema = z.object({\n    mode: z.literal('basic'),\n    username: z.string().min(1, 'Username is required'),\n    password: z.string().min(1, 'Password is required'),\n});\n\nconst headerAuthSchema = z.object({\n    mode: z.literal('header'),\n    header_name: z.string().min(1, 'Header name is required'),\n    header_value: z.string().min(1, 'Header value is required'),\n});\n\nconst sensorAuthSchema = z.discriminatedUnion('mode', [bearerAuthSchema, basicAuthSchema, headerAuthSchema]);\n\nconst optionalSensorAuthSchema = z\n    .union([\n        sensorAuthSchema,\n        z.object({\n            mode: z.literal('none'),\n        }),\n    ])\n    .optional()\n    .transform((auth) => (auth?.mode === 'none' ? undefined : auth));\n\nconst sensorConfigSchema = z.object({\n    name: z.string().min(1, 'Sensor name is required'),\n    port: z.coerce.number().int().min(1024, 'Port must be at least 1024').max(65535, 'Port must be at most 65535'),\n    model: z.string().optional(),\n    serial: z.string().optional(),\n    bind_ip: z.union([z.ipv4(), z.ipv6()]).optional().or(z.literal('0.0.0.0')),\n    reset_timeout: z.coerce.number().int().min(1).max(3600).optional(),\n    auth: optionalSensorAuthSchema,\n    repeater: z.array(repeaterEntrySchema).optional(),\n});\n\nconst platformConfigSchema = z.object({\n    name: z.string().min(1, 'Platform name is required'),\n    platform: z.literal('HttpMotionSensorPlatform'),\n    sensors: z.array(sensorConfigSchema).min(1, 'At least one sensor is required'),\n});\n\nexport type HomebridgeHttpMotionSensorRepeaterEntry = z.infer<typeof repeaterEntrySchema>;\nexport type SensorAuthConfig = z.infer<typeof sensorAuthSchema>;\nexport type HomebridgeHttpMotionSensorConfig = z.infer<typeof sensorConfigSchema>;\nexport type HttpMotionSensorPlatformConfig = z.infer<typeof platformConfigSchema>;\n\nexport interface SensorAccessoryContext {\n    sensor: HomebridgeHttpMotionSensorConfig;\n}\n\nexport function buildSensorUuid(api: API, sensor: HomebridgeHttpMotionSensorConfig): string {\n    const identity = sensor.serial ?? sensor.name;\n    return api.hap.uuid.generate(`${PLUGIN_NAME}:${identity}:${sensor.port}`);\n}\n\nexport function getMotionResetMs(sensor: HomebridgeHttpMotionSensorConfig): number {\n    return (sensor.reset_timeout ?? DEFAULT_RESET_TIMEOUT_SECONDS) * 1000;\n}\n\nexport function sensorRuntimeConfigEqual(\n    a: HomebridgeHttpMotionSensorConfig,\n    b: HomebridgeHttpMotionSensorConfig,\n): boolean {\n    return (\n        a.port === b.port &&\n        (a.bind_ip ?? '0.0.0.0') === (b.bind_ip ?? '0.0.0.0') &&\n        (a.reset_timeout ?? DEFAULT_RESET_TIMEOUT_SECONDS) === (b.reset_timeout ?? DEFAULT_RESET_TIMEOUT_SECONDS) &&\n        JSON.stringify(a.auth ?? null) === JSON.stringify(b.auth ?? null) &&\n        JSON.stringify(a.repeater ?? []) === JSON.stringify(b.repeater ?? [])\n    );\n}\n\nexport class PlatformOptions {\n    readonly name: string;\n    readonly sensors: HomebridgeHttpMotionSensorConfig[];\n\n    constructor(config: PlatformConfig) {\n        const result = platformConfigSchema.safeParse(config);\n        if (!result.success) {\n            const messages = result.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);\n            throw new Error(`Platform configuration validation failed: ${messages.join('; ')}`);\n        }\n\n        this.name = result.data.name;\n        this.sensors = result.data.sensors;\n    }\n}\n\nexport function parsePlatformConfig(config: unknown): HttpMotionSensorPlatformConfig {\n    return platformConfigSchema.parse(config);\n}\n","import type { API, Logging, PlatformAccessory, Service } from 'homebridge';\nimport { createServer, get, type IncomingMessage, type RequestOptions, type Server, type ServerResponse } from 'http';\n\nimport { getAuthStatusMessage, isAuthEnabled, validateInboundAuth } from './auth.ts';\nimport {\n    type HomebridgeHttpMotionSensorConfig,\n    type HomebridgeHttpMotionSensorRepeaterEntry,\n    type SensorAccessoryContext,\n    getMotionResetMs,\n    sensorRuntimeConfigEqual,\n} from './config.ts';\n\nexport function buildRepeaterRequestOptions(repeater: HomebridgeHttpMotionSensorRepeaterEntry): RequestOptions {\n    const options: RequestOptions = {\n        host: repeater.host,\n        port: repeater.port,\n        path: repeater.path,\n        method: 'GET',\n    };\n\n    if (repeater.auth) {\n        options.headers = {\n            Authorization: repeater.auth,\n        };\n    }\n\n    return options;\n}\n\nexport class HttpMotionSensorAccessory {\n    private motionDetected = false;\n    private timeout: ReturnType<typeof setTimeout> | null = null;\n\n    private motionSensorService?: Service;\n    private server?: Server;\n    private config: HomebridgeHttpMotionSensorConfig;\n    private readonly bindIP: string;\n\n    constructor(\n        private readonly log: Logging,\n        config: HomebridgeHttpMotionSensorConfig,\n        private readonly platformAccessory: PlatformAccessory<SensorAccessoryContext>,\n        private readonly api: API,\n    ) {\n        this.config = config;\n        this.bindIP = this.config.bind_ip ?? '0.0.0.0';\n        this.platformAccessory.context.sensor = this.config;\n\n        this.setupServices();\n        this.setupHttpServer();\n    }\n\n    hasSameRuntimeConfig(config: HomebridgeHttpMotionSensorConfig): boolean {\n        return sensorRuntimeConfigEqual(this.config, config);\n    }\n\n    updateMetadata(config: HomebridgeHttpMotionSensorConfig): void {\n        this.config = config;\n        this.platformAccessory.context.sensor = config;\n\n        const hap = this.api.hap;\n        const informationService = this.platformAccessory.getService(hap.Service.AccessoryInformation);\n        informationService\n            ?.setCharacteristic(hap.Characteristic.Model, config.model ?? 'HTTP Motion Sensor')\n            .setCharacteristic(hap.Characteristic.SerialNumber, config.serial ?? 'Default-Serial');\n    }\n\n    private setupServices(): void {\n        const hap = this.api.hap;\n\n        let informationService = this.platformAccessory.getService(hap.Service.AccessoryInformation);\n        if (!informationService) {\n            informationService = new hap.Service.AccessoryInformation();\n            this.platformAccessory.addService(informationService);\n        }\n\n        informationService\n            .setCharacteristic(hap.Characteristic.Manufacturer, 'Homebridge')\n            .setCharacteristic(hap.Characteristic.Model, this.config.model ?? 'HTTP Motion Sensor')\n            .setCharacteristic(hap.Characteristic.SerialNumber, this.config.serial ?? 'Default-Serial');\n\n        let motionSensorService = this.platformAccessory.getService(hap.Service.MotionSensor);\n        if (!motionSensorService) {\n            motionSensorService = new hap.Service.MotionSensor(this.config.name);\n            this.platformAccessory.addService(motionSensorService);\n        }\n\n        motionSensorService.getCharacteristic(hap.Characteristic.MotionDetected).onGet(() => this.motionDetected);\n        this.motionSensorService = motionSensorService;\n    }\n\n    private setupHttpServer(): void {\n        this.server = createServer((request, response) => {\n            this.handleHttpRequest(request, response);\n        });\n\n        this.server.listen(this.config.port, this.bindIP, () => {\n            this.log.info(\n                `HTTP Motion Sensor '${this.config.name}' is listening on http://${this.bindIP}:${this.config.port}`,\n            );\n\n            if (this.config.auth) {\n                this.log.debug(\n                    `HTTP Motion Sensor '${this.config.name}': authentication enabled (${getAuthStatusMessage(this.config.auth)})`,\n                );\n            }\n        });\n\n        this.server.on('error', (error) => {\n            this.log.error(`HTTP Server error: ${error.message}`);\n        });\n    }\n\n    private handleHttpRequest(request: IncomingMessage, response: ServerResponse): void {\n        if (isAuthEnabled(this.config.auth) && !validateInboundAuth(request, this.config.auth)) {\n            this.log.warn(\n                `Rejected unauthenticated request to '${this.config.name}' from ${request.socket.remoteAddress ?? 'unknown'}`,\n            );\n            response.writeHead(401, { 'Content-Type': 'text/plain' });\n            response.end('Unauthorized');\n            return;\n        }\n\n        this.httpHandler();\n        response.writeHead(200, { 'Content-Type': 'text/plain' });\n        response.end('Successfully requested: ' + request.url);\n    }\n\n    private httpHandler(): void {\n        if (this.config.repeater && Array.isArray(this.config.repeater)) {\n            for (const repeater of this.config.repeater) {\n                const options = buildRepeaterRequestOptions(repeater);\n                const url = `http://${repeater.host}:${repeater.port}${repeater.path}`;\n\n                get(options, () => {\n                    this.log.debug(`Repeater request to ${url} successful`);\n                }).on('error', (error) => {\n                    this.log.warn(`Repeater request to ${url} failed: ${error.message}`);\n                });\n            }\n        }\n\n        this.setMotionDetected(true);\n\n        if (this.timeout) {\n            clearTimeout(this.timeout);\n        }\n\n        this.timeout = setTimeout(() => {\n            this.setMotionDetected(false);\n            this.timeout = null;\n            this.log.debug('Motion detection reset');\n        }, getMotionResetMs(this.config));\n    }\n\n    private setMotionDetected(detected: boolean): void {\n        this.motionDetected = detected;\n\n        if (!this.motionSensorService) {\n            return;\n        }\n\n        this.motionSensorService\n            .getCharacteristic(this.api.hap.Characteristic.MotionDetected)\n            .updateValue(this.motionDetected);\n\n        if (detected) {\n            this.log.debug('Motion detected via HTTP request');\n        }\n    }\n\n    shutdown(): Promise<void> {\n        if (this.timeout) {\n            clearTimeout(this.timeout);\n            this.timeout = null;\n        }\n\n        if (!this.server) {\n            return Promise.resolve();\n        }\n\n        const server = this.server;\n        this.server = undefined;\n\n        return new Promise((resolve) => {\n            server.close(() => {\n                this.log.info(`HTTP server shutdown for '${this.config.name}'`);\n                resolve();\n            });\n        });\n    }\n}\n","import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig } from 'homebridge';\n\nimport { HttpMotionSensorAccessory } from './accessory.ts';\nimport { PLATFORM_NAME, PLUGIN_NAME } from './constants.ts';\nimport {\n    type HomebridgeHttpMotionSensorConfig,\n    type SensorAccessoryContext,\n    PlatformOptions,\n    buildSensorUuid,\n} from './config.ts';\n\nexport class HttpMotionSensorPlatform implements DynamicPlatformPlugin {\n    private readonly options: PlatformOptions;\n    private readonly cachedAccessories = new Map<string, PlatformAccessory<SensorAccessoryContext>>();\n    private readonly handlers = new Map<string, HttpMotionSensorAccessory>();\n\n    constructor(\n        private readonly log: Logging,\n        config: PlatformConfig,\n        private readonly api: API,\n    ) {\n        this.log.info('Initializing HttpMotionSensorPlatform');\n\n        try {\n            this.options = new PlatformOptions(config);\n        } catch (error) {\n            const message = error instanceof Error ? error.message : String(error);\n            this.log.error(`Invalid platform configuration: ${message}`);\n            throw error;\n        }\n\n        this.log.info(`Found ${this.options.sensors.length} motion sensor(s) in configuration`);\n\n        this.api.on('didFinishLaunching', () => {\n            void this.syncSensorsFromConfig();\n        });\n\n        this.api.on('shutdown', () => {\n            void this.shutdownHandlers();\n        });\n    }\n\n    configureAccessory(accessory: PlatformAccessory): void {\n        const platformAccessory = accessory as PlatformAccessory<SensorAccessoryContext>;\n        this.cachedAccessories.set(accessory.UUID, platformAccessory);\n        this.log.debug(`Loaded cached accessory: ${accessory.displayName} (${accessory.UUID})`);\n\n        const sensorConfig = this.findSensorConfigByUuid(accessory.UUID);\n        if (!sensorConfig) {\n            this.log.warn(\n                `Cached accessory '${accessory.displayName}' does not match any sensor in config — will be removed on sync`,\n            );\n            return;\n        }\n\n        void this.attachHandler(sensorConfig, platformAccessory, { source: 'cache' });\n    }\n\n    private findSensorConfigByUuid(uuid: string): HomebridgeHttpMotionSensorConfig | undefined {\n        return this.options.sensors.find((sensor) => buildSensorUuid(this.api, sensor) === uuid);\n    }\n\n    private updateAccessoryDisplayName(accessory: PlatformAccessory, name: string): void {\n        if (accessory.displayName !== name) {\n            accessory.updateDisplayName(name);\n        }\n    }\n\n    private async shutdownHandlers(): Promise<void> {\n        await Promise.all([...this.handlers.values()].map((handler) => handler.shutdown()));\n        this.handlers.clear();\n    }\n\n    private async attachHandler(\n        sensorConfig: HomebridgeHttpMotionSensorConfig,\n        platformAccessory: PlatformAccessory<SensorAccessoryContext>,\n        options: { source: 'cache' | 'sync' },\n    ): Promise<boolean> {\n        const uuid = buildSensorUuid(this.api, sensorConfig);\n        const existingHandler = this.handlers.get(uuid);\n\n        if (existingHandler?.hasSameRuntimeConfig(sensorConfig)) {\n            existingHandler.updateMetadata(sensorConfig);\n            this.updateAccessoryDisplayName(platformAccessory, sensorConfig.name);\n            return true;\n        }\n\n        if (existingHandler) {\n            await existingHandler.shutdown();\n            this.handlers.delete(uuid);\n        }\n\n        try {\n            const handler = new HttpMotionSensorAccessory(this.log, sensorConfig, platformAccessory, this.api);\n            this.handlers.set(uuid, handler);\n            this.updateAccessoryDisplayName(platformAccessory, sensorConfig.name);\n\n            if (options.source === 'cache') {\n                this.log.info(`Restored motion sensor from cache: ${sensorConfig.name}`);\n            }\n\n            return true;\n        } catch (error) {\n            const message = error instanceof Error ? error.message : String(error);\n            this.log.error(`Failed to create motion sensor ${sensorConfig.name}: ${message}`);\n            return false;\n        }\n    }\n\n    private async syncSensorsFromConfig(): Promise<void> {\n        const expectedUuids = new Set<string>();\n        const newAccessories: PlatformAccessory<SensorAccessoryContext>[] = [];\n\n        for (const sensorConfig of this.options.sensors) {\n            const uuid = buildSensorUuid(this.api, sensorConfig);\n            expectedUuids.add(uuid);\n\n            let platformAccessory = this.cachedAccessories.get(uuid);\n            const isNew = !platformAccessory;\n\n            if (!platformAccessory) {\n                const PlatformAccessoryClass = this.api.platformAccessory;\n                platformAccessory = new PlatformAccessoryClass(\n                    sensorConfig.name,\n                    uuid,\n                ) as PlatformAccessory<SensorAccessoryContext>;\n                this.cachedAccessories.set(uuid, platformAccessory);\n            }\n\n            if (this.handlers.has(uuid)) {\n                const handler = this.handlers.get(uuid)!;\n                if (handler.hasSameRuntimeConfig(sensorConfig)) {\n                    handler.updateMetadata(sensorConfig);\n                    this.updateAccessoryDisplayName(platformAccessory, sensorConfig.name);\n                } else {\n                    await this.attachHandler(sensorConfig, platformAccessory, { source: 'sync' });\n                }\n                continue;\n            }\n\n            const attached = await this.attachHandler(sensorConfig, platformAccessory, { source: 'sync' });\n            if (!attached) {\n                if (isNew) {\n                    this.cachedAccessories.delete(uuid);\n                }\n                continue;\n            }\n\n            if (isNew) {\n                newAccessories.push(platformAccessory);\n                this.log.info(`Successfully created motion sensor: ${sensorConfig.name}`);\n            }\n        }\n\n        if (newAccessories.length > 0) {\n            this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, newAccessories);\n        }\n\n        const staleAccessories: PlatformAccessory<SensorAccessoryContext>[] = [];\n\n        for (const [uuid, accessory] of this.cachedAccessories) {\n            if (!expectedUuids.has(uuid)) {\n                staleAccessories.push(accessory);\n            }\n        }\n\n        if (staleAccessories.length > 0) {\n            await Promise.all(\n                staleAccessories.map(async (accessory) => {\n                    const handler = this.handlers.get(accessory.UUID);\n                    if (handler) {\n                        await handler.shutdown();\n                        this.handlers.delete(accessory.UUID);\n                    }\n                }),\n            );\n\n            for (const accessory of staleAccessories) {\n                this.cachedAccessories.delete(accessory.UUID);\n                this.log.info(`Removing motion sensor no longer in config: ${accessory.displayName}`);\n            }\n\n            this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, staleAccessories);\n        }\n    }\n}\n","import type { API } from 'homebridge';\n\nimport { PLATFORM_NAME, PLUGIN_NAME } from './constants.ts';\nimport { HttpMotionSensorPlatform } from './platform.ts';\n\nexport default (api: API): void => {\n    api.registerPlatform(PLUGIN_NAME, PLATFORM_NAME, HttpMotionSensorPlatform);\n};\n"],"mappings":"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"}