diff --git a/package.json b/package.json index bcb95ad..6fb94e9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "bun-types": "latest" }, "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-client-serverless": "bun --filter 'doorman-client' build && rm -rf packages/serverless/assets/* && mkdir packages/serverless/assets/assets && cp -fr packages/client/dist/* packages/serverless/assets/ && cp -f packages/serverless/assets/index.html packages/serverless/assets/assets/index.html", "deploy-serverless": "bun run prepare-client-serverless && bun --filter 'serverless' deploy" }, "peerDependencies": { diff --git a/packages/client/src/index.tsx b/packages/client/src/index.tsx index f644adf..ac91d02 100644 --- a/packages/client/src/index.tsx +++ b/packages/client/src/index.tsx @@ -19,11 +19,6 @@ const router = createBrowserRouter([ path: "", loader: doorpageloader, element: - }, - { - path: "door/:door", - loader: doorpageloader, - element: , } ] } diff --git a/packages/client/src/pages/DoorPage.tsx b/packages/client/src/pages/DoorPage.tsx index b32fbf8..3a35ffa 100644 --- a/packages/client/src/pages/DoorPage.tsx +++ b/packages/client/src/pages/DoorPage.tsx @@ -6,8 +6,10 @@ import OtpInput from 'react-otp-input'; 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/info?door=${params.door}`: `/api/door/info`).then(res => res.json()); +export async function loader({ params, request }: any) { + const door = new URL(request.url).searchParams.get('door'); + + const response = await fetch(`/api/door/info?door=${door}`).then(res => res.json()); console.log(response); @@ -241,8 +243,8 @@ export function DoorPage() { width: '2rem', fontSize: '2rem', }} - value={'2207'} - numInputs={4} + value={doorResponse.buzzerCode} + numInputs={doorResponse.buzzerCode.length} onChange={() => null} renderSeparator={() => -} renderInput={(props) => } diff --git a/packages/server/src/types/IDoorResponse.ts b/packages/server/src/types/IDoorResponse.ts index e6e6992..bd77640 100644 --- a/packages/server/src/types/IDoorResponse.ts +++ b/packages/server/src/types/IDoorResponse.ts @@ -1,7 +1,5 @@ -import { IAuthMode } from "./IAuthMode"; - export interface IDoorResponse { id: string, - authModes: IAuthMode[]; timeout: number; -} \ No newline at end of file + buzzerCode: string; +}; diff --git a/packages/serverless/functions/api/door/auth.js b/packages/serverless/functions/api/door/auth.js index 1c0c788..dc235a3 100644 --- a/packages/serverless/functions/api/door/auth.js +++ b/packages/serverless/functions/api/door/auth.js @@ -13,27 +13,29 @@ exports.handler = async function(context, event, callback) { return callback(null, response); } - if (!context['FIXED_PIN_' + door.toUpperCase()]) { + const ddbPath = Runtime.getFunctions()['common/ddb'].path; + const ddb = require(ddbPath); + const client = ddb.createDDBClient(context); + + const config = await client.send(ddb.getDoorConfigCommand(door)); + + if (!config.Item) { response.setStatusCode(404); return callback(null, response); } - let correctPin = context['FIXED_PIN_' + door.toUpperCase()]; + let correctPin = config.Item.pin.S; if (correctPin !== pin) { response.setStatusCode(401); return callback(null, response); } - const ddbPath = Runtime.getFunctions()['common/ddb'].path; - const ddb = require(ddbPath); - const client = ddb.createDDBClient(context); - const fingerprint = { method: "PIN", userAgent: event.request.headers['user-agent'], }; - const timeout = context['OPEN_TIMEOUT_' + door.toUpperCase()] || 60; + const timeout = config.Item.timeout.N; await client.send(ddb.setLockStatusCommand(door, timeout, fingerprint)) .then(async (item) => { diff --git a/packages/serverless/functions/api/door/info.js b/packages/serverless/functions/api/door/info.js index cc4a695..ac8a242 100644 --- a/packages/serverless/functions/api/door/info.js +++ b/packages/serverless/functions/api/door/info.js @@ -5,9 +5,10 @@ exports.handler = async function(context, event, callback) { const response = new Twilio.Response(); - const door = event.door || context.DEFAULT_DOOR; + let door = event.door; + const buzzer = event.buzzer?.slice(-10); - if (!door) { + if (!door && !buzzer) { response.setStatusCode(400); return callback(null, response); } @@ -16,24 +17,58 @@ exports.handler = async function(context, event, callback) { const ddb = require(ddbPath); const client = ddb.createDDBClient(context); - const timeout = context['OPEN_TIMEOUT_' + door.toUpperCase()] || 60; + if (buzzer) { + door = await client.send(ddb.getDoorAliasCommand(buzzer)) + .then(async (alias) => { + if (!alias.Item) { + response + .setStatusCode(404) + .appendHeader('Content-Type', 'application/json') + .setBody({ err: "This buzzer is not registered" }); + return undefined; + } + return alias.Item.name.S; + }); + } - await client.send(ddb.getLockStatusCommand(door)) - .then(async (lock) => { - const status = ddb.isLockOpen(lock) ? "OPEN": "CLOSED"; + if (door) { + const config = await client.send(ddb.getDoorConfigCommand(door)); + if (!config.Item) { response - .setStatusCode(200) + .setStatusCode(404) .appendHeader('Content-Type', 'application/json') - .setBody({ id: door, timeout, status }); - - }).catch((e) => { - console.log(e); - response - .setStatusCode(500) - .appendHeader('Content-Type', 'application/json') - .setBody({ err: e }); - }); - await client.destroy(); - return callback(null, response); + .setBody({ err: "This buzzer is not registered properly" }); + } else { + if (buzzer) { + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ + buzzer, + door, + fallbackNumbers: config.Item.fallbackNumbers.SS, + }); + } else { + await client.send(ddb.getLockStatusCommand(door)) + .then(async (lock) => { + const status = ddb.isLockOpen(lock) ? "OPEN": "CLOSED"; + + response + .setStatusCode(200) + .appendHeader('Content-Type', 'application/json') + .setBody({ id: door, timeout: config.Item.timeout.N, status, buzzerCode: config.Item.buzzerCode.S }); + + }).catch((e) => { + console.log(e); + response + .setStatusCode(500) + .appendHeader('Content-Type', 'application/json') + .setBody({ err: e }); + }); + } + } + } + await client.destroy(); + return callback(null, response); }; \ No newline at end of file diff --git a/packages/serverless/functions/common/ddb.private.js b/packages/serverless/functions/common/ddb.private.js index 8cf8fe6..62bf239 100644 --- a/packages/serverless/functions/common/ddb.private.js +++ b/packages/serverless/functions/common/ddb.private.js @@ -24,6 +24,34 @@ exports.getLockStatusCommand = (door) => { }); }; +exports.getDoorAliasCommand = (buzzerNumber) => { + return new GetItemCommand({ + TableName: "doorman", + Key: { + "PK": { + S: buzzerNumber, + }, + "SK": { + S: "alias", + } + }, + }); +}; + +exports.getDoorConfigCommand = (door) => { + return new GetItemCommand({ + TableName: "doorman", + Key: { + "PK": { + S: `door-${door}`, + }, + "SK": { + S: "config", + }, + }, + }); +}; + exports.isLockOpen = (lock) => { // ttl is a UTC ms time for how long it is unlocked const ttl = lock.Item?.TTL?.N || 0;