Skip to content

Commit

Permalink
Merge pull request #12 from lacchain/chain-of-trust-manager
Browse files Browse the repository at this point in the history
Chain of trust manager, closes #1
  • Loading branch information
eum602 authored Jun 1, 2023
2 parents 035ab15 + e61a617 commit 283e6d7
Show file tree
Hide file tree
Showing 17 changed files with 395 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ EMAIL_TRANSPORTER = AWS


# EXTERNAL SERVICES
# IS_DEPENDENT_SERVICE = true # uncomment this only if the service communicates with the other components by way of external services
# IS_COT_DEPENDENT_SERVICE = true # uncomment this only if the service communicates with the other components by way of external services
IDENTITY_MANAGER_BASE_URL = http://laccpass-identity-manager/api/v1
DID_WEB_LAC = /did-web-lac
DID_WEB_LAC_CONTROLLER= /did-web-lac/controller
Expand Down
73 changes: 73 additions & 0 deletions .example.env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#PORT

PORT = 80 # use port 80 when running with docker
EXPOSED_CONTAINER_SERVER_PORT = 3002

#DOCS

DOCS_ENABLED = true

#TYPEORM

TYPEORM_TYPE = postgres
TYPEORM_HOST = localhost
TYPEORM_USERNAME = postgres
TYPEORM_PASSWORD = postgres
TYPEORM_DATABASE = laccpass_chain_of_trust_development
TYPEORM_PORT = 5432
TYPEORM_SYNCHRONIZE = false
TYPEORM_LOGGING = true
TYPEORM_MIGRATIONS_RUN = true
EXPOSED_CONTAINER_TYPEORM_PORT = 5434

#REDIS

REDIS_HOST = redis
REDIS_PORT = 6379
REDIS_PASSWORD = redis
EXPOSED_CONTAINER_REDIS_PORT = 6381

#TOKEN

JWT_SECRET = some-secret-string
ACCESS_TOKEN_LIFE = 360000000

#RATE LIMIT

RATE_LIMIT_WINDOW = 5
RATE_LIMIT_MAX_REQUESTS = 100

#AWS

AWS_ID=<ID>
AWS_SECRET=<SECRET>
AWS_REGION=<REGION>
AWS_S3_BUCKETNAME=api-express-test
AWS_SES_API_VERSION=<VERSION>


#SENDGRID
SENDGRID_API_USER=<USER>
SENDGRID_API_KEY=<API-KEY>

#Email
EMAIL_TRANSPORTER = AWS


# EXTERNAL SERVICES
# IS_COT_DEPENDENT_SERVICE = true # uncomment this only if the service communicates with the other components by way of external services
IDENTITY_MANAGER_BASE_URL = http://laccpass-identity-manager/api/v1
DID_LAC1 = /did/lac1


# Did Registry
CHAIN_ID = 0x9e55c
# DID_REGISTRY_ADDRESS = 0x00f23cda3cbec27ae630894dd84e88033676d136 # optional address, just in case you are willing to use another did registry
# DOMAIN_NAME = lacchain.id # optional param just in case you are willing to use another domain name

# Blockchain Connection
# for open protestnet: 'http://35.185.112.219'
# for mainnet: TBD
NODE_RPC_URL = http://35.185.112.219
#Node Address depends on the lacchain node you are connecting with
NODE_ADDRESS = 0xad730de8c4bfc3d845f7ce851bcf2ea17c049585
5 changes: 3 additions & 2 deletions ormconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
TYPEORM_MIGRATIONS_RUN,
PRODUCTION_ENV,
TYPEORM_TYPE,
IS_DEPENDENT_SERVICE,
IS_COT_DEPENDENT_SERVICE,
log4TSProvider
} from '@config';

// TODO: import Secp256k1Entity from key-manager
import { DidEntity, Secp256k1Entity } from 'lacpass-identity';

const log = log4TSProvider.getLogger('ormConfig');
Expand Down Expand Up @@ -44,7 +45,7 @@ const config: ConnectionOptions = {
}
};

if (IS_DEPENDENT_SERVICE !== 'true') {
if (IS_COT_DEPENDENT_SERVICE !== 'true') {
log.info('Importing entities from external components');
config.entities?.push(DidEntity);
config.entities?.push(Secp256k1Entity);
Expand Down
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"name": "laccpass-chain-of-trust",
"version": "0.0.1",
"name": "lacpass-chain-of-trust",
"version": "0.0.7",
"description": "Rest api for laccpass Chain Of Trust built on top of Lacchain",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"/dist"
],
"license": "MIT",
"scripts": {
"dev": "yarn && nodemon --watch 'src/**/*.ts' --exec 'ENV=dev ts-node -r tsconfig-paths/register' src/server.ts",
Expand Down Expand Up @@ -78,7 +83,7 @@
"express-rate-limit": "^6.3.0",
"helmet": "^5.0.2",
"jsonwebtoken": "^9.0.0",
"lacpass-identity": "^0.0.10",
"lacpass-identity": "^0.0.20",
"morgan": "^1.10.0",
"multer": "^1.4.4",
"nodemailer": "^6.7.3",
Expand Down
10 changes: 5 additions & 5 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { randomUUID } from 'crypto';
import { config } from 'dotenv';
import { LogLevel } from 'typescript-logging';
import { Log4TSProvider } from 'typescript-logging-log4ts-style';

config({ path: `.env.${process.env.ENV || 'dev'}` });

export const log4TSProvider = Log4TSProvider.createProvider(
'Log4ProviderChainOfTrust',
'Log4ProviderChainOfTrust' + randomUUID(),
{
level: LogLevel.Debug,
groups: [
Expand Down Expand Up @@ -55,9 +56,8 @@ export const {
DOCS_ENABLED,
SENDGRID_API_USER,
SENDGRID_API_KEY,
IS_DEPENDENT_SERVICE,
IS_COT_DEPENDENT_SERVICE,
IDENTITY_MANAGER_BASE_URL,
DID_WEB_LAC,
DID_WEB_LAC_CONTROLLER,
DID_WEB_LAC_DECODE_DID
DID_LAC1,
DID_LAC1_ADD_NEW_ETHEREUM_ACCOUNT_ATTRIBUTE
} = process.env;
8 changes: 7 additions & 1 deletion src/constants/errorMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ export enum ErrorsMessages {
CREATE_DID_ERROR = 'An internal server error occurred while trying to create a new did',
GET_DID_CONTROLLER_ERROR = 'Error while trying to get did controller',
DECODE_DID_CONTROLLER_ERROR = 'Error while decoding did',
ADD_ATTRIBUTE_ERROR = 'Error while associating attribute to did'
ADD_ATTRIBUTE_ERROR = 'Error while associating attribute to did',
// eslint-disable-next-line max-len
CREATE_NEW_DELEGATE_ERROR = 'An error occurred while trying to create a new delagate',

// eslint-disable-next-line max-len
MANAGER_ALREADY_EXISTIS = 'A manager already exists for the entity Did, please remove it before creating a new one',
MANAGER_DOES_NOT_EXIST = 'A manager does not exist for the Entity Did passed in'
}

export const Errors = {
Expand Down
5 changes: 4 additions & 1 deletion src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export const controllers = [];
import { DidLac1Controller } from './lac1/did.controller';
import { ManagerController } from './lac1/manager.controller';

export const controllers = [DidLac1Controller, ManagerController];
21 changes: 21 additions & 0 deletions src/controllers/lac1/did.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JsonController, Post, BadRequestError } from 'routing-controllers';
import { Service } from 'typedi';
import { ErrorsMessages } from '@constants/errorMessages';
import { DidServiceLac1 } from '@services/external/did-lac/did.service';

@JsonController('/did/lac1')
@Service()
export class DidLac1Controller {
constructor(private readonly didServiceLac1: DidServiceLac1) {}

@Post()
async createDidLac1(): Promise<any> {
try {
return this.didServiceLac1.createDid();
} catch (error: any) {
throw new BadRequestError(
error.detail ?? error.message ?? ErrorsMessages.INTERNAL_SERVER_ERROR
);
}
}
}
43 changes: 43 additions & 0 deletions src/controllers/lac1/manager.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
JsonController,
Post,
BadRequestError,
Body,
Get,
Param
} from 'routing-controllers';
import { Service } from 'typedi';
import { ErrorsMessages } from '../../constants/errorMessages';
import { ManagerService } from '../../services/manager';
import { IManager } from 'src/interfaces/manager/manager';
import { NewManagerDto } from '../../dto/lac1/managerDTO';

@JsonController('/manager')
@Service()
export class ManagerController {
constructor(private readonly managerService: ManagerService) {}

@Post()
async createManager(
@Body({ validate: true }) newManager: NewManagerDto
): Promise<any> {
try {
return this.managerService.createManager(newManager);
} catch (error: any) {
throw new BadRequestError(
error.detail ?? error.message ?? ErrorsMessages.INTERNAL_SERVER_ERROR
);
}
}

@Get('/:entityDid')
async getManager(@Param('entityDid') entityDid: string): Promise<IManager> {
try {
return this.managerService.getManager(entityDid);
} catch (error: any) {
throw new BadRequestError(
error.detail ?? error.message ?? ErrorsMessages.INTERNAL_SERVER_ERROR
);
}
}
}
8 changes: 8 additions & 0 deletions src/dto/lac1/managerDTO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IsNumber, IsString } from 'class-validator';

export class NewManagerDto {
@IsString()
did!: string;
@IsNumber()
validDays!: number;
}
11 changes: 11 additions & 0 deletions src/entities/manager.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Column, Entity } from 'typeorm';
import { Base } from './base.entity';
@Entity()
export class Manager extends Base {
@Column({ unique: true })
entityDid!: string;
@Column()
managerDid!: string;
@Column()
managerAddress!: string;
}
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './interfaces/manager/manager';
export { INewAccountIdAttribute, DidEntity } from 'lacpass-identity';
export { ManagerService } from './services/manager';
export { ErrorsMessages } from './constants/errorMessages';
export * from './dto/lac1/managerDTO';
export { Manager as ManagerEntity } from './entities/manager.entity';
17 changes: 17 additions & 0 deletions src/interfaces/manager/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface IManagerService {
createManager(managerRequest: INewManager): Promise<IManager>;
getManager(entityDid: string): Promise<IManager>;
renewManagerAuthorization(): Promise<any>;
removeManager(entityDid: string): Promise<any>;
}

export interface INewManager {
did: string;
validDays: number;
}

export interface IManager {
entityDid: string;
managerDid: string;
managerAddress: string;
}
98 changes: 98 additions & 0 deletions src/services/external/did-lac/did.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
DID_LAC1,
IDENTITY_MANAGER_BASE_URL,
IS_COT_DEPENDENT_SERVICE,
log4TSProvider,
DID_LAC1_ADD_NEW_ETHEREUM_ACCOUNT_ATTRIBUTE
} from '../../../config';
import { ErrorsMessages } from '../../../constants/errorMessages';
import {
DidLacService,
DidType,
INewAccountIdAttribute,
INewDelegateResponse
} from 'lacpass-identity';
import { InternalServerError } from 'routing-controllers';
import { Service } from 'typedi';
import fetch from 'node-fetch';

@Service()
export class DidServiceLac1 {
public createDid: () => Promise<DidType>;
public addNewEthereumAccountIdAttribute: (
newAccountIdAttribute: INewAccountIdAttribute
) => Promise<INewDelegateResponse>;
log = log4TSProvider.getLogger('IdentityManagerService');

private didService: DidLacService | null;

constructor() {
if (IS_COT_DEPENDENT_SERVICE !== 'true') {
this.log.info('Configuring library usage');
this.createDid = this.createDidByLib;
this.addNewEthereumAccountIdAttribute =
this.addNewEthereumAccountIdAttributeByLib;

// setting imported did service
const S = require('lacpass-identity').DidLac1Service;
this.didService = new S();
} else {
this.log.info('Configuring external service connection');
this.addNewEthereumAccountIdAttribute =
this.addNewEthereumAccountIdAttributeByExternalService;
this.createDid = this.createDidByExternalService;

// setting did service to null since connections will be made by way
// of http connections rather than using imported libraries
this.didService = null;
}
}

private async createDidByLib(): Promise<DidType> {
return (await this.didService?.createDid()) as DidType;
}

private async createDidByExternalService(): Promise<DidType> {
const result = await fetch(`${IDENTITY_MANAGER_BASE_URL}${DID_LAC1}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
console.log('status', result.status);
if (result.status !== 200) {
console.log(await result.text());
throw new InternalServerError(ErrorsMessages.CREATE_DID_ERROR);
}
return (await result.json()) as DidType;
}

private async addNewEthereumAccountIdAttributeByLib(
newAccountIdAttribute: INewAccountIdAttribute
): Promise<INewDelegateResponse> {
return (await this.didService?.addNewEthereumAccountIdAttribute(
newAccountIdAttribute
)) as INewDelegateResponse;
}

private async addNewEthereumAccountIdAttributeByExternalService(
newAccountIdAttribute: INewAccountIdAttribute
): Promise<INewDelegateResponse> {
const result = await fetch(
`${IDENTITY_MANAGER_BASE_URL}${DID_LAC1_ADD_NEW_ETHEREUM_ACCOUNT_ATTRIBUTE}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newAccountIdAttribute)
}
);
console.log('status', result.status);
if (result.status !== 200) {
console.log(await result.text());
throw new InternalServerError(ErrorsMessages.CREATE_NEW_DELEGATE_ERROR);
}
return (await result.json()) as INewDelegateResponse;
}
}
Loading

0 comments on commit 283e6d7

Please sign in to comment.