Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

rsksmart/email-vc-issuer

Repository files navigation

logo

vc-issuer

Verifiable Credential issuer

alerts

Use this tool to issue Verifiable Credentials claming email and phone verifications.

Try it out at email-verifier.identity.rifos.org

Features

The backend enables email and phone verificatoins:

  • Email verificatoins - uses nodemailer
  • Phones verifications sending SMS - uses Twilo
  • Verifies digital signatures - uses ethereumjs-util
  • Issues Verifiable Credentials - uses did-jwt-vc
  • Saves the issued credentials in a database - uses typeorm and SQLite

The frontend is a simple app that serves as tool and code example:

Run for development

Development mode will allow you to run the tool without actual verifications. The verificatoin code will be logged and sent via Ethereal

Setup

  1. Install dependencies
npm i
npm run setup
  1. Configure the backend, create a .env file in './back' folder with
PRIVATE_KEY=ab12cd34... # a 32 bytes private key used to sign the verifiable credentials
  1. Configure the frontend. Change the endpoint in the .env file in ./front folder with
# REACT_APP_BACK_END_URL=https://email-verifier-backend.identity.rifos.org
REACT_APP_BACK_END_URL=http://localhost:5108

If you run the frontend from anopther port than 3000, please configure the new port in the whitelist

Run tests

npm test

Run the service

npm start

Run in watch mode

npm run start:dev

Branching model

  • main has latest release. Merge into main will deploy front-end to email-verifier.identity.rifos.org. Do merge commits.
  • develop has latest approved PR. PRs need to pass ci, LGTM and Sonar. Do squash & merge.
  • Use branches pointing to develop to add new PRs.
  • Do external PRs against latest commit in develop.

Run for production

You can optionally run any of the services. You will need to add some .env variables to activate the features. First add

NODE_ENV=production

Email verifications

SMTP_HOST=
SMTP_PORT=
SMTP_USER=
SMTP_PASS=

Phone verifications

TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_PHONE_NUMBER=

Optional config

LOG_FILE=./log/email-vc-issuer.log # relative path of the log file
LOG_ERROR_FILE=./log/email-vc-issuer.log # relative path of the error log file
NETWORK_NAME=rsk # rsk:testnet or rsk, for the issuer DID
PORT=5108 # port where the service will be served

Run the backend with Docker

Create the .env following the description above and run it

cd back/
docker-compose build
docker-compose up -d

It opens port 5108. Change it in the compose if you have changed it in the config file.

How it works

The tool will make the user digirally sign a verificatoin code that is sent via email/phone. This will proove that the user controls the asset and the wallet. The backend will verify this signature, sign a Verifiable Credentials and send it to the user. The user can then save to their Data Vault

Adding new verifiers

The service is built to make easy to add new verification services. You need to:

  1. Set up the Credential subject
    1. Create the new Schemas at @rsksmart/vc-json-schemas and @rsksmart/vc-json-schemas-parser
    2. Create a template function to create the new VC in ./back/src/vc.ts
  2. Set up the transport service
    1. Add the transport service configurations to ./back/src/config.ts
    2. Create a Sender class implementing sendVerificationCode function
  3. Prepare the instance of VCIssuer at setupServices in ./back/src/index.ts using the template, the Sender and a desired credentialType
  4. Backend all set! The API is no serverd at /${credentialType.toLowerCase()}/requestVerification and /${credentialType.toLowerCase()}/verify
  5. Now, to add the feature to the front, just add to front/src/App.tsx the credential type
    1. CredentialType indicating the API module name
    2. getKeyByCredentialType for the file key in the Data Vault

The best example is Twilo integration

import { Logger } from '@rsksmart/rif-node-utils/lib/logger'
import { Twilio } from 'twilio'
import { MessageInstance } from 'twilio/lib/rest/api/v2010/account/message'
import { Sender } from './sender'

export class SMSSender extends Sender<MessageInstance> {
  twilio: Twilio
  from: string

  constructor(twilio: Twilio, from: string, logger: Logger) {
    super(logger)
    this.twilio = twilio
    this.from = from
  }

  logSendResult = (result: MessageInstance): void => { this.logger.info(`SMS sent: ${result.sid}`) }
  sendVerificationCode = (to: string, text: string): Promise<any>  => this.twilio.messages.create({ from: this.from, to, body: text })
}