Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ut-port-swagger

softwaregroup-bg147Apache-2.04.5.0

UT Port Swagger

swagger

readme

UT Port Swagger

Configuration

{
  // UT specific configuration
  namespace: 'swagger',
  // static context
  /*
    static content that will be automatically served by the server.
    e.g. {
      status: ['pending', 'approved']
    }
    then the following route will be exposed:
    GET /context/status
    which will return the payload: ['pending', 'approved']
  */
  context: {},
  // json schema schemas.
  /*
    Should be a key-value object
    where the key is the name of the entity
    and the value is the schema itself.

    The context properties are tokenized and can be used
    within the schemas via interpolation.
    I.e.
    {
      ...
      "status": {
        "type": "string",
        "enum": "${status}",
        "title": "The status Schema "
      }
    }
  */
  schemas: {},
    // swagger document, path to swagger document or a function
    /*
    The context properties and the schemas are tokenized and can be used
    within the swagger document via interpolation.
    I.e.
    {
      ...
      "status": {
        "type": "string",
        "enum": "${context.status}",
        "title": "The status Schema "
      }
    }
    or
    {
      "definitions": {
        "someSchema": "${schemas.someSchema}"
      }
    }
    */
  document: null,
  // prefix for auto generated static routes. e.g: '/meta'
  // if set then static routes like /context/status for example will become /meta/context/status
  staticRoutesPrefix: '',
  // middleware options
  /*
    These below are the default options.
    In order to configure a certain middleware
    just provide the options for the respective key.
    In order to disable a certain middleware
    just provide false as its value.

    The middleware chain order is as follows:
    [
      'wrapper',
      'audit',
      'report',
      'swaggerUI',
      'cors',
      'conditionalGet',
      'etag',
      'formParser',
      'bodyParser',
      'auth',
      'basicAuth',
      'jwt',
      'router',
      'validator',
      'contextProvider',
      'requestHandler'
    ]

    Note: contextProvider is an explicit middleware
    and cannot be configured.
  */

  middleware: {
      wrapper: {},
      audit: false,
      report: false,
      swaggerUI: {
          pathRoot: '/docs',
          skipPaths: []
      },
      cors: {},
      conditionalGet: {},
      etag: {},
      formParser: false,
      bodyParser: {},
      basicAuth: false,
      jwt: false,
      router: {},
      auth: {},
      validator: {
          request: true,
          response: true
      },
      requestHandler: {}
  },
  // http server connection options
  // https://nodejs.org/api/net.html#net_server_listen_options_callback
  // {port, host, path, backlog, exclusive, readableAll, writableAll}
  server: {}
}

Middleware

wrapper

TO DO: wrapper middleware description

  • configuration options
    • formatError [ function ]: fn (error, ctx): give ability to developer to do what it wants

keep in mind that if error have meta property with property status (meta.status) it will remove meta property from the error and set status to return status code of http server

audit

This middleware is responsible for sending audit data events to a message queue (Rabbit MQ)

  • configuration options

    • namespace (required) [ string ] - Rabbit MQ producer port namespace
    • exchange (required) [ string ] - Rabbit MQ exchange
    • routingKey (required) [ string ] - Rabbit MQ routing key
    • format (optional) [ string | function ] - Payload formatter. By default it is the dw formatter.
    • options (optional) [ object ] - Rabbit MQ options. May include headers, type, appId, etc... see amqplib channel publish options

    For more info about options, exchange and routingKey check ut-port-amqp docs

    Example:

    {
      "swagger": {
        "middleware": {
          "audit": {
            "namespace": "audit",
            "exchange": "asdfasdf",
            "routingKey": "gfgfd",
            "options": {
              "headers": {
                "__TypeId__": "com.softwaregroup.audit.dto.AuditDto"
              }
            }
          }
        }
      }
    }

report

This middleware is responsible for sending reporting data events to a message queue (Rabbit MQ).

  • configuration options

    • namespace (required) [ string ] - Rabbit MQ producer port namespace
    • exchange (required) [ string ] - Rabbit MQ exchange
    • routingKey (required) [ string ] - Rabbit MQ routing key
    • format (optional) [ string | function ] - Payload formatter. By default it is the dw formatter.
    • options (optional) [ object ] - Rabbit MQ options. May include headers, type, appId, etc... see amqplib channel publish options

    For more info about options, exchange and routingKey check ut-port-amqp docs

    • service (required) [ string ] - mandatory field to be included in the payload
    • methods (optional) [ object | array ] - Which bus methods to be reported
      • if omitted then all methods will be reported
      • if an array of strings (each record representing a method name). Then the respective methods will be reported
      • if an object (each key representing a method name) Then the respective methods will be reported. The value can be used to override the reported objectId, eventType, objectType and data

    Examples:

    • Report all methods:
    {
      "swagger": {
        "middleware": {
          "report": {
            "namespace": "audit",
            "exchange": "exchange",
            "routingKey": "reporting",
            "service": "serviceName"
          }
        }
      }
    }
    • Report certain methods only
    {
      "swagger": {
        "middleware": {
          "report": {
            "namespace": "audit",
            "exchange": "exchange",
            "routingKey": "reporting",
            "service": "serviceName",
            "methods": [
              "a.b.c",
              "d.e.f"
            ]
          }
        }
      }
    }
    • Report certain methods with overrides
    {
      "swagger": {
        "middleware": {
          "report": {
            "namespace": "audit",
            "exchange": "exchange",
            "routingKey": "reporting",
            "service": "serviceName",
            "methods": {
              "a.b.c": {},
              "d.e.f": {
                "objectType": "test"
              },
              "g.h.i": {
                "objectType": "test",
                "eventType": "edit"
              },
              "j.k.l": {
                "objectId": "request.msg.id",
                "data": {
                  "idCustom": "request.msg.id"
                }
              }
            }
          }
        }
      }
    }

    NOTE: objectId and data object values can be in dot-prop format. Check docs. If set then the respective objectId will be automatically extracted. the dot-prop object is formed as follows: {request: {msg, $meta}, response}. So the possible paths would be:

    • request.msg.*
    • request.$meta.*
    • response.*

    If not set in dot-prop format or it represents a path that doesn't exist then the value itself will be set as a fallback.

    If provided, the data object will be merged with the request message. data properties are treated as defaults so if any keys match they will be overridden by the message.

swaggerUI

TO DO: swaggerUI middleware description

cors

TO DO: cors middleware description

conditionalGet

TO DO: conditionalGet middleware description

etag

TO DO: etag middleware description

formParser

TO DO: formParser middleware description

bodyParser

TO DO: bodyParser middleware description

basicAuth

For configuration options please check basic-auth

  • configuration options
    • identities (required) [ array | function ] -
      • if array: array of objects {name: 'username', pass: 'password'}
      • if function: function receives 1 argument, object: {name: 'username', pass: 'password'} so it can validate against this object
    • realm (optional) [ string ] - Response header text on wrong auth

jwt

This middleware lets you authenticate HTTP requests using JSON Web Tokens in your application.

If the token is not valid then an error will be thrown.

If the token gets successfully validated then the $meta.auth property will be populated with fields extracted from token's payload.

$meta.auth is represented by a normalized data structure no matter what identity provider had generated the token. This is achieved by the concept of formatters. Currently only keycloak format is supported but more formats can be added in the long term in case any need for that arises. The formatter is set via the format property (see the examples below). It should be either a string or a function. If a string then a predefined formatter will be used (an error will be thrown if no matching formatter is found). If a custom function is provided then it will be called with jwt's body for each incoming HTTP request. The standard $meta.auth content format is:

{
    // user's session id (null if no info)
    sessionId: 'sessionId',
    // user's business unit id (null if no info)
    businessUnitId: 'businessUnitId',
    // user's business unit name(null if no info)
    businessUnitName: 'businessUnitName',
    // user's tenant id (null if no info)
    tenantId: 'tenantId',
    // user's tenant name (null if no info)
    tenantName: 'tenantName',
    // user's id (null if no info)
    userId: 'userId',
    // user's username (null if no info)
    username: 'username',
    // user's full name (null if no info)
    name: 'name',
    // user's roles (empty array if no info)
    roles: ['role1', 'role2']
}

configuration examples

Using a symmetric key:

  {
    "swagger": {
      "middleware": {
        "jwt": {
          "secret": "secret",
          "format": "keycloak"
        }
      }
    }
  }

The token is normally provided in a HTTP header (Authorization) but it can also be provided in a cookie. Specify that by setting the 'cookie' option. In the example below the middleware will expect the token to be found at Cookie: "ut5-cookie=encryptedJwtToken"

  {
    "swagger": {
      "middleware": {
        "jwt": {
            "cookie": "ut5-cookie",
            "secret": "ut5-secret",
            "format": "ut5"
        }
      }
    }
  }

You can specify audience and/or issuer as well:

  {
    "swagger": {
      "middleware": {
        "jwt": {
          "secret": "secret",
          "audience": "http://myapi/protected",
          "issuer": "http://issuer",
          "format": "keycloak"
        }
      }
    }
  }

You can also specify an array of secrets.

  {
    "swagger": {
      "middleware": {
        "jwt": {
          "secret": ["oldSecret", "newSecret"],
          "format": "keycloak"
        }
      }
    }
  }

The token will be considered valid if it validates successfully against any of the supplied secrets. This allows for rolling shared secrets.

This middleware also supports verification via public keys

  const publicKey = fs.readFileSync('/path/to/public.pub');
  return {
    swagger: {
      middleware: {
        jwt: {
          secret: publicKey,
          format: 'keycloak'
        }
      }
    }
  };

The secret option can also be a function. If the secret option is a function, this function is called for each JWT received in order to determine which secret is used to verify the JWT. The signature of this function should be (header, payload) => [Promise(secret)], where header is the token header and payload is the token payload.

JWKS (JSON Web Key Set) support is also provided. For example:

{
  "swagger": {
    "middleware": {
      "jwt": {
        "jwks": {
          "jwksUri": "http://host:port/auth/realms/Test/protocol/openid-connect/certs",
          "cache": true,
          "cacheMaxEntries": 5,
          "cacheMaxAge": 86400000
        },
        "audience": "some-audience",
        "issuer": "http://host:port/auth/realms/Test",
        "format": "keycloak"
      }
    }
  }
}

auth

This middleware can be used to switch on / off the authorization of the incoming http requests. if auth is explicitly set to false the authorization mechanisms will be disabled even if jwt or basicAuth middlewares are enabled.

router

TO DO: router middleware description

validator

TO DO: validator middleware description

contextProvider

TO DO: contextProvider middleware description

requestHandler

This middleware is responsible for dispatching the requests to the backend.

  • configuration options

    • authorize (optional) [ string | function ] - Authorization handler. The authorization would fail if the handler returns a falsy value or throws an error.
    • transformRequest (optional) [ function ] - Global request transformation handler.
    • transformResponse (optional) [ function ] - Global response transformation handler.
    • transformErrorResponse (optional) [ function ] - Global error response transformation handler.

    Examples:

    • Custom handler on port level (recommended):
      module.exports = (...params) => {
        return class swagger extends require('ut-port-swagger')(...params) {
          get defaults() {
            return {
              middleware: {
                requestHandler: {
                  authorize: function({message, $meta}) {
                    // apply authorization logic
                    // based on message and $meta
    
                    // successful authorization
                    return true;
    
                    // reject unauthorized
                    // return false;
    
                    // reject unauthorized with specific error
                    // throw new Error('xxx')
                  },
                  transformRequest: function(message, $meta) {
                    return message;
                  },
                  transformResponse: function(message, $meta) {
                    return message;
                  }
                }
              }
            }
          }
        }
      };
    • Custom handler in js config:
      {
        swagger: {
          middleware: {
            requestHandler: {
              authorize: function({message, $meta}) {
                // apply authorization logic
                // based on message and $meta
              }
            }
          }
        }
      }
    • Authorization via bus method:
      {
        "swagger": {
          "middleware": {
            "requestHandler": {
              "authorize": "custom.authorization.handler"
            }
          }
        }
      }

Headers

Request headers

Access the request headers from $meta.requestHeaders

Response headers

In order to set response headers just attach a responseHeaders object in $meta from the bus method that has been called. E.g

  function(incomingMessage, $meta) {
    $meta.responseHeaders = {
      'x-test': 'x-test response header value'
    };
    const outgoingMessage = {
      test: 1
    };
    return outgoingMessage;
  }

Cookies

In order to set response cookies just attach a cookies array in $meta from the bus method that has been called. E.g

  function(incomingMessage, $meta) {
    $meta.cookies = [
      ['cookie1Name', 'cookie1Value', {/*cookie 1 options*/}],
      ['cookie2Name', 'cookie2Value', {/*cookie 2 options*/}]
    ];
    const outgoingMessage = {
      test: 1
    };
    return outgoingMessage;
  }

For more information about how to describe cookies check koa documentation

OpenAPI Schema specifics

  • operationId - specifies the controller (the bus method which will be executed when the respective http route gets called)

JSON Schema custom keywords

  • x-occurrences - specifies that certain field should appear in a way compliant with the provided specification. Example:
 {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "personalData": {
        "type": "object",
        "properties": {
          "phones": {
            "type": "array",
            "x-occurrences": [
              {
                "key": "isPrimary",
                "value": true,
                "min": 1,
                "max": 1
              },
              {
                "key": "isMWallet",
                "value": true,
                "min": 0,
                "max": 1
              }
            ],
            "items": {
              "type": "object",
              "properties": {
                "mno": {
                  "type": "string",
                  "title": "The Mno Schema ",
                  "default": "",
                  "example": "A1"
                },
                "phoneType": {
                  "type": "string",
                  "title": "The phoneType Schema ",
                  "default": "",
                  "example": "home"
                },
                "phoneNumber": {
                  "type": "string",
                  "title": "The phoneNumber Schema ",
                  "default": "",
                  "example": "359787666555"
                },
                "isPrimary": {
                  "type": "boolean",
                  "title": "The isPrimary Schema ",
                  "default": false,
                  "example": true
                },
                "isMWallet": {
                  "type": "boolean",
                  "title": "The isMWallet Schema ",
                  "default": false,
                  "example": true
                }
              }
            }
      }
    }
  }

Known issues

Setting ut-port-swagger as a dependency will not work out of the box!!!

Temporary solution:

Explicitly set a dependency to swagger-ui-dist in your package.json

changelog

4.5.0 (2020-09-16)

Features

  • allow url strings in addition to url objects when instructing for serving static files (ceebe8f)
  • provide possibility to serve static files (b15688e)

4.4.1 (2020-04-21)

Bug Fixes

4.4.0 (2020-04-02)

Bug Fixes

Features

  • when auth in request handler returns, we check for .local, if any we put it in .local. this will help in pass some request specific data, like, what resource is allowed for this user (7db109d)

4.3.3 (2020-03-25)

4.3.2 (2020-03-23)

Bug Fixes

  • resolve jwt check only in case it is specified in route definition (1ac19a7)

4.3.1 (2020-02-20)

Bug Fixes

4.3.0 (2020-02-20)

Bug Fixes

Features

  • map/transform error responses (f9f89ba)

4.2.0 (2020-02-18)

Bug Fixes

Features

  • multi-factor authentication (3741b7a)

4.1.3 (2020-02-13)

Bug Fixes

4.1.2 (2020-02-12)

Bug Fixes

4.1.1 (2020-02-12)

Bug Fixes

4.1.0 (2020-02-11)

Bug Fixes

Features

4.0.0 (2020-02-10)

Bug Fixes

Features

  • global request/response transform handlers (78f5269)
  • BREAKING CHANGE: swagger-ui-dist (5db3af5)

BREAKING CHANGES

  • swagger-ui-dist
  • swagger-ui-dist

3.12.0 (2020-01-21)

Features

  • support multiple payloads when sending reporting/auditing messages (5adb28e)

3.11.0 (2019-12-20)

Features

  • add possibility to define additional reporting data (49968eb)

3.10.0 (2019-12-19)

Features

  • possibility to set response cookies (3231ad8)

3.9.0 (2019-12-02)

3.8.1 (2019-09-12)

Bug Fixes

  • use timestamp in milliseconds instead of unix epoch time (c95904e)

3.8.0 (2019-08-16)

Bug Fixes

  • get trace from request headers if present (5848f8b)
  • refactor dw format (45580ed)
  • tenantUUID->tenantId (48076e8)

Features

  • add possibility for custom audit and report formatters (a4b1fc3)

3.7.0 (2019-08-12)

Bug Fixes

Features

  • provide jwt ut5 formatter (38a76d6)

3.6.1 (2019-08-08)

Bug Fixes

  • update swagger validator (a2470da)

3.6.0 (2019-08-07)

Features

3.5.1 (2019-08-06)

Bug Fixes

  • resolve schema refs properly (d962189)

3.5.0 (2019-08-05)

Bug Fixes

Features

  • COREADM-132: interpolate ut-port-swagger schemas (b84886e)

3.4.0 (2019-08-01)

Features

3.3.1 (2019-07-24)

3.3.0 (2019-07-24)

Features

  • ALZDFA1-519: add user info in report message payload (c3e7dac)

3.2.1 (2019-07-15)

Bug Fixes

  • put back service in report middleware config (d75f146)

3.2.0 (2019-07-15)

Features

  • ALZDFA1-449: possibility to define public methods (58cf94f)

3.1.3 (2019-07-12)

Bug Fixes

  • remove report 'service' config property. Use implementation name as such (4d4710e)

3.1.2 (2019-07-12)

Bug Fixes

  • add sessionId to keycloak format and enrich audit object (bc3245e)

3.1.1 (2019-07-12)

Bug Fixes

  • extract status code from error if available (2866b50)

3.1.0 (2019-07-11)

3.0.0 (2019-06-24)

2.2.4 (2019-06-13)

Bug Fixes

2.2.3 (2019-06-05)

Bug Fixes

2.2.2 (2019-06-04)

Bug Fixes

  • add debug error info, fix schemas route payload (c15c1ef)

2.2.1 (2019-06-03)

Bug Fixes

  • fix hot reload. Don't override schema by reference (6ee9c33)

2.2.0 (2019-05-30)

Bug Fixes

Features

  • add conditional-get and etag middlewares (6fd3133)

2.1.1 (2019-05-17)

Bug Fixes

  • don't validate undefined primitives that are not required (5602479)

2.1.0 (2019-05-16)

Features

  • array payloads are now acceptd. They are put in message key called 'list' (676bcec)

2.0.2 (2019-05-15)

Bug Fixes

  • change naming from content to context (9978685)

2.0.1 (2019-05-14)

Bug Fixes

2.0.0 (2019-05-08)

1.5.0 (2019-01-31)

Features

  • add possibility to set response headers (dfc949b)

1.4.2 (2018-12-19)

Bug Fixes

  • make use of default values in json schemas (a89b8cf)

1.4.1 (2018-09-10)

Bug Fixes

  • more descriptive path errors (889a484)

1.4.0 (2018-08-15)

Features

  • allow additional processing of the swaggerDocument on imlpementation level (e7d2c9c)

1.3.3 (2018-08-06)

Bug Fixes

  • set swaggerDocument as an instance property in swagger port class (e44f5b9)

1.3.2 (2018-07-25)

Bug Fixes

  • edge cases and optimize code (bd9eb77)

1.3.1 (2018-07-20)

Bug Fixes

  • refactor middlewares to achieve path params validation (bf7f7c2)

1.3.0 (2018-07-18)

Features

  • add validator configuration, prepare jwt (5df86ba)

1.2.2 (2018-07-09)

Bug Fixes

  • pass request headers in (fbd02fb)

1.2.1 (2018-07-03)

Bug Fixes

  • Automatically set successful status code based on the swagger document definition. Improve error handling. (68ce222)

1.2.0 (2018-06-28)

Bug Fixes

  • add custom keyword (54ad23a)
  • add custom keyword x-occurances (f6b4c62)
  • add file upload support in custom validator (84f7506)
  • add metaschema for x-required and x-file. Improve x-occurrences. Remove x-required and x-file as they are used internally only. (1449487)
  • add minProperties equal to maxProperties so that the can be exactly 4 (0d9531c)
  • Ajv wrapping class (422b939)
  • custom required and file validations (c5f7968)
  • fix x-occurrences matching algorithm (30a3a6e)
  • fix x-occurrences validation bugs (f881e09)
  • improve x-occurrences validations. add custom messages (db288ce)
  • put validation handler into a separate function. create empty validator (ae5a6cc)
  • refactoring (3cdb52c)
  • refactoring plus wrapper middleware (a44bdc7)
  • use to support relationships between fields (440d7d2)
  • x-occurances min and max values. Add documentation. Rename to x-required and to x-file (ccb48cc)

Features

1.1.3 (2018-06-27)

Bug Fixes

1.1.2 (2018-06-09)

Bug Fixes

  • remove lodash.merge dependency (285b0d2)

1.1.1 (2018-06-08)

Bug Fixes

  • make swaggerDocument private (478916d)

1.1.0 (2018-06-08)

Features

  • add possibility to pass swaggerDocument (402c831)

1.0.0 (2018-06-06)

Features

  • reorganize config an add possibility to pass options per middleware (4f847d6)

BREAKING CHANGES

  • configuration options are different
  • this version is not compatible with previous versions

0.5.2 (2018-06-05)

Bug Fixes

0.5.1 (2018-06-05)

Bug Fixes

  • abstract koa router and request handlers into a common middleware called router (d15361d)

0.5.0 (2018-06-05)

Features

  • split validators and add file upload support for swagger 2 (34bf50e)

0.4.0 (2018-06-04)

Features

  • pass formData files to handlers (68af4bd)

0.3.0 (2018-06-01)

Bug Fixes

Features

  • use swagger2 instead of swagger2-koa (a88442f)

0.2.1 (2018-05-31)

Bug Fixes

  • use uuid module and fix port start log message (b2b30f7)

0.2.0 (2018-05-30)

Bug Fixes

Features

  • enable metrics and optimize code (f584d0c)