Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added hub-node-core-master.zip
Binary file not shown.
18 changes: 16 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,26 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@decentralized-identity/did-auth-jose": "^0.1.14",
"@decentralized-identity/did-common-typescript": "^0.1.19",
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"@types/multer": "^1.4.7",
"base64url": "^3.0.1",
"crypto": "^1.0.1",
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"typeorm": "^0.2.41"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/config": "^1.1.5",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@trust/keyto": "^1.0.1",
"@types/express": "^4.17.13",
"@types/jest": "^27.0.1",
"@types/node": "^16.0.0",
Expand All @@ -41,15 +50,20 @@
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"fs": "^0.0.2",
"jest": "^27.2.5",
"light-date": "^1.2.0",
"path": "^0.12.7",
"prettier": "^2.3.2",
"secp256k1": "^4.0.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.10.1",
"typescript": "^4.3.5"
"typescript": "^4.3.5",
"uuid": "^8.3.2"
},
"jest": {
"moduleFileExtensions": [
Expand Down
1 change: 1 addition & 0 deletions src/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ATTACH_SAVE_PATH=/static
27 changes: 21 additions & 6 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import { Controller, Get } from '@nestjs/common';
import { Controller, Post, Req, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { Request, Response } from 'express';
import { Express } from 'express';
import { UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
constructor(private readonly appService: AppService) { }

@Get()
getHello(): string {
return this.appService.getHello();
@Post('Collections')
async handleCollectionsRequest(@Req() req: Request, @Res() res: Response) {
console.log(req.data);
const result = await this.appService.handleRequest(Buffer.from(req.data));
if (result.ok) { res.status(200).send(result.body.toString()); }
else { res.status(400).send(result.body.toString()); }
}
}

@Post('Permissions')
async handlePermissionsRequest(@Req() req: Request, @Res() res: Response) {
console.log(req.data);
const result = await this.appService.handleRequest(Buffer.from(req.data));
if (result.ok) { res.status(200).send({data: result.body.toString()}); }
else { res.status(400).send({data: result.body.toString()}); }
}
}
7 changes: 5 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { hubProvider } from './hub.provider';
import { ConfigModule } from '@nestjs/config';
import { FileModule } from './file/file.module';

@Module({
imports: [],
imports: [ConfigModule.forRoot(), FileModule],
controllers: [AppController],
providers: [AppService],
providers: [AppService, ...hubProvider],
})
export class AppModule {}
10 changes: 7 additions & 3 deletions src/app.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Inject } from '@nestjs/common';
import Hub from './lib/Hub';

@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
constructor (@Inject('Hub') private readonly hub: Hub) {}

async handleRequest(request: Buffer): Promise<any> {
const response = await this.hub.handleRequest(request);
return response;
}
}
26 changes: 26 additions & 0 deletions src/file/file.controllers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Controller, Get, Post, Param, UseInterceptors, UploadedFile, Res, Query } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Response } from 'express';
import { ConfigService } from '@nestjs/config';

@Controller('file')
export class FileController {
constructor(private config: ConfigService) {}

@Post()
@UseInterceptors(FileInterceptor('file'))
create(@UploadedFile() file) {
const path = file.path.replace(this.config.get('ATTACH_SAVE_PATH'), '');
console.log(path.replace(/\\/gi, '/'));
return {
fileName: file.originalname,
savedPath: path.replace(/\\/gi, '/'),
size: file.size,
};
}

@Get(':path/:name')
async download(@Res() res: Response, @Param('path') path: string, @Param('name') name: string, @Query('fn') fileName) {
res.download(`${this.config.get('ATTACH_SAVE_PATH')}/${path}/${name}`, fileName);
}
}
41 changes: 41 additions & 0 deletions src/file/file.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Module } from '@nestjs/common';
import { FileController } from './file.controller';
import { MulterModule } from '@nestjs/platform-express';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { diskStorage } from 'multer';
import { format } from 'light-date';
import { extname } from 'path';

import * as fs from 'fs';

@Module({
imports: [
MulterModule.registerAsync({
imports: [ConfigModule],
useFactory: async (config: ConfigService) => ({
storage: diskStorage({
destination: function (req, file, cb) {
const dest = `${config.get('ATTACH_SAVE_PATH')}/`;

if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}

cb(null, dest);
},
filename: (req, file, cb) => {
const randomName = Array(32)
.fill(null)
.map(() => Math.round(Math.random() * 16).toString(16))
.join('');
return cb(null, `${randomName}${extname(file.originalname)}`);
},
}),
}),
inject: [ConfigService],
}),
],
controllers: [FileController],
})
export class FileModule {}
30 changes: 30 additions & 0 deletions src/hub.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { HttpResolver } from '@decentralized-identity/did-common-typescript';
import Hub from './lib/Hub';
import Store from './lib/interfaces/Store';
import Context from './lib/interfaces/Context';
import { Secp256k1CryptoSuite } from './lib/crypto/Secp256k1CryptoSuite';

export const hubProvider = [
{
provide: "HUB",
useFactory: async() => {
const keys = {"kid": "PUB_K1_6oKhayVuCEwiqeGN1PP4bpyh7Pbe3sqeWmaRyWs1wSA4NXWehb"};
const didServerURL = "http://146.56.161.150:8080";
const httpResolver = new HttpResolver(didServerURL);
const store = new Store();
await store.init(
"localhost",
"postgres",
5432,
"username",
"password",
"blockerDB"
);

const context = new Context(keys, [new Secp256k1CryptoSuite()], store, httpResolver);
const hub = new Hub(context);

return hub;
}
}
];
126 changes: 126 additions & 0 deletions src/lib/Hub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Authentication } from '@decentralized-identity/did-auth-jose';
import AuthorizationController from './controllers/AuthorizationController';
import Context from './interfaces/Context';
import BaseController from './controllers/BaseController';
import BaseRequest from './models/BaseRequest';
import BaseResponse from './models/BaseResponse';
import CommitContoller from './controllers/CommitController';
import CommitQueryController from './controllers/CommitQueryController';
import ObjectQueryController from './controllers/ObjectQueryController';
import PermissionAskController from './controllers/PermissionAskController';
import PermissionGrantController from './controllers/PermissionGrantController';
import PermissionQueryController from './controllers/PermissionQueryController';
import CommitQueryRequest from './models/CommitQueryRequest';
import CommitRequest from './models/CommitRequest';
import ObjectQueryRequest from './models/ObjectQueryRequest';
import PermissionQueryRequest from './models/PermissionQueryRequest';
import PermissionGrantRequest from './models/PermissionGrantRequest';

/**
* Core class that handles Hub requests.
* TODO: Formalize Hub error handling then remove all references to HTTP - Hub request handling should be completely independent of HTTP.
*/
export default class Hub {
private _controllers: {[name: string]: BaseController};
private _authentication: Authentication;
private _authorization: AuthorizationController;

public constructor(private context: Context) {
this._authentication = new Authentication({
resolver: this.context.resolver,
keys: this.context.keys,
cryptoSuites: this.context.cryptoSuites
});

this._authorization = new AuthorizationController(this.context);

this._controllers= {
Commit: new CommitContoller(this.context, this._authorization),
CommitQuery: new CommitQueryController(this.context, this._authorization),
ObjectQuery: new ObjectQueryController(this.context, this._authorization),
PermissionAsk: new PermissionAskController(this.context, this._authorization),
PermissionGrant: new PermissionGrantController(this.context, this._authorization),
PermissionQuery: new PermissionQueryController(this.context, this._authorization)
};
}
public async handleRequest(request: Buffer): Promise<any> {
let verifiedRequest;
try {
verifiedRequest = await this._authentication.getVerifiedRequest(request, false);
} catch (error) {
// TODO: Proper error logging with logger, for now logging to console.
console.log(error);
return {
ok: false,
body: Buffer.from(String(error)),
};
}

if (verifiedRequest instanceof Buffer) {
return {
ok: true,
body: verifiedRequest,
};
}
try {
let response: BaseResponse;
const requestType = BaseRequest.getTypeFromJson(verifiedRequest.request);
switch (requestType) {
case 'CommitQueryRequest':
const commitQueryRequest = new CommitQueryRequest(verifiedRequest.request);
const commitQueryController = this._controllers[requestType];
response = await commitQueryController.handleRequest(commitQueryRequest);
break;

case 'CommitRequest':
const commitRequest = new CommitRequest(verifiedRequest.request);
const CommitRequestController = this._controllers[requestType];
response = await commitQueryController.handleRequest(commitRequest);
break;

case 'ObjectQueryRequest':
const objectQueryRequest = new ObjectQueryRequest(verifiedRequest.request);
const objectQueryController = this._controllers[requestType];
response = await objectQueryController.handleRequest(objectQueryRequest);
break;

case 'PermissionAskRequest':
const permissionAskRequest = new PermissionQueryRequest(verifiedRequest.request);
const permissionAskController = this._controllers[requestType];
response = await permissionAskController.handleRequest(permissionAskRequest);
break;

case 'PermissionGrantRequest':
const permissionGrantRequest = new PermissionGrantRequest(verifiedRequest.request);
const permissionGrantController = this._controllers[requestType];
response = await permissionGrantController.handleRequest(permissionGrantRequest);
break;

case 'PermissionQueryRequest':
const permissionQueryRequest = new PermissionQueryRequest(verifiedRequest.request);
const permissionQueryController = this._controllers[requestType];
response = await permissionQueryController.handleRequest(permissionQueryRequest);
break;

default:
throw "Bad request type";
}

const responseBody = response.toString();
const responseBuffer = await this._authentication.getAuthenticatedResponse(verifiedRequest, responseBody);

console.log(responseBody);
return {
ok: true,
body: responseBuffer
};
}
catch(error) {
console.log(error);
return {
ok:false,
body: Buffer.from(String(error)),
}
}
}
}
39 changes: 39 additions & 0 deletions src/lib/controllers/AuthorizationController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

import BaseRequest from '../models/BaseRequest';
import WriteRequest from '../models/CommitRequest';
import CommitQueryRequest from '../models/CommitQueryRequest';
import ObjectQueryRequest from '../models/ObjectQueryRequest';
import ObjectQueryResponse from '../models/ObjectQueryResponse';
import Commit from '../models/Commit';
import Context from '../interfaces/Context';

export enum AuthorizationOperation {
Create = 'create',
Read = 'read',
Update = 'update',
Delete = 'delete',
}

export default class AuthorizationController {
constructor (private context: Context) {
}

async hasRegistered(profile: string): Promise<Boolean> {
const registered = await this.context.store.isRegistered(profile);
return registered;
}

async registerUser(profile: string, hub: string): Promise<Number> {
const registered = await this.context.store.isRegistered(profile);
if(!registered) {
const createdProfile = await this.context.store.postProfile(profile, hub);
return createdProfile;
}

return 0;
}

async hasPermissions(objectId: string, profile: string): Promise<Boolean> {
return this.context.store.getHasPermission(objectId, profile);
}
}
Loading