add buzzer code field
All checks were successful
Build and push image for doorman / docker (push) Successful in 1m39s

This commit is contained in:
Martin Dimitrov 2024-07-06 19:22:50 -07:00
parent c1f068f5aa
commit 81699c7bf4
7 changed files with 99 additions and 39 deletions

View File

@ -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": {

View File

@ -19,11 +19,6 @@ const router = createBrowserRouter([
path: "",
loader: doorpageloader,
element: <DoorPage />
},
{
path: "door/:door",
loader: doorpageloader,
element: <DoorPage />,
}
]
}

View File

@ -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={() => <span>-</span>}
renderInput={(props) => <input readOnly {...props} />}

View File

@ -1,7 +1,5 @@
import { IAuthMode } from "./IAuthMode";
export interface IDoorResponse {
id: string,
authModes: IAuthMode[];
timeout: number;
}
buzzerCode: string;
};

View File

@ -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) => {

View File

@ -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,8 +17,39 @@ 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;
});
}
if (door) {
const config = await client.send(ddb.getDoorConfigCommand(door));
if (!config.Item) {
response
.setStatusCode(404)
.appendHeader('Content-Type', 'application/json')
.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";
@ -25,7 +57,7 @@ exports.handler = async function(context, event, callback) {
response
.setStatusCode(200)
.appendHeader('Content-Type', 'application/json')
.setBody({ id: door, timeout, status });
.setBody({ id: door, timeout: config.Item.timeout.N, status, buzzerCode: config.Item.buzzerCode.S });
}).catch((e) => {
console.log(e);
@ -34,6 +66,9 @@ exports.handler = async function(context, event, callback) {
.appendHeader('Content-Type', 'application/json')
.setBody({ err: e });
});
}
}
}
await client.destroy();
return callback(null, response);
};

View File

@ -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;