From f0570a6101b23dd0b4b4301998132ad76e1b0e34 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Sat, 10 Apr 2021 07:26:42 -0500 Subject: [PATCH] Comment all the things and remove unnecessary files --- src/app/FirebaseResource.ts | 5 +++++ src/app/configs/app.config.ts | 9 +++++++++ src/app/configs/lang/common.config.ts | 5 ----- src/app/configs/lang/en_US.config.ts | 6 ------ src/app/configs/server.config.ts | 3 ++- .../controllers/api/Blockchain.controller.ts | 7 ++++--- .../http/middlewares/DebugOnly.middleware.ts | 20 +++++++++++++++++++ .../http/middlewares/LogRequest.middleware.ts | 12 ----------- .../api/FirebaseUserOnly.middleware.ts | 3 +++ ...ValidateEncounterTransaction.middleware.ts | 3 ++- src/app/http/routes/app.routes.ts | 1 + src/app/resources/views/welcome.pug | 5 ++--- src/app/rtdb/BlockResource.ts | 18 +++++++++++------ src/app/rtdb/TransactionResource.ts | 13 +++++++----- src/app/units/Blockchain.ts | 2 ++ src/app/units/rtdb/Transaction.ts | 19 +++++++++++++++++- 16 files changed, 88 insertions(+), 43 deletions(-) delete mode 100644 src/app/configs/lang/common.config.ts delete mode 100644 src/app/configs/lang/en_US.config.ts create mode 100644 src/app/http/middlewares/DebugOnly.middleware.ts delete mode 100644 src/app/http/middlewares/LogRequest.middleware.ts diff --git a/src/app/FirebaseResource.ts b/src/app/FirebaseResource.ts index 8253c3e..bc25ac3 100644 --- a/src/app/FirebaseResource.ts +++ b/src/app/FirebaseResource.ts @@ -12,10 +12,15 @@ export interface FirebaseResourceItem { seqID: number; } +/** + * An asynchronous iterable wrapper that enables us to use AsyncCollection + * to interact with the Firebase realtime database. + */ @Injectable() export class FirebaseResource extends Iterable { protected refName!: RTDBRef + /** Get the Reference for this resource. */ ref(): firebase.database.Reference { return Application.getApplication().make(FirebaseUnit).ref(this.refName) } diff --git a/src/app/configs/app.config.ts b/src/app/configs/app.config.ts index a332486..1254bf4 100644 --- a/src/app/configs/app.config.ts +++ b/src/app/configs/app.config.ts @@ -6,21 +6,30 @@ export default { gpg: { key: { + // Contents of the SERVER's GPG public key, armored. public: fs.readFileSync(env('GPG_KEY_PUB')).toString('utf-8'), + + // Contents of the SERVER's GPG private key, armored. private: fs.readFileSync(env('GPG_KEY_PRIV')).toString('utf-8'), }, }, firebase: { + // Contents of the Firebase service account credentials file. credentials: JSON.parse( fs.readFileSync(env('FIREBASE_CREDENTIALS')) .toString('utf-8') ), + // Name of the HTTP header to check for the firebase auth token api_auth_header: env('FIREBASE_API_AUTH_HEADER', 'X-Auth-Token'), rtdb: { + // URL of the realtime-database this app should use default: env('FIREBASE_DEFAULT_RTDB', 'https://loc-chain-default-rtdb.firebaseio.com'), + + // Mapping of ref-shortname to actual database reference + // If you add a value here, also add it to the RTDBRef type alias refs: { peers: 'chain/server/peers', transaction: 'chain/pending/transactions', diff --git a/src/app/configs/lang/common.config.ts b/src/app/configs/lang/common.config.ts deleted file mode 100644 index 972fea9..0000000 --- a/src/app/configs/lang/common.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { env } from "@extollo/lib" - -export default { - app_name: env('APP_NAME', 'Extollo'), -} diff --git a/src/app/configs/lang/en_US.config.ts b/src/app/configs/lang/en_US.config.ts deleted file mode 100644 index 5ab104c..0000000 --- a/src/app/configs/lang/en_US.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {env} from '@extollo/lib' - -export default { - welcome_to_extollo: 'Welcome to Extollo!', - viewed_page_num_times: 'You have viewed this page :num: times.', -} diff --git a/src/app/configs/server.config.ts b/src/app/configs/server.config.ts index 3226c0e..b76ed18 100644 --- a/src/app/configs/server.config.ts +++ b/src/app/configs/server.config.ts @@ -37,7 +37,8 @@ export default { middleware: { global: { - pre: ['LogRequest'], + pre: [], + post: [], }, }, } diff --git a/src/app/http/controllers/api/Blockchain.controller.ts b/src/app/http/controllers/api/Blockchain.controller.ts index f0dd1a0..f3918b6 100644 --- a/src/app/http/controllers/api/Blockchain.controller.ts +++ b/src/app/http/controllers/api/Blockchain.controller.ts @@ -1,5 +1,5 @@ import {Controller} from "@extollo/lib" -import {Inject, Injectable} from "@extollo/di" +import {Injectable} from "@extollo/di" import {TransactionResource, TransactionResourceItem} from "../../../rtdb/TransactionResource" import {one} from "@extollo/util" @@ -10,7 +10,9 @@ import {one} from "@extollo/util" */ @Injectable() export class Blockchain extends Controller { - + /** + * Post a new transaction to the blockchain. This is only intended for testing. + */ public async postTransaction() { const item: TransactionResourceItem = { firebaseID: '', @@ -25,5 +27,4 @@ export class Blockchain extends Controller { await ( this.make(TransactionResource)).push(item) return one(item) } - } diff --git a/src/app/http/middlewares/DebugOnly.middleware.ts b/src/app/http/middlewares/DebugOnly.middleware.ts new file mode 100644 index 0000000..1930f8f --- /dev/null +++ b/src/app/http/middlewares/DebugOnly.middleware.ts @@ -0,0 +1,20 @@ +import {Config, error, Middleware} from "@extollo/lib" +import {Inject, Injectable} from "@extollo/di" +import {HTTPStatus} from "@extollo/util" + +/** + * DebugOnly Middleware + * -------------------------------------------- + * Only allows the request to proceed if the app is in debug mode. + */ +@Injectable() +export class DebugOnly extends Middleware { + @Inject() + protected readonly config!: Config + + public async apply() { + if ( !this.config.get('server.debug', false) ) { + return error('Not found.', HTTPStatus.NOT_FOUND) + } + } +} diff --git a/src/app/http/middlewares/LogRequest.middleware.ts b/src/app/http/middlewares/LogRequest.middleware.ts deleted file mode 100644 index 0cdad15..0000000 --- a/src/app/http/middlewares/LogRequest.middleware.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {json, Logging, Middleware} from "@extollo/lib"; -import {Inject, Injectable} from "@extollo/di"; - -@Injectable() -export class LogRequest extends Middleware { - @Inject() - protected readonly logging!: Logging - - public async apply() { - this.logging.info(`Incoming request: ${this.request.method} @ ${this.request.path}`) - } -} diff --git a/src/app/http/middlewares/api/FirebaseUserOnly.middleware.ts b/src/app/http/middlewares/api/FirebaseUserOnly.middleware.ts index 4b08885..bd9299d 100644 --- a/src/app/http/middlewares/api/FirebaseUserOnly.middleware.ts +++ b/src/app/http/middlewares/api/FirebaseUserOnly.middleware.ts @@ -16,16 +16,19 @@ export class FirebaseUserOnly extends Middleware { @Inject() protected readonly config!: Config + /** Get the name of the API token header. */ get headerName(): string { return String(this.config.get('app.firebase.api_auth_header')) } + /** Get the API token from the request header. */ getAuthHeader(): string { const tokens = this.request.getHeader(this.headerName) if ( Array.isArray(tokens) ) return tokens[0] return String(tokens) } + /** Check if the request contains a valid Firebase API token. */ public async apply() { const token = this.getAuthHeader() diff --git a/src/app/http/middlewares/api/ValidateEncounterTransaction.middleware.ts b/src/app/http/middlewares/api/ValidateEncounterTransaction.middleware.ts index 1433f1d..874dce8 100644 --- a/src/app/http/middlewares/api/ValidateEncounterTransaction.middleware.ts +++ b/src/app/http/middlewares/api/ValidateEncounterTransaction.middleware.ts @@ -5,7 +5,8 @@ import {HTTPStatus} from "@extollo/util"; /** * ValidateEncounterTransaction Middleware * -------------------------------------------- - * Put some description here. + * Errors out the request if it is missing any fields required to create + * a new encounter transaction on the blockchain. */ @Injectable() export class ValidateEncounterTransaction extends Middleware { diff --git a/src/app/http/routes/app.routes.ts b/src/app/http/routes/app.routes.ts index 76f96b0..963a3c6 100644 --- a/src/app/http/routes/app.routes.ts +++ b/src/app/http/routes/app.routes.ts @@ -2,5 +2,6 @@ import {Route} from "@extollo/lib" Route.group('/api/v1', () => { Route.post('/encounter', 'api:Blockchain.postTransaction') + .pre('DebugOnly') .pre('api:ValidateEncounterTransaction') }) diff --git a/src/app/resources/views/welcome.pug b/src/app/resources/views/welcome.pug index 7649fb1..016ff6b 100644 --- a/src/app/resources/views/welcome.pug +++ b/src/app/resources/views/welcome.pug @@ -1,6 +1,5 @@ html head - title !{locale('app_name')} + title loc-chain body - h1 !{locale('welcome_to_extollo')} - h2 !{locale('viewed_page_num_times', { interp: { num: app_visits } })} + h1 Welcome to Loc-Chain diff --git a/src/app/rtdb/BlockResource.ts b/src/app/rtdb/BlockResource.ts index 2a087d4..94fd090 100644 --- a/src/app/rtdb/BlockResource.ts +++ b/src/app/rtdb/BlockResource.ts @@ -23,6 +23,7 @@ export interface BlockInfectionTransaction { /** Union type of all possible block transactions. */ export type BlockTransaction = BlockInfectionTransaction | BlockEncounterTransaction +/** Returns true if the item is a valid BlockEncounterTransaction. */ export function isBlockEncounterTransaction(what: any): what is BlockEncounterTransaction { return ( what @@ -32,6 +33,7 @@ export function isBlockEncounterTransaction(what: any): what is BlockEncounterTr ) } +/** Returns true if the item is a valid BlockInfectionTransaction. */ export function isBlockInfectionTransaction(what: any): what is BlockInfectionTransaction { return ( what @@ -40,6 +42,7 @@ export function isBlockInfectionTransaction(what: any): what is BlockInfectionTr ) } +/** Returns true if the item is a valid BlockTransaction. */ export function isBlockTransaction(what: any): what is BlockTransaction { return isBlockEncounterTransaction(what) || isBlockInfectionTransaction(what) } @@ -48,14 +51,17 @@ export function isBlockTransaction(what: any): what is BlockTransaction { * Interface representing a single block in the chain. */ export interface BlockResourceItem extends FirebaseResourceItem { - uuid: string; - transactions: BlockTransaction[]; - lastBlockHash: string; - lastBlockUUID: string; - proof: string; - timestamp: number; + uuid: string; // Globally unique ID + transactions: BlockTransaction[]; // Transactions validated by this block + lastBlockHash: string; // The combined sha256 hash of the previous block + lastBlockUUID: string; // the UUID of the previous block + proof: string; // the generated proof-of-work string + timestamp: number; // millisecond unix timestamp when this block was created } +/** + * A Firebase realtime database resource for blocks in the chain. + */ @Injectable() export class BlockResource extends FirebaseResource { public static collect(): AsyncCollection { diff --git a/src/app/rtdb/TransactionResource.ts b/src/app/rtdb/TransactionResource.ts index c4609b6..ddcee06 100644 --- a/src/app/rtdb/TransactionResource.ts +++ b/src/app/rtdb/TransactionResource.ts @@ -7,13 +7,16 @@ import {AsyncCollection} from "@extollo/util" * Interface representing a client-submitted encounter transaction. */ export interface TransactionResourceItem extends FirebaseResourceItem { - combinedHash: string; - timestamp: number; - encodedGPSLocation: string; - partnerPublicKey: string; - validationSignature: string; + combinedHash: string; // The salted and hashed combination of the client IDs + timestamp: number; // the unix-time in milliseconds when the interaction occurred + encodedGPSLocation: string; // Encoded GPS location data + partnerPublicKey: string; // The public key of the other client + validationSignature: string; // The transaction validation data } +/** + * A Firebase realtime-database resource for managing encounter transactions. + */ @Injectable() export class TransactionResource extends FirebaseResource { public static collect(): AsyncCollection { diff --git a/src/app/units/Blockchain.ts b/src/app/units/Blockchain.ts index a05160b..6eb8665 100644 --- a/src/app/units/Blockchain.ts +++ b/src/app/units/Blockchain.ts @@ -19,9 +19,11 @@ export class Block implements BlockResourceItem { lastBlockHash: string lastBlockUUID: string proof: string + get config(): Config { return Application.getApplication().make(Config) } + constructor(rec: BlockResourceItem) { this.firebaseID = rec.firebaseID this.seqID = rec.seqID diff --git a/src/app/units/rtdb/Transaction.ts b/src/app/units/rtdb/Transaction.ts index 5e9ec9e..a3ae171 100644 --- a/src/app/units/rtdb/Transaction.ts +++ b/src/app/units/rtdb/Transaction.ts @@ -8,10 +8,13 @@ import { Blockchain } from "../Blockchain" /** * Transaction Unit * --------------------------------------- - * Put some description here. + * This unit listens for transactions created on the realtime database. + * When new ones come through, it matches them up, validates them, and pushes + * them onto this server's blockchain. */ @Singleton() export class Transaction extends Unit { + /** True if currently processing transactions. */ private processing: boolean = false @Inject() @@ -23,6 +26,7 @@ export class Transaction extends Unit { @Inject() protected readonly logging!: Logging + /** Claim the right to process transactions. Returns true if the right was granted. */ claim() { if ( !this.processing ) { this.processing = true @@ -32,10 +36,17 @@ export class Transaction extends Unit { return false } + /** Release the right to claim transactions. */ release() { this.processing = false } + /** + * Given two transactions, determine whether the came from a valid interaction. + * That is, do the two transactions vouch for each-other cryptographically. + * @param transaction1 + * @param transaction2 + */ public async compareTransactions(transaction1: TransactionResourceItem, transaction2: TransactionResourceItem) { // verify signature const result1 = await openpgp.verify({ @@ -59,6 +70,9 @@ export class Transaction extends Unit { return (await result1.signatures[0].verified) && (await result2.signatures[0].verified) } + /** + * Subscribe to the transactions reference and wait for new transactions to be added. + */ public async up() { this.firebase.ref("transaction").on("child_added", async () => { this.logging.debug('Received child_added event for transactions reference.') @@ -110,6 +124,9 @@ export class Transaction extends Unit { }) } + /** + * Release listeners and resources before shutdown. + */ public async down() { // Release all subscriptions before shutdown this.firebase.ref("transaction").off()