mirror of
https://github.com/hackku21/loc-chain-backend.git
synced 2024-10-27 20:34:03 +00:00
Comment all the things and remove unnecessary files
This commit is contained in:
parent
6ba038e4bf
commit
f0570a6101
@ -12,10 +12,15 @@ export interface FirebaseResourceItem {
|
|||||||
seqID: number;
|
seqID: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An asynchronous iterable wrapper that enables us to use AsyncCollection
|
||||||
|
* to interact with the Firebase realtime database.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FirebaseResource<T extends FirebaseResourceItem> extends Iterable<T> {
|
export class FirebaseResource<T extends FirebaseResourceItem> extends Iterable<T> {
|
||||||
protected refName!: RTDBRef
|
protected refName!: RTDBRef
|
||||||
|
|
||||||
|
/** Get the Reference for this resource. */
|
||||||
ref(): firebase.database.Reference {
|
ref(): firebase.database.Reference {
|
||||||
return Application.getApplication().make<FirebaseUnit>(FirebaseUnit).ref(this.refName)
|
return Application.getApplication().make<FirebaseUnit>(FirebaseUnit).ref(this.refName)
|
||||||
}
|
}
|
||||||
|
@ -6,21 +6,30 @@ export default {
|
|||||||
|
|
||||||
gpg: {
|
gpg: {
|
||||||
key: {
|
key: {
|
||||||
|
// Contents of the SERVER's GPG public key, armored.
|
||||||
public: fs.readFileSync(env('GPG_KEY_PUB')).toString('utf-8'),
|
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'),
|
private: fs.readFileSync(env('GPG_KEY_PRIV')).toString('utf-8'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
firebase: {
|
firebase: {
|
||||||
|
// Contents of the Firebase service account credentials file.
|
||||||
credentials: JSON.parse(
|
credentials: JSON.parse(
|
||||||
fs.readFileSync(env('FIREBASE_CREDENTIALS'))
|
fs.readFileSync(env('FIREBASE_CREDENTIALS'))
|
||||||
.toString('utf-8')
|
.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'),
|
api_auth_header: env('FIREBASE_API_AUTH_HEADER', 'X-Auth-Token'),
|
||||||
|
|
||||||
rtdb: {
|
rtdb: {
|
||||||
|
// URL of the realtime-database this app should use
|
||||||
default: env('FIREBASE_DEFAULT_RTDB', 'https://loc-chain-default-rtdb.firebaseio.com'),
|
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: {
|
refs: {
|
||||||
peers: 'chain/server/peers',
|
peers: 'chain/server/peers',
|
||||||
transaction: 'chain/pending/transactions',
|
transaction: 'chain/pending/transactions',
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import { env } from "@extollo/lib"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
app_name: env('APP_NAME', 'Extollo'),
|
|
||||||
}
|
|
@ -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.',
|
|
||||||
}
|
|
@ -37,7 +37,8 @@ export default {
|
|||||||
|
|
||||||
middleware: {
|
middleware: {
|
||||||
global: {
|
global: {
|
||||||
pre: ['LogRequest'],
|
pre: [],
|
||||||
|
post: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Controller} from "@extollo/lib"
|
import {Controller} from "@extollo/lib"
|
||||||
import {Inject, Injectable} from "@extollo/di"
|
import {Injectable} from "@extollo/di"
|
||||||
import {TransactionResource, TransactionResourceItem} from "../../../rtdb/TransactionResource"
|
import {TransactionResource, TransactionResourceItem} from "../../../rtdb/TransactionResource"
|
||||||
import {one} from "@extollo/util"
|
import {one} from "@extollo/util"
|
||||||
|
|
||||||
@ -10,7 +10,9 @@ import {one} from "@extollo/util"
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Blockchain extends Controller {
|
export class Blockchain extends Controller {
|
||||||
|
/**
|
||||||
|
* Post a new transaction to the blockchain. This is only intended for testing.
|
||||||
|
*/
|
||||||
public async postTransaction() {
|
public async postTransaction() {
|
||||||
const item: TransactionResourceItem = {
|
const item: TransactionResourceItem = {
|
||||||
firebaseID: '',
|
firebaseID: '',
|
||||||
@ -25,5 +27,4 @@ export class Blockchain extends Controller {
|
|||||||
await (<TransactionResource> this.make(TransactionResource)).push(item)
|
await (<TransactionResource> this.make(TransactionResource)).push(item)
|
||||||
return one(item)
|
return one(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
20
src/app/http/middlewares/DebugOnly.middleware.ts
Normal file
20
src/app/http/middlewares/DebugOnly.middleware.ts
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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}`)
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,16 +16,19 @@ export class FirebaseUserOnly extends Middleware {
|
|||||||
@Inject()
|
@Inject()
|
||||||
protected readonly config!: Config
|
protected readonly config!: Config
|
||||||
|
|
||||||
|
/** Get the name of the API token header. */
|
||||||
get headerName(): string {
|
get headerName(): string {
|
||||||
return String(this.config.get('app.firebase.api_auth_header'))
|
return String(this.config.get('app.firebase.api_auth_header'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the API token from the request header. */
|
||||||
getAuthHeader(): string {
|
getAuthHeader(): string {
|
||||||
const tokens = this.request.getHeader(this.headerName)
|
const tokens = this.request.getHeader(this.headerName)
|
||||||
if ( Array.isArray(tokens) ) return tokens[0]
|
if ( Array.isArray(tokens) ) return tokens[0]
|
||||||
return String(tokens)
|
return String(tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if the request contains a valid Firebase API token. */
|
||||||
public async apply() {
|
public async apply() {
|
||||||
const token = this.getAuthHeader()
|
const token = this.getAuthHeader()
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import {HTTPStatus} from "@extollo/util";
|
|||||||
/**
|
/**
|
||||||
* ValidateEncounterTransaction Middleware
|
* 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()
|
@Injectable()
|
||||||
export class ValidateEncounterTransaction extends Middleware {
|
export class ValidateEncounterTransaction extends Middleware {
|
||||||
|
@ -2,5 +2,6 @@ import {Route} from "@extollo/lib"
|
|||||||
|
|
||||||
Route.group('/api/v1', () => {
|
Route.group('/api/v1', () => {
|
||||||
Route.post('/encounter', 'api:Blockchain.postTransaction')
|
Route.post('/encounter', 'api:Blockchain.postTransaction')
|
||||||
|
.pre('DebugOnly')
|
||||||
.pre('api:ValidateEncounterTransaction')
|
.pre('api:ValidateEncounterTransaction')
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
html
|
html
|
||||||
head
|
head
|
||||||
title !{locale('app_name')}
|
title loc-chain
|
||||||
body
|
body
|
||||||
h1 !{locale('welcome_to_extollo')}
|
h1 Welcome to Loc-Chain
|
||||||
h2 !{locale('viewed_page_num_times', { interp: { num: app_visits } })}
|
|
||||||
|
@ -23,6 +23,7 @@ export interface BlockInfectionTransaction {
|
|||||||
/** Union type of all possible block transactions. */
|
/** Union type of all possible block transactions. */
|
||||||
export type BlockTransaction = BlockInfectionTransaction | BlockEncounterTransaction
|
export type BlockTransaction = BlockInfectionTransaction | BlockEncounterTransaction
|
||||||
|
|
||||||
|
/** Returns true if the item is a valid BlockEncounterTransaction. */
|
||||||
export function isBlockEncounterTransaction(what: any): what is BlockEncounterTransaction {
|
export function isBlockEncounterTransaction(what: any): what is BlockEncounterTransaction {
|
||||||
return (
|
return (
|
||||||
what
|
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 {
|
export function isBlockInfectionTransaction(what: any): what is BlockInfectionTransaction {
|
||||||
return (
|
return (
|
||||||
what
|
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 {
|
export function isBlockTransaction(what: any): what is BlockTransaction {
|
||||||
return isBlockEncounterTransaction(what) || isBlockInfectionTransaction(what)
|
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.
|
* Interface representing a single block in the chain.
|
||||||
*/
|
*/
|
||||||
export interface BlockResourceItem extends FirebaseResourceItem {
|
export interface BlockResourceItem extends FirebaseResourceItem {
|
||||||
uuid: string;
|
uuid: string; // Globally unique ID
|
||||||
transactions: BlockTransaction[];
|
transactions: BlockTransaction[]; // Transactions validated by this block
|
||||||
lastBlockHash: string;
|
lastBlockHash: string; // The combined sha256 hash of the previous block
|
||||||
lastBlockUUID: string;
|
lastBlockUUID: string; // the UUID of the previous block
|
||||||
proof: string;
|
proof: string; // the generated proof-of-work string
|
||||||
timestamp: number;
|
timestamp: number; // millisecond unix timestamp when this block was created
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Firebase realtime database resource for blocks in the chain.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BlockResource extends FirebaseResource<BlockResourceItem> {
|
export class BlockResource extends FirebaseResource<BlockResourceItem> {
|
||||||
public static collect(): AsyncCollection<BlockResourceItem> {
|
public static collect(): AsyncCollection<BlockResourceItem> {
|
||||||
|
@ -7,13 +7,16 @@ import {AsyncCollection} from "@extollo/util"
|
|||||||
* Interface representing a client-submitted encounter transaction.
|
* Interface representing a client-submitted encounter transaction.
|
||||||
*/
|
*/
|
||||||
export interface TransactionResourceItem extends FirebaseResourceItem {
|
export interface TransactionResourceItem extends FirebaseResourceItem {
|
||||||
combinedHash: string;
|
combinedHash: string; // The salted and hashed combination of the client IDs
|
||||||
timestamp: number;
|
timestamp: number; // the unix-time in milliseconds when the interaction occurred
|
||||||
encodedGPSLocation: string;
|
encodedGPSLocation: string; // Encoded GPS location data
|
||||||
partnerPublicKey: string;
|
partnerPublicKey: string; // The public key of the other client
|
||||||
validationSignature: string;
|
validationSignature: string; // The transaction validation data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Firebase realtime-database resource for managing encounter transactions.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TransactionResource extends FirebaseResource<TransactionResourceItem> {
|
export class TransactionResource extends FirebaseResource<TransactionResourceItem> {
|
||||||
public static collect(): AsyncCollection<TransactionResourceItem> {
|
public static collect(): AsyncCollection<TransactionResourceItem> {
|
||||||
|
@ -19,9 +19,11 @@ export class Block implements BlockResourceItem {
|
|||||||
lastBlockHash: string
|
lastBlockHash: string
|
||||||
lastBlockUUID: string
|
lastBlockUUID: string
|
||||||
proof: string
|
proof: string
|
||||||
|
|
||||||
get config(): Config {
|
get config(): Config {
|
||||||
return Application.getApplication().make(Config)
|
return Application.getApplication().make(Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(rec: BlockResourceItem) {
|
constructor(rec: BlockResourceItem) {
|
||||||
this.firebaseID = rec.firebaseID
|
this.firebaseID = rec.firebaseID
|
||||||
this.seqID = rec.seqID
|
this.seqID = rec.seqID
|
||||||
|
@ -8,10 +8,13 @@ import { Blockchain } from "../Blockchain"
|
|||||||
/**
|
/**
|
||||||
* Transaction Unit
|
* 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()
|
@Singleton()
|
||||||
export class Transaction extends Unit {
|
export class Transaction extends Unit {
|
||||||
|
/** True if currently processing transactions. */
|
||||||
private processing: boolean = false
|
private processing: boolean = false
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
@ -23,6 +26,7 @@ export class Transaction extends Unit {
|
|||||||
@Inject()
|
@Inject()
|
||||||
protected readonly logging!: Logging
|
protected readonly logging!: Logging
|
||||||
|
|
||||||
|
/** Claim the right to process transactions. Returns true if the right was granted. */
|
||||||
claim() {
|
claim() {
|
||||||
if ( !this.processing ) {
|
if ( !this.processing ) {
|
||||||
this.processing = true
|
this.processing = true
|
||||||
@ -32,10 +36,17 @@ export class Transaction extends Unit {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Release the right to claim transactions. */
|
||||||
release() {
|
release() {
|
||||||
this.processing = false
|
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) {
|
public async compareTransactions(transaction1: TransactionResourceItem, transaction2: TransactionResourceItem) {
|
||||||
// verify signature
|
// verify signature
|
||||||
const result1 = await openpgp.verify({
|
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)
|
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() {
|
public async up() {
|
||||||
this.firebase.ref("transaction").on("child_added", async () => {
|
this.firebase.ref("transaction").on("child_added", async () => {
|
||||||
this.logging.debug('Received child_added event for transactions reference.')
|
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() {
|
public async down() {
|
||||||
// Release all subscriptions before shutdown
|
// Release all subscriptions before shutdown
|
||||||
this.firebase.ref("transaction").off()
|
this.firebase.ref("transaction").off()
|
||||||
|
Loading…
Reference in New Issue
Block a user