Home

Awesome

Azure DevOps

Codacy Badge

codecov

IO mobile backend

This repository contains the code of the backend used by the mobile applications of the IO project.

Table of content


What is this?

This is the backend that supports the io-app mobile application.

This project is part of the Italian Digital Citizenship initiative, see the main repository for further information.

Authentication process

The io-app application will authenticate using the APIs exposed by the service Session Manager in IO Auth monorepo.

Once the token is obtained it can be used to call authenticated APIs of this repository.

Token authentication

All API requests sent by the client to the backend must have an Authorization: Bearer header with the value of the token obtained from the SPID authentication process. The token is used to retrieve the User object from the SessionStorage service.

The code that manage this flow are in the src/strategies/bearerSessionTokenStrategy.ts file.

How to run the application

Dependencies

A Linux/macOS environment is required at the moment.

Installation steps

  1. clone the project in a folder called io-backend

  2. go to the project's folder

  3. run scripts/build-tools.sh to build the tools Docker image

  4. run scripts/yarn.sh to install backend dependencies

  5. run scripts/generate-proxy-api-models.sh to generate the models defined in api_proxy.yaml and api_notifications.yaml

  6. run scripts/build.sh to compile the Typescript files

  7. run scripts/generate-test-certs.sh to create certificates needed to start the HTTPS server in DEV mode

  8. edit your /etc/hosts file by adding:

    127.0.0.1    io-backend
    
  9. copy .env.example to .env and fill the variables with your values

  10. run docker compose --env-file .env up -d to start the containers

  11. point your browser to https://io-backend/info to check that the server is started

If you are using Docker with a Docker Machine replace localhost with the IP of the Docker Machine (More details here).

Container description

Nginx is reachable at https://io-backend \

Environment variables

Those are all Environment variables needed by the application:

Variable nameDescriptiontype
API_KEYThe key used to authenticate to the io-functions-app APIstring
API_URLThe io-functions-app URLstring
API_BASE_PATHThe root path for the backend api endpointsstring
BONUS_API_KEYThe key used to authenticate to the io-functions-bonus APIstring
BONUS_API_URLThe io-functions-bonus URLstring
BONUS_API_BASE_PATHThe root path for the backend bonus api endpointsstring
CGN_API_KEYThe key used to authenticate to the io-functions-cgn APIstring
CGN_API_URLThe io-functions-cgn URLstring
CGN_API_BASE_PATHThe root path for the backend cgn api endpointsstring
PORTThe HTTP port the Express server is listening toint
REDIS_URLThe URL of a Redis instancestring
PRE_SHARED_KEYThe key shared with the API backend to authenticate the webhook notificationsstring
ALLOW_NOTIFY_IP_SOURCE_RANGEThe range in CIDR form of allowed IPs for the webhook notificationsstring
NOTIFICATIONS_STORAGE_CONNECTION_STRINGConnection string to Azure queue storage for notification hub messagesstring
NOTIFICATIONS_QUEUE_NAMEQueue name of Azure queue storage for notification hub messagesstring
ALLOW_MYPORTAL_IP_SOURCE_RANGEThe range in CIDR form of allowed IPs for the MyPortal APIstring
ALLOW_SESSION_HANDLER_IP_SOURCE_RANGEThe range in CIDR form of IPs of service allowed to handle user sessionsstring
AUTHENTICATION_BASE_PATHThe root path for the authentication endpointsstring
PAGOPA_API_URL_PRODThe url for the PagoPA api endpoints in prod modestring
PAGOPA_API_KEY_PRODThe api-key needed to call the pagopa proxy APIstring
PAGOPA_API_URL_TESTThe url for the PagoPA api endpoints in test modestring
PAGOPA_API_KEY_UATThe api-key needed to call the pagopa proxy API for UAT instancestring
MYPORTAL_BASE_PATHThe root path for the MyPortal endpointsstring
CACHE_MAX_AGE_SECONDSThe value in seconds for duration of in-memory api cacheint
APICACHE_DEBUGWhen is true enable the apicache debug modeboolean
GITHUB_TOKENThe value of your Github Api Key, used in build phasestring
FETCH_KEEPALIVE_ENABLEDWhen is true enables keepalive agent in the API client (defaults to false)boolean
FETCH_KEEPALIVE_MAX_SOCKETS(Optional) See agentkeepalive
FETCH_KEEPALIVE_FREE_SOCKET_TIMEOUT_MS(Optional) See agentkeepalive
FETCH_KEEPALIVE_KEEPALIVE_MSECS(Optional) See agentkeepalive
FETCH_KEEPALIVE_MAX_FREE_SOCKETS(Optional) See agentkeepalive
FETCH_KEEPALIVE_TIMEOUT(Optional) See agentkeepalive
FETCH_KEEPALIVE_SOCKET_ACTIVE_TTL(Optional) See agentkeepalive
FF_CGN_ENABLEDWhen is true (namely 1) enables CGN API to be registered into backend appboolean
FF_CGN_ENABLEDWhen is true (namely 1) enables CGN API to be registered into backend appboolean
APP_MESSAGES_API_KEYThe key used to authenticate to the io-functions-app-messages APIstring
APP_MESSAGES_API_URLThe io-functions-app-messages URLstring
THIRD_PARTY_CONFIG_LIST(Optional, default empty) A list of ThirdParty Configurationstringified JSON
IS_APPBACKENDLI(Optional, default false) Enables notify and session lock endpoints working only on appbackendliboolean
FF_PN_ACTIVATION_ENABLED(Optional) Enable the integration with PN for Service Activation (1 enabled)int
PN_ACTIVATION_BASE_PATH(Required if FF_PN_ACTIVATION_ENABLED = 1) base path for activation endpointstring
PN_API_KEY(Required if FF_PN_ACTIVATION_ENABLED = 1) PN API key for production environmentstring
PN_API_KEY_UAT(Required if FF_PN_ACTIVATION_ENABLED = 1) PN API key for UAT environmentstring
PN_API_URL(Required if FF_PN_ACTIVATION_ENABLED = 1) PN API base url for productionstring
PN_API_URL_UAT(Required if FF_PN_ACTIVATION_ENABLED = 1) PN API base url for UAT environmentstring
FF_IO_SIGN_ENABLEDWhen is true (namely 1) enables IO SIGN API to be registered into backend appboolean
IO_SIGN_API_BASE_PATHThe root path for the backend io-sign api endpointsstring
IO_SIGN_API_KEYThe key used to authenticate to the io-func-sign-user APIstring
IO_SIGN_API_URLThe io-func-sign-user URLstring
LOLLIPOP_API_KEYThe key used to authenticate to the io-function-lollipop APIstring
LOLLIPOP_API_URLThe io-function-lollipop URLstring
LOLLIPOP_API_BASE_PATHThe io-function-lollipop api base pathstring
LOLLIPOP_REVOKE_STORAGE_CONNECTION_STRINGConnection string to Azure queue storage for revoke Users lollipop PubKeysstring
LOLLIPOP_REVOKE_QUEUE_NAMEQueue name of Azure queue storage for revoke Users lollipop PubKeysstring
LOCKED_PROFILES_STORAGE_CONNECTION_STRINGConnection string to Azure queue storage for locked profiles tablestring
LOCKED_PROFILES_TABLE_NAMEThe locked profiles table namestring
FF_UNIQUE_EMAIL_ENFORCEMENT(Optional) Enable the unique email enforcement policy. Default: NONEstring (enum: NONE, BETA, ALL)
UNIQUE_EMAIL_ENFORCEMENT_USERS(Optional) Comma separated list of UNIQUE_EMAIL_ENFORCEMENT beta testers. Default: empty arraystring
SERVICES_APP_BACKEND_BASE_PATHNew Service APIs(include search engine) basepathstring
SERVICES_APP_BACKEND_API_URLServices App Backend FunctionApp Urlstring
SERVICES_APP_BACKEND_API_BASE_PATHServices App Backend FunctionApp Api Basepathstring
FF_TRIAL_SYSTEM_ENABLED(Optional) enables Trial System API to be registered into backend app - default falsestring
TRIAL_SYSTEM_API_BASE_PATHTrial System Api Base pathstring
TRIAL_SYSTEM_API_URLTrial System FunctionApp Api urlstring
TRIAL_SYSTEM_API_KEYThe key used to authenticate to the Trial System APIstring

Notes:

If you are trying to run the docker images on your local environment (through the docker-compose) you must set the following variables:

The connection string has a default value needed to connect to Azurite, a local emulator used to provide a free local environment for testing an Azure Blob, Queue Storage, and Table Storage application. As for docker-compose instructions, the Azurite docker image runs the Blob service on port 20003, the Queue service on port 20004 and the Table service on port 20005. If Azurite is executed on different address or ports, the connection string must be changed according to the service.

You must also set the following variables:

With the same values defined in the docker-compose.yml file.

Logs

Application logs are saved into the logs folder.


API Monitoring

Is possible link the API to AppInsignts service by setting the ENV variable APPINSIGHTS_INSTRUMENTATIONKEY. Stats of API CPU and RAM usage, API call execution time, success or failure of API calls are collected. Realtime data collection is enabled.

Redis Database

Data Structure

Redis Database stores data required only by application side functionalities. Below a table with an example of data for an hypothetical user with fiscal code MRARSS80A01H501T and with session token HexToken.

KeyValuetypeexpire in
SESSION-HexTokena JSON representing the user objectUserTOKEN_DURATION_IN_SECONDS
WALLET-WalletHexToken"SESSION-HexToken"StringTOKEN_DURATION_IN_SECONDS
SESSIONINFO-HexTokena JSON representing the SessionInfo objectSessionInfoTOKEN_DURATION_IN_SECONDS
USERSESSIONS-MRARSS80A01H501Ta Set of SessionInfo KeysSet<SessionInfoKey>never

Mobile App compatibility

Backend

To handle Backend compatibility with several Mobile App versions, the oldest mobile app version supported by the backend is stored into the property min_app_version inside the package.json. This value is provided to the app through the /info API. If the mobile app version is lower an upgrade is required.

PagoPa

To handle the mobile app compatibility with the latest implementation of PagoPA APIs, the backend exposes through the /info API a property called min_app_version_pagopa defined into package.json file. If the mobile app version is lower of this value, all the functions that require PagoPa are disabled to avoid compatibility issues.

How to contribute

Dependencies

A Linux/macOS environment is required at the moment.

Starting steps

In general follow the Node Best Practices.

Architecture decision records

In a world of evolutionary architecture, it's important to record certain design decisions for the benefit of future team members as well as for external oversight. Architecture Decision Records is a technique for capturing important architectural decisions along with their context and consequences. We store these details in source control, along with code, as then they can provide a record that remains in sync with the code itself.

We use ADRs to track architectural decisions of this initiative.

This repository is configured for Nat Pryce's adr-tools.

Here's the decisions we taken so far:

ADRTitlePR (discussion)
1Record architecture decisions
2Backend runs on Docker on local environments
3Use OpenAPI to defined the API specs
4Use a dependency injection container
5Use a GUID as Installation ID
6Backend is deployed on more than one instance

Troubleshooting

I installed on my mac but seems that https://io-backend is not working (ping io-backend return a host error)

Check out /etc/hosts Remember that in some cases you need to use your docker-machine ip (get it from >docker-machine ip) instead of localhost.

I followed all the steps but when i go to https://io-backend it shows me the same as https://io-backend:8080

This problem seems to be dependent on how Docker for Mac (doesn't) manage well the /etc/hosts file. If you install Docker Toolbox it works fine (and can coexist) (Read more at https://medium.com/@itseranga/set-hosts-in-docker-for-mac-2029276fd448)