migrate auth route
This commit is contained in:
parent
ff2b5f9b9e
commit
50c4e9ae2c
@ -5,14 +5,14 @@
|
|||||||
import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types";
|
import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types";
|
||||||
import { TwilioContext } from "../../../types/TwilioContext";
|
import { TwilioContext } from "../../../types/TwilioContext";
|
||||||
import { UserAgentHeader } from "../../../utils/blockUserAgent";
|
import { UserAgentHeader } from "../../../utils/blockUserAgent";
|
||||||
import { clearLockStatusCommand, createDDBClient, ddbItemToJSON, getDoorConfigCommand, getLockStatusCommand, isLockOpen, setLockStatusCommand } from "../../../utils/ddb";
|
import { createDynaBridgeClient } from "../../../utils/ddb";
|
||||||
import { DoorConfig } from "../../../types/DoorConfig";
|
|
||||||
import { AuthMethod } from "../../../types/AuthMethod";
|
import { AuthMethod } from "../../../types/AuthMethod";
|
||||||
import { Lock } from "../../../types/Lock";
|
|
||||||
import { DoorStatus } from "../../../types/DoorStatus";
|
import { DoorStatus } from "../../../types/DoorStatus";
|
||||||
import { getMetricFromRegistry, withMetrics } from "../../../common/DoormanHandler";
|
import { getMetricFromRegistry, withMetrics } from "../../../common/DoormanHandler";
|
||||||
import { AuthMetrics, registerMetrics } from "../../../metrics/AuthMetrics";
|
import { AuthMetrics, registerMetrics } from "../../../metrics/AuthMetrics";
|
||||||
import { Counter } from "prom-client";
|
import { Counter } from "prom-client";
|
||||||
|
import { DoorConfig, getDoorConfigID } from "../../../schema/DoorConfig";
|
||||||
|
import { createLockStatusWithTimeout, getLockStatusID, isLockOpen } from "../../../schema/LockStatus";
|
||||||
|
|
||||||
export interface AuthRequest extends ServerlessEventObject<{}, UserAgentHeader> {
|
export interface AuthRequest extends ServerlessEventObject<{}, UserAgentHeader> {
|
||||||
door?: string;
|
door?: string;
|
||||||
@ -34,10 +34,9 @@ export const handler: ServerlessFunctionSignature<TwilioContext, AuthRequest> =
|
|||||||
return callback(null, response);
|
return callback(null, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
const client = createDDBClient(context);
|
const db = createDynaBridgeClient(context);
|
||||||
|
|
||||||
const ddbConfig = await client.send(getDoorConfigCommand(door));
|
const config: DoorConfig | undefined = await db.entities.doorConfig.findById(getDoorConfigID(door));
|
||||||
const config: DoorConfig = ddbItemToJSON<DoorConfig>(ddbConfig);
|
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
getMetricFromRegistry<Counter>(metricsRegistry, AuthMetrics.DOOR_CONFIG_NOT_FOUND).inc({ door }, 1);
|
getMetricFromRegistry<Counter>(metricsRegistry, AuthMetrics.DOOR_CONFIG_NOT_FOUND).inc({ door }, 1);
|
||||||
@ -76,41 +75,32 @@ export const handler: ServerlessFunctionSignature<TwilioContext, AuthRequest> =
|
|||||||
const timeout = event.timeout ? parseInt(event.timeout) : config.timeout;
|
const timeout = event.timeout ? parseInt(event.timeout) : config.timeout;
|
||||||
|
|
||||||
// check lock status if locked, then unlock. If unlocked then lock
|
// check lock status if locked, then unlock. If unlocked then lock
|
||||||
await client.send(getLockStatusCommand(door))
|
const lock = await db.entities.lockStatus.findById(getLockStatusID(door));
|
||||||
.then(async (lockDdb) => {
|
const isOpen = isLockOpen(lock);
|
||||||
const isOpen = isLockOpen(lockDdb);
|
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen && lock) {
|
||||||
const lock: Lock = ddbItemToJSON<Lock>(lockDdb);
|
const fingerprint = JSON.parse(lock.fingerprint);
|
||||||
const fingerprint = JSON.parse(lock.fingerprint);
|
|
||||||
|
|
||||||
response
|
response
|
||||||
.setStatusCode(200)
|
.setStatusCode(200)
|
||||||
.appendHeader('Content-Type', 'application/json')
|
.appendHeader('Content-Type', 'application/json')
|
||||||
.setBody({
|
.setBody({
|
||||||
status: DoorStatus.CLOSED,
|
status: DoorStatus.CLOSED,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.send(clearLockStatusCommand(lockDdb));
|
await db.entities.lockStatus.deleteById(getLockStatusID(door));
|
||||||
return;
|
} 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))
|
// destroy the internal client after
|
||||||
.then(async (item) => {
|
// @ts-ignore
|
||||||
response
|
db.ddbClient.destroy();
|
||||||
.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 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.destroy();
|
|
||||||
return callback(null, response);
|
return callback(null, response);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,14 +5,15 @@ export const LOCK_STATUS_SK = "lock";
|
|||||||
|
|
||||||
export const LockStatusSchema = z.object({
|
export const LockStatusSchema = z.object({
|
||||||
// keys
|
// keys
|
||||||
PK: z.string(), // phone number (buzzer number)
|
PK: z.string(), // door name
|
||||||
SK: z.literal(LOCK_STATUS_SK).default(LOCK_STATUS_SK),
|
SK: z.literal(LOCK_STATUS_SK).default(LOCK_STATUS_SK),
|
||||||
|
|
||||||
TTL: z.number(),
|
TTL: z.number(),
|
||||||
fingerprint: z.string(),
|
fingerprint: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getLockStatusID = (buzzer: string): string[] => {
|
export const getLockStatusID = (door: string): string[] => {
|
||||||
return [buzzer, LOCK_STATUS_SK];
|
return [door, LOCK_STATUS_SK];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LockStatus = z.infer<typeof LockStatusSchema>;
|
export type LockStatus = z.infer<typeof LockStatusSchema>;
|
||||||
@ -28,3 +29,12 @@ export const isLockOpen = (lock?: LockStatus) => {
|
|||||||
|
|
||||||
return parseInt("" + ttl) > Date.now();
|
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),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user