From 50c4e9ae2cdc0c0c414e706014dd565de2bde333 Mon Sep 17 00:00:00 2001 From: Martin Dimitrov Date: Sat, 31 May 2025 14:47:43 -0700 Subject: [PATCH] migrate auth route --- .../src/functions/api/door/auth.ts | 64 ++++++++----------- packages/doorman-api/src/schema/LockStatus.ts | 16 ++++- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/doorman-api/src/functions/api/door/auth.ts b/packages/doorman-api/src/functions/api/door/auth.ts index 21653c9..902f807 100644 --- a/packages/doorman-api/src/functions/api/door/auth.ts +++ b/packages/doorman-api/src/functions/api/door/auth.ts @@ -5,14 +5,14 @@ import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types"; import { TwilioContext } from "../../../types/TwilioContext"; import { UserAgentHeader } from "../../../utils/blockUserAgent"; -import { clearLockStatusCommand, createDDBClient, ddbItemToJSON, getDoorConfigCommand, getLockStatusCommand, isLockOpen, setLockStatusCommand } from "../../../utils/ddb"; -import { DoorConfig } from "../../../types/DoorConfig"; +import { createDynaBridgeClient } from "../../../utils/ddb"; import { AuthMethod } from "../../../types/AuthMethod"; -import { Lock } from "../../../types/Lock"; import { DoorStatus } from "../../../types/DoorStatus"; import { getMetricFromRegistry, withMetrics } from "../../../common/DoormanHandler"; import { AuthMetrics, registerMetrics } from "../../../metrics/AuthMetrics"; import { Counter } from "prom-client"; +import { DoorConfig, getDoorConfigID } from "../../../schema/DoorConfig"; +import { createLockStatusWithTimeout, getLockStatusID, isLockOpen } from "../../../schema/LockStatus"; export interface AuthRequest extends ServerlessEventObject<{}, UserAgentHeader> { door?: string; @@ -34,10 +34,9 @@ export const handler: ServerlessFunctionSignature = return callback(null, response); } - const client = createDDBClient(context); + const db = createDynaBridgeClient(context); - const ddbConfig = await client.send(getDoorConfigCommand(door)); - const config: DoorConfig = ddbItemToJSON(ddbConfig); + const config: DoorConfig | undefined = await db.entities.doorConfig.findById(getDoorConfigID(door)); if (!config) { getMetricFromRegistry(metricsRegistry, AuthMetrics.DOOR_CONFIG_NOT_FOUND).inc({ door }, 1); @@ -76,41 +75,32 @@ export const handler: ServerlessFunctionSignature = const timeout = event.timeout ? parseInt(event.timeout) : config.timeout; // check lock status if locked, then unlock. If unlocked then lock - await client.send(getLockStatusCommand(door)) - .then(async (lockDdb) => { - const isOpen = isLockOpen(lockDdb); + const lock = await db.entities.lockStatus.findById(getLockStatusID(door)); + const isOpen = isLockOpen(lock); - if (isOpen) { - const lock: Lock = ddbItemToJSON(lockDdb); - const fingerprint = JSON.parse(lock.fingerprint); + if (isOpen && lock) { + const fingerprint = JSON.parse(lock.fingerprint); - response - .setStatusCode(200) - .appendHeader('Content-Type', 'application/json') - .setBody({ - status: DoorStatus.CLOSED, - fingerprint, - }); + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ + status: DoorStatus.CLOSED, + fingerprint, + }); - await client.send(clearLockStatusCommand(lockDdb)); - return; - } + await db.entities.lockStatus.deleteById(getLockStatusID(door)); + } else { + await db.entities.lockStatus.save(createLockStatusWithTimeout(door, timeout, fingerprint)); + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ msg: `Opened the door "${door}" for ${timeout}s` }); + } - await client.send(setLockStatusCommand(door, timeout, fingerprint)) - .then(async (item) => { - response - .setStatusCode(200) - .appendHeader('Content-Type', 'application/json') - .setBody({ msg: `Opened the door "${door}" for ${timeout}s` }); - }).catch((e) => { - console.log(e); - response - .setStatusCode(500) - .appendHeader('Content-Type', 'application/json') - .setBody({ err: e }); - }); - }); + // destroy the internal client after + // @ts-ignore + db.ddbClient.destroy(); - await client.destroy(); return callback(null, response); }); diff --git a/packages/doorman-api/src/schema/LockStatus.ts b/packages/doorman-api/src/schema/LockStatus.ts index 682646c..3c67733 100644 --- a/packages/doorman-api/src/schema/LockStatus.ts +++ b/packages/doorman-api/src/schema/LockStatus.ts @@ -5,14 +5,15 @@ export const LOCK_STATUS_SK = "lock"; export const LockStatusSchema = z.object({ // keys - PK: z.string(), // phone number (buzzer number) + PK: z.string(), // door name SK: z.literal(LOCK_STATUS_SK).default(LOCK_STATUS_SK), + TTL: z.number(), fingerprint: z.string(), }); -export const getLockStatusID = (buzzer: string): string[] => { - return [buzzer, LOCK_STATUS_SK]; +export const getLockStatusID = (door: string): string[] => { + return [door, LOCK_STATUS_SK]; } export type LockStatus = z.infer; @@ -28,3 +29,12 @@ export const isLockOpen = (lock?: LockStatus) => { return parseInt("" + ttl) > Date.now(); }; + +export const createLockStatusWithTimeout = (door: string, timeoutSeconds: number, fingerprint: any): LockStatus => { + return { + PK: door, + SK: LOCK_STATUS_SK, + TTL: Date.now() + timeoutSeconds * 1000, + fingerprint: JSON.stringify(fingerprint), + }; +};