Skip to content
Snippets Groups Projects
Commit a20aa27a authored by zdravko iliev's avatar zdravko iliev
Browse files

feat: add principal manager and infra repo into compose dir, fix docker images

parent 576d95f5
No related branches found
No related tags found
No related merge requests found
Showing
with 1117 additions and 65 deletions
......@@ -3,7 +3,23 @@
#### Dependencies
Node 12
Python 2.5.0 >= <3.0.0
pnpm
### Installation
### Setup local
1. pnpm install
2. pnpm prisma:generate
3. pnpm /app/:build
app options: attestation, connection, principal, ssi
### Docker compose
1. Go to compose dir
2. docker-compose up
## Example Flows (OCM Usage)
Please refer to [OCM-flow-overview](documentation/ocm-flow-overview.md)
yarn
FROM node:20-alpine3.16 AS builder
FROM node:16-slim AS builder
WORKDIR /usr/src/app
RUN yarn global add @nestjs/cli
RUN apt-get update
RUN apt-get install -y openssl
COPY package.json ./
COPY yarn.lock ./
WORKDIR /app
# --prod works if @types/node is in deps (not devDeps)
RUN yarn --frozen-lockfile --prod
RUN npm i -g pnpm
COPY . .
RUN yarn prisma:generate
RUN pnpm install
RUN pnpm -F attestation-manager prisma:generate
RUN yarn build
RUN pnpm -F attestation-manager build
FROM node:16-slim
RUN apt-get update
RUN apt-get install -y openssl
FROM node:14-alpine3.15
ENV PATH /usr/src/app/node_modules/.bin:$PATH
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/start.sh ./start.sh
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/src/prisma prisma
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/start.sh ./start.sh
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/src/prisma prisma
EXPOSE 3005
......
FROM node:14-alpine3.15
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json ./
COPY yarn.lock ./
COPY . .
RUN yarn
RUN yarn prisma:generate
EXPOSE 3005
CMD ["yarn", "start:docker"]
FROM node:16-alpine3.15 AS builder
FROM node:16-slim AS builder
WORKDIR /usr/src/app
RUN yarn global add @nestjs/cli
RUN apt-get update
RUN apt-get install -y openssl
COPY package.json ./
COPY yarn.lock ./
WORKDIR /app
# --prod works if @types/node is in deps (not devDeps)
RUN yarn --frozen-lockfile --prod
RUN npm i -g pnpm
COPY . .
RUN yarn prisma:generate
RUN pnpm install
RUN pnpm -F connection-manager prisma:generate
RUN yarn build
RUN pnpm -F connection-manager build
FROM node:16-slim
RUN apt-get update
RUN apt-get install -y openssl
FROM node:14-alpine3.15
ENV PATH /usr/src/app/node_modules/.bin:$PATH
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/start.sh ./start.sh
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/src/prisma prisma
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/start.sh ./start.sh
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/src/prisma prisma
EXPOSE 3003
RUN chmod +x ./start.sh
CMD ["./start.sh"]
CMD ["./start.sh"]
\ No newline at end of file
FROM node:16-alpine3.15
WORKDIR /usr/src/app
COPY . .
RUN pnpm install --frozen-lockfile
RUN pnpm -F connection-manager build
EXPOSE 3003
CMD ["pnpm", "-F", "connection-manager", "start:docker"]
Dockerfile
Jenkinsfile
coverage
docker-compose.yml
docs
node_modules
yarn-error.log
*.md
!README.md
.circle*
.codecov*
.coveralls*
.dockerignore
.drone*
.editorconfig
# .env
.git*
.huskyrc*
.lintstagedrc*
.npmignore
.prettierrc*
dist
\ No newline at end of file
PORT=3008
DATABASE_URL=postgresql://root:password@localhost:5432/postgres?schema=principal
ECSURL=http://localhost:9200/
CONNECTION_MANAGER_URL=http://3.111.77.38:3003
ATTESTATION_MANAGER_URL=http://3.111.77.38:3005
NATS_URL=nats://localhost:4222
USE_AUTH=false
OAUTH_CLIENT_ID=clientid
OAUTH_CLIENT_SECRET=clientsecret
OAUTH_TOKEN_URL=https://tokenurl
\ No newline at end of file
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'airbnb-base',
'airbnb-typescript/base',
],
parserOptions: {
project: './tsconfig.json',
},
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
{
"singleQuote": true,
"trailingComma": "all"
}
\ No newline at end of file
# GDPR Compliance Document
The objective of this document is to detail, the data being stored and proccessed by the Organization Credential Manager's, Principal Manger.
## What information is stored
### Source User Information
No personal data is accessed or processed
### Technical User Information (Public)
- Refrence id
## How is the information stored
The Technical User Information is encrypted using the Private Key of the Organizations SSI Agent and stored internally (on the agent) on PostgreSQL and externally/ metadata (shared between the OCM services) on PostgreSQL of Organization.
## Who can access the information
The Technical User Information both are accessible only by the Organization specific SSI agent's private key.
## How long will the information stay
The Technical User Information is wiped out according to the retention periods (not defined yet).
{
"openapi": "3.0.0",
"paths": {
"/v1/health": {
"get": {
"operationId": "HealthController_getHealth",
"parameters": [],
"responses": {
"200": {
"description": ""
}
}
}
},
"/v1/map-user-info": {
"post": {
"operationId": "PrincipalController_mapUserInfo",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MapUserInfoDTO"
}
}
}
},
"responses": {
"201": {
"description": ""
}
}
}
}
},
"info": {
"title": "XFSC Principal Manager API",
"description": "API documentation for XFSC Principal Manager",
"version": "1.0",
"contact": {}
},
"tags": [],
"servers": [{
"url": "http://localhost:3008/",
"description": "Localhost with docker configuration."
}
],
"components": {
"schemas": {
"MapUserInfoDTO": {
"type": "object",
"properties": {
"userInfoURL": {
"type": "string"
}
},
"required": [
"userInfoURL"
]
}
}
}
}
\ No newline at end of file
This diff is collapsed.
# OCM Principal Manager
## Description
<hr/>
The Principal Manager is the microservice responsible for handling the authentication and credential issuance for an individual PCM user.
## Usage
<hr/>
### Swagger Documentation:
[Swagger/OpenAPI](swagger.json)
## Installation
<hr/>
### Pre-requisite
* yarn
* docker
* docker-compose
* Postgres
### OCM Services Dependencies
* SSI Abstraction
## Running the app
<hr/>
**Each service in the Organizational Credential Manager can be run from the infrastructure repository with Docker.**
**The .env files are in the infrastructure repository under /env**
```bash
## production in:
./deployment/ci
## development in:
./deployment/dev
```
* (optional) Edit docker-compose.yml in "infrastructure" to use either **/ci/** or **/dev/** Dockerfiles.
* Run while in **"infrastructure"** project:
```bash
$ docker-compose up --build attestation-m
```
to run only Attestation Manager or
```bash
$ docker-compose up --build
```
to run all the services.
## Build
```
yarn build
```
## Run
```
yarn start
```
### Environment variable required
```
1. PORT
2. DATABASE_URL
3. ECSURL
4. NATS_URL
5. AGENT_URL
```
### Outgoing communication services
```
1. CONNECTION MANAGER
```
### Incoming communication services
```
1. ATTESTATION MANAGER
```
## Features supported
```
1. Issue Membership credential
```
## Test
```bash
# unit tests
$ yarn test
# e2e tests
$ yarn test:e2e
# test coverage
$ yarn test:cov
```
## GDPR
<hr/>
[GDPR](GDPR.md)
## Dependencies
<hr/>
[Dependencies](package.json)
## License
<hr/>
[Apache 2.0 license](LICENSE)
const config = () => ({
PORT: Number(process.env.PORT),
nats: {
url: process.env.NATS_URL,
},
auth: {
useAuth: process.env.USE_AUTH || 'false',
clientId: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
tokenUrl: process.env.OAUTH_TOKEN_URL,
},
DATABASE: {
type: 'postgres',
port: 5432,
synchronize: false,
logging: false,
entities: [`${__dirname}/../**/**.model{.ts,.js}`],
},
ECSURL: process.env.ECSURL,
});
export default config;
import * as Joi from 'joi';
const validationSchema = Joi.object({
DATABASE_URL: Joi.string().required(),
NATS_URL: Joi.string().required(),
PORT: Joi.number().required(),
USE_AUTH: Joi.string(),
OAUTH_CLIENT_ID: Joi.string(),
OAUTH_CLIENT_SECRET: Joi.string(),
OAUTH_TOKEN_URL: Joi.string(),
});
export default validationSchema;
FROM node:16-slim AS builder
RUN apt-get update
RUN apt-get install -y openssl
WORKDIR /app
RUN npm i -g pnpm
COPY . .
RUN pnpm install
RUN pnpm -F principal-manager prisma:generate
RUN pnpm -F principal-manager build
FROM node:16-slim
RUN apt-get update
RUN apt-get install -y openssl
ENV PATH /usr/src/app/node_modules/.bin:$PATH
WORKDIR /usr/src/app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/start.sh ./start.sh
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/src/prisma prisma
EXPOSE 3008
RUN chmod +x ./start.sh
CMD ["./start.sh"]
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}
{
"name": "principal-manager",
"version": "0.0.1",
"description": "",
"author": "Sagar",
"private": true,
"license": "Apache 2.0",
"scripts": {
"clean": "rm -r dist",
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"dbSchema": "npx prisma db push --schema=./src/prisma/schema.prisma",
"prisma:generate": "prisma generate --schema=./src/prisma/schema.prisma",
"prisma:migrate": "npx prisma migrate deploy --schema=./src/prisma/schema.prisma",
"prismaStudio": "npx prisma studio",
"start": "nest start",
"start:docker": "yarn prisma:migrate && yarn start",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@elastic/ecs-winston-format": "^1.3.1",
"@nestjs/axios": "^0.0.8",
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^1.1.6",
"@nestjs/core": "^8.0.0",
"@nestjs/mapped-types": "*",
"@nestjs/microservices": "^8.2.6",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/schedule": "^1.0.2",
"@nestjs/swagger": "^5.2.0",
"@nestjs/terminus": "^8.0.4",
"@prisma/client": "^3.9.2",
"@types/node": "^16.0.0",
"class-validator": "^0.13.2",
"express": "^4.17.3",
"joi": "^17.6.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^3.0.0",
"liquibase": "^4.4.0",
"moment": "^2.29.1",
"nats": "^2.6.0",
"openid-client": "^5.1.6",
"pg": "^8.7.3",
"prisma": "^3.9.2",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"swagger-ui-express": "^4.3.0",
"winston": "^3.6.0",
"winston-elasticsearch": "^0.16.1"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@types/express": "^4.17.13",
"@types/jest": "27.0.2",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"dotenv-cli": "^4.1.1",
"eslint": "^8.12.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"jest": "^27.2.5",
"prettier": "^2.3.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"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"setupFiles": [
"<rootDir>/../setup.js"
],
"coveragePathIgnorePatterns": [
"<rootDir>/main"
],
"moduleNameMapper": {
"@src/(.*)": [
"<rootDir>/$1"
],
"@client/(.*)": [
"<rootDir>/client/$1"
],
"@config/(.*)": [
"<rootDir>/../config/$1"
],
"@utils/*": [
"<rootDir>/utils/$1"
],
"@common/(.*)": [
"<rootDir>/common/$1"
],
"@principal/(.*)": [
"<rootDir>/principal/$1"
],
"@health/(.*)": [
"<rootDir>/health/$1"
],
"@DB/(.*)": [
"<rootDir>/prisma/$1"
]
}
}
}
process.env.PORT = 3000
\ No newline at end of file
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import AppModule from './app.module';
describe('App Module', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('should work', () => {
expect(true).toBe(true);
});
afterAll(async () => {
await app.close();
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment