diff --git a/packages/server/src/middlewares/TimeLockMiddleware.ts b/packages/server/src/middlewares/TimeLockMiddleware.ts new file mode 100644 index 0000000..0681a95 --- /dev/null +++ b/packages/server/src/middlewares/TimeLockMiddleware.ts @@ -0,0 +1,17 @@ +import { RequestHandler } from "express"; +import { getDoorSettingTimeLock } from "../util/EnvConfigUtil"; +import { IDoorStatus } from "../types/IDoorStatus"; + +export const TimeLockVerify: RequestHandler = async (req, res, next) => { + const timeLock = getDoorSettingTimeLock(req.params.id); + + const timeHr = (new Date()).getHours(); + + + if (timeHr >= timeLock[0] || timeHr <= timeLock[1]) { + res.status(401).json({ status: IDoorStatus.TIME_LOCK, msg: 'Sorry! This door is locked at this hour, try again later' }); + return; + } + + next(); +} \ No newline at end of file diff --git a/packages/server/src/routers/DoorRouter.ts b/packages/server/src/routers/DoorRouter.ts index 714f90a..1074dbb 100644 --- a/packages/server/src/routers/DoorRouter.ts +++ b/packages/server/src/routers/DoorRouter.ts @@ -4,16 +4,18 @@ import { doorStatusKey } from "../types/RedisKeys"; import { HandleAuthMode } from "../middlewares/DoorAuthModes"; import { getDoorSettingNumber, getDoorSettingString } from "../util/EnvConfigUtil"; import { IDoorConfig } from "../types/IDoorConfig"; +import { TimeLockVerify } from "../middlewares/TimeLockMiddleware"; +import { IDoorStatus } from "../types/IDoorStatus"; const router = express.Router(); const client = await getRedisClient(); -router.get('/:id/status', async(req, res) => { +router.get('/:id/status', TimeLockVerify, async(req, res) => { const isOpen = await client.get(doorStatusKey(req.params.id)); if (isOpen) { const fingerprint = JSON.parse(isOpen); - res.status(200).json({ status: 'open', fingerprint }); + res.status(200).json({ status: IDoorStatus.OPEN, fingerprint }); if (getDoorSettingString(req.params.id, IDoorConfig.CLOSE_AFTER_POLL)) { await client.remove(doorStatusKey(req.params.id)); @@ -21,7 +23,7 @@ router.get('/:id/status', async(req, res) => { return; } - res.status(401).json({ status: 'closed' }); + res.status(401).json({ status: IDoorStatus.CLOSED }); }); router.delete('/:id/status', async(req, res) => { diff --git a/packages/server/src/types/IDoorConfig.ts b/packages/server/src/types/IDoorConfig.ts index 99da2e0..91acec9 100644 --- a/packages/server/src/types/IDoorConfig.ts +++ b/packages/server/src/types/IDoorConfig.ts @@ -3,4 +3,5 @@ export enum IDoorConfig { OPEN_TIMEOUT = "OPEN_TIMEOUT", FIXED_PIN = "FIXED_PIN", CLOSE_AFTER_POLL="CLOSE_AFTER_POLL", + ALWAYS_LOCKED_TIME="ALWAYS_LOCKED_TIME", } \ No newline at end of file diff --git a/packages/server/src/types/IDoorStatus.ts b/packages/server/src/types/IDoorStatus.ts new file mode 100644 index 0000000..5857a4e --- /dev/null +++ b/packages/server/src/types/IDoorStatus.ts @@ -0,0 +1,5 @@ +export enum IDoorStatus { + OPEN="OPEN", + CLOSED="CLOSED", + TIME_LOCK="TIME_LOCK" +} \ No newline at end of file diff --git a/packages/server/src/util/EnvConfigUtil.ts b/packages/server/src/util/EnvConfigUtil.ts index 00a5eb4..4868151 100644 --- a/packages/server/src/util/EnvConfigUtil.ts +++ b/packages/server/src/util/EnvConfigUtil.ts @@ -21,4 +21,19 @@ export const getDoorSettingString = (door: string, setting: IDoorConfig): string export const getDoorSettingNumber = (door: string, setting: IDoorConfig): number => { return parseInt(getDoorSettingString(door, setting) || "0"); -}; \ No newline at end of file +}; + +export const getDoorSettingTimeLock = (door: string): number[] => { + const config = getDoorSettingString(door, IDoorConfig.ALWAYS_LOCKED_TIME); + + if (config) { + try { + return config.split(',').map(n => parseInt(n)); + } catch (e) { + console.warn(`Config ${IDoorConfig.ALWAYS_LOCKED_TIME} for door ${door} is invalid`); + } + } + + // never locked (always -1 < hr < 25) + return [25, -1]; +} \ No newline at end of file