From 79b03574ffa4cfc3d67df98fc999b6fb98b34426 Mon Sep 17 00:00:00 2001 From: Martin Dimitrov Date: Fri, 3 May 2024 15:08:23 -0700 Subject: [PATCH] recreate backend with lambdas --- .vscode/settings.json | 3 + bun.lockb | Bin 388882 -> 389371 bytes package.json | 2 +- .../client/src/components/AuthComponent.tsx | 2 +- packages/client/src/pages/DoorPage.tsx | 4 +- packages/serverless/.gitignore | 1 - .../serverless/functions/api/door/auth.js | 56 ++++++++++++++++++ .../serverless/functions/api/door/info.js | 44 ++++++++++++++ .../serverless/functions/api/door/status.js | 54 +++++++++++++++++ packages/serverless/package.json | 4 -- 10 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 packages/serverless/functions/api/door/auth.js create mode 100644 packages/serverless/functions/api/door/info.js create mode 100644 packages/serverless/functions/api/door/status.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7d8e6ab --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotenv.enableAutocloaking": false +} \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index ca157889a9f69a597f876a3302ccc21f17348379..ea001727c7004d0c7fbd6279a6c9f969ffa1fb1d 100755 GIT binary patch delta 66231 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 wYCdM-h(V)W#mf>6R=12N*sr2><{9 delta 66755 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

K+8Uw98z^DqU@J; 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 diff --git a/package.json b/package.json index 44370a9..bcb95ad 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ }, "scripts": { "prepare-client-serverless": "bun --filter 'doorman-client' build && cp -fr packages/client/dist/* packages/serverless/assets/ && cp -f packages/serverless/assets/index.html packages/serverless/assets/assets/index.html", - "prepare-server-serverless": "bun --filter 'doorman-server' build && cp -fr packages/server/build/* packages/serverless/functions/ && mv packages/serverless/functions/server.js packages/serverless/functions/api.js", "deploy-serverless": "bun run prepare-client-serverless && bun --filter 'serverless' deploy" }, "peerDependencies": { "typescript": "^5.0.0" }, "dependencies": { + "@types/twilio": "^3.19.3", "crypto": "^1.0.1", "express-fingerprint": "^1.2.2", "hono": "^4.3.0", diff --git a/packages/client/src/components/AuthComponent.tsx b/packages/client/src/components/AuthComponent.tsx index d14e4bb..a0e3a2e 100644 --- a/packages/client/src/components/AuthComponent.tsx +++ b/packages/client/src/components/AuthComponent.tsx @@ -28,7 +28,7 @@ export const AuthComponent = ({ door, secret, authMode, onError, onUnlock, runCh }, [runCheck]) const onSubmit = () => { - fetch(`/api/door/${door}/auth?key=${key}&rotatingKey=${key}`) + fetch(`/api/door/auth?key=${key}&rotatingKey=${key}&door=${door}`) .then(async res => { if (res.status !== 200) { setError("Incorrect PIN"); diff --git a/packages/client/src/pages/DoorPage.tsx b/packages/client/src/pages/DoorPage.tsx index ec439ee..67c50ca 100644 --- a/packages/client/src/pages/DoorPage.tsx +++ b/packages/client/src/pages/DoorPage.tsx @@ -7,7 +7,7 @@ import type { IDoorResponse } from "../../../server/src/types/IDoorResponse"; import { CountdownBar } from "../components/CountdownBar"; export async function loader({ params }: any) { - const response = await fetch(params.door ? `/api/door/${params.door}`: `/api/door`).then(res => res.json()); + const response = await fetch(params.door ? `/api/door/info?door=${params.door}`: `/api/door/info`).then(res => res.json()); console.log(response); @@ -74,7 +74,7 @@ export function DoorPage() { } const timer = setInterval(async () => { - const response = await fetch(`/api/door/${door}`).then(res => res.json()); + const response = await fetch(`/api/door/info?door=${door}`).then(res => res.json()); // polling assumes that the door was opened and whatever closed it was the buzzer system... // ie. state transition from OPEN to CLOSED before timeout means that twilio opened the door diff --git a/packages/serverless/.gitignore b/packages/serverless/.gitignore index a798209..655b8ab 100644 --- a/packages/serverless/.gitignore +++ b/packages/serverless/.gitignore @@ -11,7 +11,6 @@ lerna-debug.log* .pnpm-debug.log* assets -functions # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/packages/serverless/functions/api/door/auth.js b/packages/serverless/functions/api/door/auth.js new file mode 100644 index 0000000..51afa1b --- /dev/null +++ b/packages/serverless/functions/api/door/auth.js @@ -0,0 +1,56 @@ +/** + * Try to unlock the door with auth mode + */ + +const redis = require('redis'); + +function doorStatusKey(id) { + return concatKeys("doors", id, 'open'); +} + +function concatKeys(...keys) { + return keys.join(':'); +} + +exports.handler = function(context, event, callback) { + const response = new Twilio.Response(); + + let door = event.door; + let pin = event.key; + + if (!door || !pin) { + response.setStatusCode(400); + return callback(null, response); + } + + door = door.toUpperCase(); + + if (!context['FIXED_PIN_' + door]) { + response.setStatusCode(404); + return callback(null, response); + } + + let correctPin = context['FIXED_PIN' + door]; + + if (correctPin !== pin) { + response.setStatusCode(401); + return callback(null, response); + } + + let client = new redis.RedisDbClient((err) => console.error(err), { url: context.REDIS_CONNECT_URL }); + client.connect() + .then(async () => { + const statusKey = doorStatusKey(door); + const fingerprint = { method: "PIN" }; + const timeout = context['OPEN_TIMEOUT_' + door] || 60; + + await client.put(statusKey, JSON.stringify(fingerprint)); + await client.getClient().expire(statusKey, timeout); + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ msg: `Opened the door "${door}" for ${timeout}s` }); + + return callback(null, response); + }); +}; \ No newline at end of file diff --git a/packages/serverless/functions/api/door/info.js b/packages/serverless/functions/api/door/info.js new file mode 100644 index 0000000..873e235 --- /dev/null +++ b/packages/serverless/functions/api/door/info.js @@ -0,0 +1,44 @@ +/** + * Try to get door info + */ + +const redis = require('redis'); + +function doorStatusKey(id) { + return concatKeys("doors", id, 'open'); +} + +function concatKeys(...keys) { + return keys.join(':'); +} + +exports.handler = function(context, event, callback) { + const response = new Twilio.Response(); + + let door = event.door || context.DEFAULT_DOOR; + + if (!door) { + response.setStatusCode(400); + return callback(null, response); + } + + door = door.toUpperCase(); + + const timeout = context['OPEN_TIMEOUT_' + door] || 60; + + + res.status(200).json(); + + let client = new RedisDbClient((err) => console.error(err), { url: context.REDIS_CONNECT_URL }); + client.connect() + .then(async () => { + const status = await client.get(doorStatusKey(door)) ? "OPEN": "CLOSED"; + + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ id: doorId, timeout, status }); + + return callback(null, response); + }); +}; \ No newline at end of file diff --git a/packages/serverless/functions/api/door/status.js b/packages/serverless/functions/api/door/status.js new file mode 100644 index 0000000..b15e13d --- /dev/null +++ b/packages/serverless/functions/api/door/status.js @@ -0,0 +1,54 @@ +/** + * Try to update door status + */ + +const redis = require('redis'); + +function doorStatusKey(id) { + return concatKeys("doors", id, 'open'); +} + +function concatKeys(...keys) { + return keys.join(':'); +} + +exports.handler = function(context, event, callback) { + const response = new Twilio.Response(); + + let door = event.door; + + if (!door) { + response.setStatusCode(400); + return callback(null, response); + } + + let client = new RedisDbClient((err) => console.error(err), { url: context.REDIS_CONNECT_URL }); + client.connect() + .then(async () => { + const isOpen = await client.get(doorStatusKey(door)); + + if (isOpen) { + const fingerprint = JSON.parse(isOpen); + + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ + status: "OPEN", + fingerprint, + }); + await client.remove(doorStatusKey(req.params.id)); + + return callback(null, response); + } + + response + .setStatusCode(401) + .appendHeader('Content-Type', 'application/json') + .setBody({ + status: "CLOSED", + }); + + return callback(null, response); + }); +}; \ No newline at end of file diff --git a/packages/serverless/package.json b/packages/serverless/package.json index 08789df..f8d3c83 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -11,10 +11,6 @@ "dependencies": { "twilio": "^3.56", "@twilio/runtime-handler": "1.3.0", - "@codegenie/serverless-express": "^4.14.1", - "express": "^4.18.2", - "express-fileupload": "^1.4.0", - "express-rate-limit": "^6.10.0", "qrcode": "^1.5.3", "redis": "^4.6.8" },