diff --git a/package-lock.json b/package-lock.json index 5d138afba9..50128f8dda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7923,9 +7923,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yallist": { diff --git a/sandbox/auth-multitenant-example/CHANGELOG.md b/sandbox/auth-multitenant-example/CHANGELOG.md index 1d4b38b698..3b6f59aea4 100644 --- a/sandbox/auth-multitenant-example/CHANGELOG.md +++ b/sandbox/auth-multitenant-example/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0-alpha.21](https://github.com/sourcefuse/loopback4-microservice-catalog/compare/@sourceloop/auth-multitenant-example@2.0.0-alpha.20...@sourceloop/auth-multitenant-example@2.0.0-alpha.21) (2021-03-31) + +**Note:** Version bump only for package @sourceloop/auth-multitenant-example + + + + + # [2.0.0-alpha.20](https://github.com/sourcefuse/loopback4-microservice-catalog/compare/@sourceloop/auth-multitenant-example@2.0.0-alpha.19...@sourceloop/auth-multitenant-example@2.0.0-alpha.20) (2021-03-17) **Note:** Version bump only for package @sourceloop/auth-multitenant-example diff --git a/sandbox/auth-multitenant-example/package-lock.json b/sandbox/auth-multitenant-example/package-lock.json index dc07128cdd..ffbf2064e8 100644 --- a/sandbox/auth-multitenant-example/package-lock.json +++ b/sandbox/auth-multitenant-example/package-lock.json @@ -1,6 +1,6 @@ { "name": "@sourceloop/auth-multitenant-example", - "version": "2.0.0-alpha.20", + "version": "2.0.0-alpha.21", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/sandbox/auth-multitenant-example/package.json b/sandbox/auth-multitenant-example/package.json index bc69ff0160..cc81c26db0 100644 --- a/sandbox/auth-multitenant-example/package.json +++ b/sandbox/auth-multitenant-example/package.json @@ -1,6 +1,6 @@ { "name": "@sourceloop/auth-multitenant-example", - "version": "2.0.0-alpha.20", + "version": "2.0.0-alpha.21", "description": "This is a sample application for sandbox testing of auth microservice components.", "private": true, "keywords": [ @@ -57,7 +57,7 @@ "@loopback/rest": "^9.0.0", "@loopback/rest-explorer": "^3.0.3", "@loopback/service-proxy": "^3.0.3", - "@sourceloop/authentication-service": "^1.0.0-alpha.45", + "@sourceloop/authentication-service": "^1.0.0-alpha.46", "@sourceloop/core": "^1.0.0-alpha.27", "bcrypt": "^5.0.0", "casbin": "^5.2.1", diff --git a/services/authentication-service/CHANGELOG.md b/services/authentication-service/CHANGELOG.md index e3bb0754bb..b989e603d9 100644 --- a/services/authentication-service/CHANGELOG.md +++ b/services/authentication-service/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0-alpha.46](https://github.com/sourcefuse/loopback4-microservice-catalog/compare/@sourceloop/authentication-service@1.0.0-alpha.45...@sourceloop/authentication-service@1.0.0-alpha.46) (2021-03-31) + + +### Features + +* **authentication-service:** add oauth-code read and write providers ([#154](https://github.com/sourcefuse/loopback4-microservice-catalog/issues/154)) ([90fa8e0](https://github.com/sourcefuse/loopback4-microservice-catalog/commit/90fa8e08a927c6c6371a19ab2f75d10c23307b92)) +* **authentication-service:** upgrade loopback4-authentication package to support https proxy ([#156](https://github.com/sourcefuse/loopback4-microservice-catalog/issues/156)) ([915b85b](https://github.com/sourcefuse/loopback4-microservice-catalog/commit/915b85b12732f677f19d960da2e88199dcd7b565)) + + + + + # [1.0.0-alpha.45](https://github.com/sourcefuse/loopback4-microservice-catalog/compare/@sourceloop/authentication-service@1.0.0-alpha.44...@sourceloop/authentication-service@1.0.0-alpha.45) (2021-03-17) **Note:** Version bump only for package @sourceloop/authentication-service diff --git a/services/authentication-service/README.md b/services/authentication-service/README.md index 4402f95d14..67033cdec5 100644 --- a/services/authentication-service/README.md +++ b/services/authentication-service/README.md @@ -1,6 +1,6 @@ # authentication-service -[![LoopBack](https://github.com/strongloop/loopback-next/raw/master/docs/site/imgs/branding/Powered-by-LoopBack-Badge-(blue)-@2x.png)](http://loopback.io/) +[![LoopBack]()](http://loopback.io/) ## Overview @@ -28,7 +28,7 @@ import { RestExplorerComponent, } from '@loopback/rest-explorer'; import {ServiceMixin} from '@loopback/service-proxy'; -import { AuthenticationServiceComponent } from '@sourceloop/in-mail-service'; +import {AuthenticationServiceComponent} from '@sourceloop/in-mail-service'; import * as dotenv from 'dotenv'; import * as dotenvExt from 'dotenv-extended'; import path from 'path'; @@ -77,38 +77,36 @@ export class Client extends BootMixin( ### Environment Variables -| Name | Required | Default Value | Description | -| ----------------------------- | -------- | ------------- | ------------------------------------------------------------ | -| `NODE_ENV` | Y | | Node environment value, i.e. `dev`, `test`, `prod` | -| `LOG_LEVEL` | Y | | Log level value, i.e. `error`, `warn`, `info`, `verbose`, `debug` | -| `DB_HOST` | Y | | Hostname for the database server. | -| `DB_PORT` | Y | | Port for the database server. | -| `DB_USER` | Y | | User for the database. | -| `DB_PASSWORD` | Y | | Password for the database user. | -| `DB_DATABASE` | Y | | Database to connect to on the database server. | +| Name | Required | Default Value | Description | +| ----------------------------- | -------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `NODE_ENV` | Y | | Node environment value, i.e. `dev`, `test`, `prod` | +| `LOG_LEVEL` | Y | | Log level value, i.e. `error`, `warn`, `info`, `verbose`, `debug` | +| `DB_HOST` | Y | | Hostname for the database server. | +| `DB_PORT` | Y | | Port for the database server. | +| `DB_USER` | Y | | User for the database. | +| `DB_PASSWORD` | Y | | Password for the database user. | +| `DB_DATABASE` | Y | | Database to connect to on the database server. | | `DB_SCHEMA` | Y | | Database schema used for the data source. In PostgreSQL, this will be `public` unless a schema is made explicitly for the service. | -| `REDIS_HOST` | Y | | Hostname of the Redis server. | -| `REDIS_PORT` | Y | | Port to connect to the Redis server over. | -| `REDIS_URL` | Y | | Fully composed URL for Redis connection. Used instead of other settings if set. | -| `REDIS_PASSWORD` | Y | | Password for Redis if authentication is enabled. | -| `REDIS_DATABASE` | Y | | Database within Redis to connect to. | -| `JWT_SECRET` | Y | | Symmetric signing key of the JWT token. | -| `JWT_ISSUER` | Y | | Issuer of the JWT token. | -| `USER_TEMP_PASSWORD` | N | | Temporary password that can be used during development. | -| `GOOGLE_AUTH_URL` | N | | Google OAuth2.0 authorization URL if authentication strategy is set to Google | -| `GOOGLE_AUTH_CLIENT_ID` | N | | Google client ID for the service | -| `GOOGLE_AUTH_CLIENT_SECRET` | N | | Google client secret for the service | -| `GOOGLE_AUTH_TOKEN_URL` | N | | Google OAuth2.0 authorization URL if authentication strategy is set to Google | -| `GOOGLE_AUTH_CALLBACK_URL` | N | | Google callback URL for the client configuration in Google | -| `FORGOT_PASSWORD_LINK_EXPIRY` | N | 1800 | Expiration period of temporary password in seconds. 1800 seconds (30 minutes) is the default. | -| `KEYCLOAK_HOST` | N | | Hostname of the Keycloak instance | -| `KEYCLOAK_REALM` | N | | Realm (tenant) in Keycloak | -| `KEYCLOAK_CLIENT_ID` | N | | Keycloak client ID for the service | -| `KEYCLOAK_CLIENT_SECRET` | N | | Keycloak client secret for the service | -| `KEYCLOAK_CALLBACK_URL` | N | | Keycloak callback URL for the client configuration in Google | -| `RATE_LIMITER_WINDOW_MS` | N | | TODO: get definition | -| `RATE_LIMITER_MAX_REQS` | N | | TODO: get definition | -| `X_FRAME_OPTIONS` | N | | TODO: get definition | +| `REDIS_HOST` | Y | | Hostname of the Redis server. | +| `REDIS_PORT` | Y | | Port to connect to the Redis server over. | +| `REDIS_URL` | Y | | Fully composed URL for Redis connection. Used instead of other settings if set. | +| `REDIS_PASSWORD` | Y | | Password for Redis if authentication is enabled. | +| `REDIS_DATABASE` | Y | | Database within Redis to connect to. | +| `JWT_SECRET` | Y | | Symmetric signing key of the JWT token. | +| `JWT_ISSUER` | Y | | Issuer of the JWT token. | +| `USER_TEMP_PASSWORD` | N | | Temporary password that can be used during development. | +| `GOOGLE_AUTH_URL` | N | | Google OAuth2.0 authorization URL if authentication strategy is set to Google | +| `GOOGLE_AUTH_CLIENT_ID` | N | | Google client ID for the service | +| `GOOGLE_AUTH_CLIENT_SECRET` | N | | Google client secret for the service | +| `GOOGLE_AUTH_TOKEN_URL` | N | | Google OAuth2.0 authorization URL if authentication strategy is set to Google | +| `GOOGLE_AUTH_CALLBACK_URL` | N | | Google callback URL for the client configuration in Google | +| `FORGOT_PASSWORD_LINK_EXPIRY` | N | 1800 | Expiration period of temporary password in seconds. 1800 seconds (30 minutes) is the default. | +| `KEYCLOAK_HOST` | N | | Hostname of the Keycloak instance | +| `KEYCLOAK_REALM` | N | | Realm (tenant) in Keycloak | +| `KEYCLOAK_CLIENT_ID` | N | | Keycloak client ID for the service | +| `KEYCLOAK_CLIENT_SECRET` | N | | Keycloak client secret for the service | +| `KEYCLOAK_CALLBACK_URL` | N | | Keycloak callback URL for the client configuration in Google | +| `HTTPS_PROXY` | N | | Https proxy url for keycloak auth | ### Setting up a `DataSource` @@ -131,7 +129,8 @@ const config = { }; @lifeCycleObserver('datasource') -export class AuthenticationDbDataSource extends juggler.DataSource +export class AuthenticationDbDataSource + extends juggler.DataSource implements LifeCycleObserver { static dataSourceName = 'authentication'; static readonly defaultConfig = config; @@ -152,6 +151,10 @@ Refer to [Database Migrations | LoopBack Documentation](https://loopback.io/doc/ ### API Documentation +### Providers + +You can find documentation for some of the providers available in this service [here](./src/providers/README.md) + #### Common Headers Authorization: Bearer where is a JWT token signed using JWT issuer and secret. @@ -173,4 +176,3 @@ Authorization: Bearer where is a JWT token signed using JWT issu #### API Details Visit the [OpenAPI spec docs](OPEN_API_SPEC.md) - diff --git a/services/authentication-service/package-lock.json b/services/authentication-service/package-lock.json index 964a4bc663..72d7ac0e1c 100644 --- a/services/authentication-service/package-lock.json +++ b/services/authentication-service/package-lock.json @@ -1,6 +1,6 @@ { "name": "@sourceloop/authentication-service", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.46", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -222,16 +222,6 @@ "to-fast-properties": "^2.0.0" } }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, "@eslint/eslintrc": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", @@ -718,36 +708,6 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, - "@sourceloop/core": { - "version": "1.0.0-alpha.26", - "resolved": "https://registry.npmjs.org/@sourceloop/core/-/core-1.0.0-alpha.26.tgz", - "integrity": "sha512-lQq5x7gMj0K3pjypVC2ZE7XnX8YeSrsMISodA9r3TIjWOuI0iDkQd1oaQZRke4tyyBMafQdBzGQ7yhDJ6WXR8g==", - "requires": { - "@loopback/boot": "^3.1.0", - "@loopback/context": "^3.13.0", - "@loopback/core": "^2.12.0", - "@loopback/openapi-v3": "^5.1.2", - "@loopback/repository": "^3.2.0", - "@loopback/rest": "^9.0.0", - "@loopback/service-proxy": "^3.0.3", - "casbin": "^5.2.1", - "i18n": "^0.10.0", - "jsonwebtoken": "^8.5.1", - "lodash": "^4.17.20", - "logform": "^2.1.2", - "loopback-datasource-juggler": "^4.21.2", - "loopback4-authentication": "^4.1.0", - "loopback4-authorization": "^3.2.0", - "loopback4-helmet": "^2.0.0", - "loopback4-ratelimiter": "^2.1.0", - "loopback4-soft-delete": "^3.1.0", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", - "swagger-stats": "^0.95.18", - "tslib": "^2.0.0", - "winston": "^3.2.1" - } - }, "@types/bcrypt": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-3.0.0.tgz", @@ -1252,11 +1212,11 @@ "dev": true }, "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "requires": { - "es6-promisify": "^5.0.0" + "debug": "4" } }, "aggregate-error": { @@ -1459,21 +1419,6 @@ "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "bcp47": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz", @@ -1502,11 +1447,6 @@ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, - "bintrees": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" - }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -1585,11 +1525,6 @@ } } }, - "bowser": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz", - "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1714,11 +1649,6 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, "capital-case": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", @@ -1861,30 +1791,11 @@ } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" - }, - "cluster-key-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", - "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1898,29 +1809,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "color-string": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", - "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" - } - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1976,11 +1864,6 @@ } } }, - "content-security-policy-builder": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", - "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -2019,15 +1902,6 @@ "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", "dev": true }, - "cookies": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", - "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", - "requires": { - "depd": "~2.0.0", - "keygrip": "~1.1.0" - } - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -2065,11 +1939,6 @@ "assert-plus": "^1.0.0" } }, - "dasherize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", - "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" - }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -2132,14 +2001,6 @@ "strip-bom": "^4.0.0" } }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "requires": { - "clone": "^1.0.2" - } - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -2158,11 +2019,6 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, - "denque": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", - "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2202,11 +2058,6 @@ "esutils": "^2.0.2" } }, - "dont-sniff-mimetype": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", - "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" - }, "dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -2232,11 +2083,6 @@ "dotenv": "^8.2.0" } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "dtrace-provider": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", @@ -2295,11 +2141,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -2771,11 +2612,6 @@ } } }, - "express-rate-limit": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.2.6.tgz", - "integrity": "sha512-nE96xaxGfxiS5jP3tD3kIW1Jg9yQgX0rXCs3rCkZtmbWHEGyotwaezkLj7bnB41Z0uaOLM8W4AX6qHao4IZ2YA==" - }, "expression-eval": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/expression-eval/-/expression-eval-2.1.0.tgz", @@ -2838,16 +2674,6 @@ "reusify": "^1.0.4" } }, - "feature-policy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", - "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" - }, - "fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" - }, "file-entry-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", @@ -2956,11 +2782,6 @@ "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", @@ -3258,45 +3079,6 @@ "tslib": "^2.0.3" } }, - "helmet": { - "version": "3.23.3", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz", - "integrity": "sha512-U3MeYdzPJQhtvqAVBPntVgAvNSOJyagwZwyKsFdyRa8TV3pOKVFljalPOCxbw5Wwf2kncGhmP0qHjyazIdNdSA==", - "requires": { - "depd": "2.0.0", - "dont-sniff-mimetype": "1.1.0", - "feature-policy": "0.3.0", - "helmet-crossdomain": "0.4.0", - "helmet-csp": "2.10.0", - "hide-powered-by": "1.1.0", - "hpkp": "2.0.0", - "hsts": "2.2.0", - "nocache": "2.1.0", - "referrer-policy": "1.2.0", - "x-xss-protection": "1.3.0" - } - }, - "helmet-crossdomain": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", - "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" - }, - "helmet-csp": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.10.0.tgz", - "integrity": "sha512-Rz953ZNEFk8sT2XvewXkYN0Ho4GEZdjAZy4stjiEQV3eN7GDxg1QKmYggH7otDyIA7uGA6XnUMVSgeJwbR5X+w==", - "requires": { - "bowser": "2.9.0", - "camelize": "1.0.0", - "content-security-policy-builder": "2.1.0", - "dasherize": "2.0.0" - } - }, - "hide-powered-by": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", - "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" - }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3307,19 +3089,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hpkp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", - "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" - }, - "hsts": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", - "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", - "requires": { - "depd": "2.0.0" - } - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3372,22 +3141,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } + "agent-base": "6", + "debug": "4" } }, "human-signals": { @@ -3411,26 +3170,6 @@ } } }, - "i18n": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.10.0.tgz", - "integrity": "sha512-lCSpIm/ZLUCQMAv+UAjSEYzPq96KG7fIx6o1mNQ0MuTBzXpPgd31t4WLzbPG10nKTLJzj9176dgOG7C0wUquSA==", - "requires": { - "debug": "*", - "make-plural": "^6.2.1", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "^4.0.1", - "sprintf-js": "^1.1.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" - } - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3504,30 +3243,6 @@ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-3.0.1.tgz", "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==" }, - "ioredis": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.24.2.tgz", - "integrity": "sha512-SSuVXwoG747sZetxxs9gyAno5kfUfvo4s5mSZp4dh8vzuTnrtA5mTf2OjL6sPfIfNbVTROg2c+VbXceGlpucPQ==", - "requires": { - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", - "denque": "^1.1.0", - "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - } - } - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -3546,11 +3261,6 @@ "call-bind": "^1.0.0" } }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "is-bigint": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", @@ -4027,12 +3737,12 @@ } }, "jwk-to-pem": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-2.0.4.tgz", - "integrity": "sha512-4CCK9UBHNWjWtfSHdyu3I6rA8vlN5cWqnVuwY0cOMyXtw6M1tP+yrM8GZpwk+P932Dc3cLag4d35B6CqyIf89A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-2.0.5.tgz", + "integrity": "sha512-L90jwellhO8jRKYwbssU9ifaMVqajzj3fpRjDKcsDzrslU9syRbFqfkXtT4B89HYAap+xsxNcxgBSB09ig+a7A==", "requires": { "asn1.js": "^5.3.0", - "elliptic": "^6.5.3", + "elliptic": "^6.5.4", "safe-buffer": "^5.0.1" } }, @@ -4045,19 +3755,6 @@ "safe-buffer": "^5.0.1" } }, - "keygrip": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", - "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", - "requires": { - "tsscmp": "1.0.6" - } - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, "lcid": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lcid/-/lcid-3.1.1.tgz", @@ -4095,16 +3792,6 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", @@ -4212,18 +3899,6 @@ } } }, - "logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", - "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - } - }, "loopback-connector": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/loopback-connector/-/loopback-connector-5.0.1.tgz", @@ -4237,62 +3912,6 @@ "uuid": "^8.3.0" } }, - "loopback-connector-kv-redis": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/loopback-connector-kv-redis/-/loopback-connector-kv-redis-4.0.0.tgz", - "integrity": "sha512-PQad2IJpqTvS+nXlX11HjnEXMXXlXAw9GjT+Y/H30JW2b6SHVudQpCulL/szcRta955Wp5OJhxb2tR3b+yI9Uw==", - "requires": { - "debug": "^4.1.1", - "ioredis": "^4.9.3", - "loopback-connector": "^4.0.0", - "strong-globalize": "^6.0.1" - }, - "dependencies": { - "loopback-connector": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/loopback-connector/-/loopback-connector-4.11.1.tgz", - "integrity": "sha512-EA31zur3xIhP4UW+P2rWEcSbqpk4jPddpTBZSSw8KCszM7T0/Pe4HvEmG0MndAWJctRPtrwKDEu/8rWuMDLf+A==", - "requires": { - "async": "^3.2.0", - "bluebird": "^3.7.2", - "debug": "^4.1.1", - "msgpack5": "^4.2.0", - "strong-globalize": "^5.1.0", - "uuid": "^7.0.3" - }, - "dependencies": { - "strong-globalize": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-5.1.0.tgz", - "integrity": "sha512-9cooAb6kNMDFmTDybkkch1x7b+LuzZNva8oIr+MxXnvx9jcvw4/4DTSXPc53mG68G0Q9YOTYZkhDkWe/DiJ1Qg==", - "requires": { - "accept-language": "^3.0.18", - "debug": "^4.1.1", - "globalize": "^1.5.0", - "lodash": "^4.17.15", - "md5": "^2.2.1", - "mkdirp": "^0.5.5", - "os-locale": "^5.0.0", - "yamljs": "^0.3.0" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" - } - } - }, "loopback-datasource-juggler": { "version": "4.26.0", "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-4.26.0.tgz", @@ -4314,13 +3933,14 @@ } }, "loopback4-authentication": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loopback4-authentication/-/loopback4-authentication-4.2.0.tgz", - "integrity": "sha512-Y2NBLf6JOUCz2+5KeJ4uXf+Y5IDRkem8ejJEeaKxYtCXT8qjbICaJ27AVcBQFqqTy+WtaJgmEhw2Gl2+lnO5vQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loopback4-authentication/-/loopback4-authentication-4.3.0.tgz", + "integrity": "sha512-r7Bk+e3kX4y3VkUIK1dLoeG1rMccPb4vROfwCH6eeqDH0DsLORf7xEAPTeq4YHUZb2tKF8SMbOX4MulzyvreJQ==", "requires": { "@exlinc/keycloak-passport": "^1.0.2", "@loopback/context": "^3.13.0", "@loopback/core": "^2.12.0", + "https-proxy-agent": "^5.0.0", "passport": "^0.4.1", "passport-azure-ad": "^4.2.1", "passport-google-oauth20": "^2.0.0", @@ -4340,44 +3960,6 @@ "lodash": "^4.17.20" } }, - "loopback4-helmet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loopback4-helmet/-/loopback4-helmet-2.0.0.tgz", - "integrity": "sha512-3PKckrA/YfObFntusqA37kOiA0wc9IZApfGzc5wEoi+jTeGs2x6StVD42FTR7Ffgv8hDMnidCQ8OTIGH69CBrA==", - "requires": { - "@loopback/boot": "^3.1.0", - "@loopback/context": "^3.13.0", - "@loopback/core": "^2.12.0", - "@loopback/rest": "^9.0.0", - "helmet": "^3.23.3" - } - }, - "loopback4-ratelimiter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/loopback4-ratelimiter/-/loopback4-ratelimiter-2.1.0.tgz", - "integrity": "sha512-gu94HGBtSI4beRfnqI5zmLYuOMBhA0aWQqPg47r/6oYKddkW5uptgviFXTLCZSXC8JpYU8E8YRijj+2XAETgjA==", - "requires": { - "@loopback/boot": "^3.1.0", - "@loopback/context": "^3.13.0", - "@loopback/core": "^2.12.0", - "@loopback/repository": "^3.2.0", - "@loopback/rest": "^9.0.0", - "express-rate-limit": "^5.1.3", - "loopback-connector-kv-redis": "^4.0.0", - "rate-limit-redis": "^1.7.0" - } - }, - "loopback4-soft-delete": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/loopback4-soft-delete/-/loopback4-soft-delete-3.1.0.tgz", - "integrity": "sha512-w70qrU3gh7D3yBRK7Roex8DcioPTYmSzq1V4Soc1uH3JoAPQLxsWhQkaOMcvC6fvOv5qCQyboBEkr3cjOIMYMQ==", - "requires": { - "@loopback/core": "^2.12.0", - "@loopback/rest": "^9.0.0", - "lodash": "^4.17.20", - "loopback4-authentication": "^4.1.0" - } - }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -4419,11 +4001,6 @@ } } }, - "make-plural": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.2.2.tgz", - "integrity": "sha512-8iTuFioatnTTmb/YJjywkVIHLjcwkFD9Ms0JpxjEm9Mo8eQYkh1z+55dwv4yc1jQ8ftVBxWQbihvZL1DfzGGWA==" - }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -4432,11 +4009,6 @@ "p-defer": "^1.0.0" } }, - "math-interval-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", - "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==" - }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -4478,36 +4050,6 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - }, - "dependencies": { - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==" - }, - "messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==" - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -4851,11 +4393,6 @@ "safe-buffer": "^5.1.2" } }, - "mustache": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.1.0.tgz", - "integrity": "sha512-0FsgP/WVq4mKyjolIyX+Z9Bd+3WS8GOwoUTyKXT5cTYMGeauNTi2HPCwERqseC1IHAy0Z7MDZnJBfjabd4O8GQ==" - }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -4987,11 +4524,6 @@ "tslib": "^2.0.3" } }, - "nocache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", - "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" - }, "node-addon-api": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.2.tgz", @@ -5445,14 +4977,6 @@ "wrappy": "1" } }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, "onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -5653,11 +5177,36 @@ "valid-url": "^1.0.6" }, "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, "passport": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz", @@ -5926,14 +5475,6 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, - "prom-client": { - "version": "11.5.3", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz", - "integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==", - "requires": { - "tdigest": "^0.1.1" - } - }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -5992,15 +5533,6 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, - "rate-limit-redis": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-1.7.0.tgz", - "integrity": "sha512-GwqpbMt0riTvra+NiFfX8BKuTdcX7xt0KpU0IahBopjRMzno0niqEKKNaQeNewOzkIz0fOO/R2CSWwfIZdf6oA==", - "requires": { - "defaults": "^1.0.3", - "redis": "^2.8.0" - } - }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", @@ -6077,46 +5609,6 @@ "picomatch": "^2.2.1" } }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" - }, - "dependencies": { - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - } - } - }, - "redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", - "requires": { - "redis-errors": "^1.0.0" - } - }, - "referrer-policy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", - "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" - }, "reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", @@ -6463,14 +5955,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - } - }, "sinon": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.2.tgz", @@ -6632,16 +6116,6 @@ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -6840,30 +6314,6 @@ "has-flag": "^3.0.0" } }, - "swagger-stats": { - "version": "0.95.18", - "resolved": "https://registry.npmjs.org/swagger-stats/-/swagger-stats-0.95.18.tgz", - "integrity": "sha512-SRq7I+VUMZVm4WR2sZbMXEuB+Cu8sp3bJVeI3UltNQmismU+uswP6gA8MCPLs5t3oBzrn+wrCE8OVh4USjtZQw==", - "requires": { - "basic-auth": "^2.0.1", - "cookies": "^0.8.0", - "debug": "^4.1.1", - "moment": "^2.24.0", - "path-to-regexp": "^6.1.0", - "prom-client": "^11.5.3", - "qs": "^6.9.1", - "request": "^2.88.0", - "send": "^0.17.1", - "uuid": "^3.4.0" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } - } - }, "swagger-ui-dist": { "version": "3.37.2", "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.37.2.tgz", @@ -6945,14 +6395,6 @@ } } }, - "tdigest": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", - "requires": { - "bintrees": "1.0.1" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -6964,11 +6406,6 @@ "minimatch": "^3.0.4" } }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7013,21 +6450,11 @@ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, "tslib": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" }, - "tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" - }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", @@ -7282,43 +6709,6 @@ "string-width": "^1.0.2 || 2" } }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "requires": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -7409,11 +6799,6 @@ "typedarray-to-buffer": "^3.1.5" } }, - "x-xss-protection": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", - "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" - }, "xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", diff --git a/services/authentication-service/package.json b/services/authentication-service/package.json index d268f8dee5..b7d6e693b4 100644 --- a/services/authentication-service/package.json +++ b/services/authentication-service/package.json @@ -1,6 +1,6 @@ { "name": "@sourceloop/authentication-service", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.46", "description": "services", "keywords": [ "loopback-extension", @@ -55,7 +55,7 @@ "dotenv-extended": "^2.8.0", "jsonwebtoken": "^8.5.1", "lodash": "^4.17.20", - "loopback4-authentication": "^4.2.0", + "loopback4-authentication": "^4.3.0", "loopback4-authorization": "^3.2.0", "moment": "^2.27.0", "moment-timezone": "^0.5.31", diff --git a/services/authentication-service/src/component.ts b/services/authentication-service/src/component.ts index 7e7036e837..08892b3a97 100644 --- a/services/authentication-service/src/component.ts +++ b/services/authentication-service/src/component.ts @@ -30,6 +30,8 @@ import {MySequence} from './sequence'; import {IAuthServiceConfig} from './types'; import {KeycloakVerifyProvider} from './modules/auth/providers/keycloak-verify.provider'; import { + AuthCodeBindings, + CodeWriterProvider, GoogleOauth2SignupProvider, GooglePostVerifyProvider, GooglePreVerifyProvider, @@ -43,6 +45,7 @@ import {KeyCloakSignupProvider} from './providers/keycloak-signup.provider'; import {LocalSignupProvider} from './providers/local-signup.provider'; import {LocalPreSignupProvider} from './providers/local-presignup.provider'; import {SignupBearerVerifyProvider} from './providers/bearer-verify.provider'; +import {OauthCodeReaderProvider} from './providers/code-reader.provider'; export class AuthenticationServiceComponent implements Component { constructor( @@ -169,6 +172,13 @@ export class AuthenticationServiceComponent implements Component { VerifyBindings.BEARER_SIGNUP_VERIFY_PROVIDER.key ] = SignupBearerVerifyProvider; + this.providers[ + AuthCodeBindings.CODEREADER_PROVIDER.key + ] = OauthCodeReaderProvider; + this.providers[ + AuthCodeBindings.CODEWRITER_PROVIDER.key + ] = CodeWriterProvider; + this.providers[ AuthServiceBindings.JWTPayloadProvider.key ] = JwtPayloadProvider; diff --git a/services/authentication-service/src/controllers/forget-password.controller.ts b/services/authentication-service/src/controllers/forget-password.controller.ts index 8744f037c9..4ea1be4059 100644 --- a/services/authentication-service/src/controllers/forget-password.controller.ts +++ b/services/authentication-service/src/controllers/forget-password.controller.ts @@ -98,6 +98,7 @@ export class ForgetPasswordController { audience: req.client_id, subject: user.username.toLowerCase(), issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', }); return new ForgetPasswordResponseDto({ code: token, @@ -133,6 +134,7 @@ export class ForgetPasswordController { try { payload = jwt.verify(token, process.env.JWT_SECRET as string, { issuer: process.env.JWT_ISSUER, + algorithms: ['HS256'], }) as ClientAuthCode; } catch (error) { throw new HttpErrors.Unauthorized(AuthErrorKeys.TokenExpired); @@ -182,6 +184,7 @@ export class ForgetPasswordController { try { payload = jwt.verify(req.token, process.env.JWT_SECRET as string, { issuer: process.env.JWT_ISSUER, + algorithms: ['HS256'], }) as ClientAuthCode; } catch (error) { throw new HttpErrors.Unauthorized(AuthErrorKeys.TokenExpired); diff --git a/services/authentication-service/src/controllers/signup-request.controller.ts b/services/authentication-service/src/controllers/signup-request.controller.ts index 2644a56258..df7cf3040f 100644 --- a/services/authentication-service/src/controllers/signup-request.controller.ts +++ b/services/authentication-service/src/controllers/signup-request.controller.ts @@ -58,6 +58,7 @@ export class SignupRequestController { expiresIn: expiryDuration, subject: signUpRequest.email, issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', }); return new SignupRequestResponseDto({ diff --git a/services/authentication-service/src/modules/auth/login.controller.ts b/services/authentication-service/src/modules/auth/login.controller.ts index f4f24417ed..12b92dfe33 100644 --- a/services/authentication-service/src/modules/auth/login.controller.ts +++ b/services/authentication-service/src/modules/auth/login.controller.ts @@ -40,7 +40,12 @@ import {URLSearchParams} from 'url'; import {AuthServiceBindings} from '../../keys'; import {AuthClient, RefreshToken, User} from '../../models'; -import {JwtPayloadFn} from '../../providers'; +import { + AuthCodeBindings, + CodeReaderFn, + CodeWriterFn, + JwtPayloadFn, +} from '../../providers'; import { AuthClientRepository, RefreshTokenRepository, @@ -154,8 +159,8 @@ export class LoginController { const token = jwt.sign(codePayload, this.client.secret, { expiresIn: this.client.authCodeExpiration, audience: req.client_id, - subject: req.username.toLowerCase(), issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', }); return { code: token, @@ -251,6 +256,8 @@ export class LoginController { }) async getToken( @requestBody() req: AuthTokenRequest, + @inject(AuthCodeBindings.CODEREADER_PROVIDER) + codeReader: CodeReaderFn, @param.header.string('device_id') deviceId?: string, ): Promise { const authClient = await this.authClientRepository.findOne({ @@ -262,10 +269,11 @@ export class LoginController { throw new HttpErrors.Unauthorized(AuthErrorKeys.ClientInvalid); } try { - const payload = jwt.verify(req.code, authClient.secret, { + const code = await codeReader(req.code); + const payload = jwt.verify(code, authClient.secret, { audience: req.clientId, - subject: req.username, issuer: process.env.JWT_ISSUER, + algorithms: ['HS256'], }) as ClientAuthCode; if ( @@ -403,6 +411,8 @@ export class LoginController { @param.query.string('code') code: string, @param.query.string('state') state: string, @inject(RestBindings.Http.RESPONSE) response: Response, + @inject(AuthCodeBindings.CODEWRITER_PROVIDER) + googleCodeWriter: CodeWriterFn, ): Promise { const clientId = new URLSearchParams(state).get('client_id'); if (!clientId || !this.user) { @@ -421,15 +431,15 @@ export class LoginController { clientId, user: this.user, }; - const token = jwt.sign(codePayload, client.secret, { - expiresIn: client.authCodeExpiration, - audience: clientId, - subject: this.user.username, - issuer: process.env.JWT_ISSUER, - }); - response.redirect( - `${client.redirectUrl}?code=${token}&username=${this.user.username}`, + const token = await googleCodeWriter( + jwt.sign(codePayload, client.secret, { + expiresIn: client.authCodeExpiration, + audience: clientId, + issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', + }), ); + response.redirect(`${client.redirectUrl}?code=${token}`); } catch (error) { this.logger.error(error); throw new HttpErrors.Unauthorized(AuthErrorKeys.InvalidCredentials); @@ -502,6 +512,8 @@ export class LoginController { @param.query.string('code') code: string, @param.query.string('state') state: string, @inject(RestBindings.Http.RESPONSE) response: Response, + @inject(AuthCodeBindings.CODEWRITER_PROVIDER) + keycloackCodeWriter: CodeWriterFn, ): Promise { const clientId = new URLSearchParams(state).get('client_id'); if (!clientId || !this.user) { @@ -520,15 +532,15 @@ export class LoginController { clientId, user: this.user, }; - const token = jwt.sign(codePayload, client.secret, { - expiresIn: client.authCodeExpiration, - audience: clientId, - subject: this.user.username, - issuer: process.env.JWT_ISSUER, - }); - response.redirect( - `${client.redirectUrl}?code=${token}&user=${this.user.username}`, + const token = await keycloackCodeWriter( + jwt.sign(codePayload, client.secret, { + expiresIn: client.authCodeExpiration, + audience: clientId, + issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', + }), ); + response.redirect(`${client.redirectUrl}?code=${token}`); } catch (error) { this.logger.error(error); throw new HttpErrors.Unauthorized(AuthErrorKeys.InvalidCredentials); @@ -676,6 +688,7 @@ export class LoginController { const accessToken = jwt.sign(data, process.env.JWT_SECRET as string, { expiresIn: authClient.accessTokenExpiration, issuer: process.env.JWT_ISSUER, + algorithm: 'HS256', }); const refreshToken: string = randomBytes(size).toString('hex'); // Set refresh token into redis for later verification diff --git a/services/authentication-service/src/modules/auth/models/auth-token-request.dto.ts b/services/authentication-service/src/modules/auth/models/auth-token-request.dto.ts index 67b11983ab..1b2de5877a 100644 --- a/services/authentication-service/src/modules/auth/models/auth-token-request.dto.ts +++ b/services/authentication-service/src/modules/auth/models/auth-token-request.dto.ts @@ -17,12 +17,6 @@ export class AuthTokenRequest extends Model { }) clientId: string; - @property({ - type: 'string', - required: true, - }) - username: string; - constructor(data?: Partial) { super(data); } diff --git a/services/authentication-service/src/modules/auth/providers/bearer-token-verify.provider.ts b/services/authentication-service/src/modules/auth/providers/bearer-token-verify.provider.ts index 504400e528..b7f8ff0ab3 100644 --- a/services/authentication-service/src/modules/auth/providers/bearer-token-verify.provider.ts +++ b/services/authentication-service/src/modules/auth/providers/bearer-token-verify.provider.ts @@ -28,6 +28,7 @@ export class BearerTokenVerifyProvider try { user = verify(token, process.env.JWT_SECRET as string, { issuer: process.env.JWT_ISSUER, + algorithms: ['HS256'], }) as AuthUser; } catch (error) { this.logger.error(JSON.stringify(error)); diff --git a/services/authentication-service/src/providers/README.md b/services/authentication-service/src/providers/README.md index 8576d12cef..ceb50ef616 100644 --- a/services/authentication-service/src/providers/README.md +++ b/services/authentication-service/src/providers/README.md @@ -9,112 +9,143 @@ A [provider](http://loopback.io/doc/en/lb4/Creating-components.html#providers) is a class that provides a `value()` function. This function is called `Context` when another entity requests a value to be injected. -Here we create a provider for a logging function that can be used as a new -action in a custom [sequence](http://loopback.io/doc/en/lb4/Sequence.html). +## Basic Usage -The logger will log the URL, the parsed request parameters, and the result. The -logger is also capable of timing the sequence if you start a timer at the start -of the sequence using `this.logger.startTimer()`. +These are the optional bindings that can be used to extend the functionality of this service. -## Basic Usage +### BEARER_TOKEN_VERIFIER -### TimerProvider +This provides a function that is used to verify the Bearer Token for endpoints using the Bearer Token authentication. -TimerProvider is automatically bound to your Application's -[Context](http://loopback.io/doc/en/lb4/Context.html) using the LogComponent -which exports this provider with a binding key of `extension-starter.timer`. You -can learn more about components in the -[related resources section](#related-resources). +Implementation for this can be seen [here](../modules/auth/providers/bearer-token-verify.provider.ts); -This provider makes availble to your application a timer function which given a -start time _(given as an array [seconds, nanoseconds])_ can give you a total -time elapsed since the start in milliseconds. The timer can also start timing if -no start time is given. This is used by LogComponent to allow a user to time a -Sequence. +### CODEREADER_PROVIDER -_NOTE:_ _You can get the start time in the required format by using -`this.logger.startTimer()`._ +This provides a function that can process the authorization code (used in KeyCloak and Google Oauth authentications) before being verified. +This can be used to decrypt a code or to retrieve it from Cache/Redis. -You can provide your own implementation of the elapsed time function by binding -it to the binding key (accessible via `ExtensionStarterBindings`) as follows: +Sample implementation - ```ts -app.bind(ExtensionStarterBindings.TIMER).to(timerFn); +export class CodeReaderProvider + implements Provider { + constructor( + @repository(CodeRepository) + private readonly codeRepo: CodeRepository + ) { } + + value(): CodeReaderFn { + return async (token) => { + let codeModel = await this.codeRepo.get(token); + if (!codeModel?.code) { + return token; + } + await this.codeRepo.delete(token); + return codeModel.code + } + } +} ``` +Here ```CodeRepository``` is a Redis Repository, implementation for such a key pair repository can be seen [here](https://loopback.io/doc/en/lb4/Repository.html#access-keyvalue-stores). -### LogProvider -LogProvider can automatically be bound to your Application's Context using the -LogComponent which exports the provider with a binding key of -`extension-starter.actions.log`. +### CODEWRITER_PROVIDER -The key can be accessed by importing `ExtensionStarterBindings` as follows: +This provides a function that can process the authorization code before it is passed to the client, it can be used to store the token in a cache and pass only a key, or to encrypt the token. -**Example: Binding Keys** +Sample implementation - ```ts -import {ExtensionStarterBindings} from 'HelloExtensions'; -// Key can be accessed as follows now -const key = ExtensionStarterBindings.LOG_ACTION; +export class CodeWriterProvider + implements Provider { + constructor( + @repository(CodeRepository) + private readonly codeRepo: CodeRepository + ) { } + + value(): CodeWriterFn { + return async (token) => { + let key = uuidv4(); + await this.codeRepo.set(key, {code: token}); + return key; + } + } +} ``` +Here ```CodeRepository``` is a Redis Repository, implementation for such a key pair repository can be seen [here](https://loopback.io/doc/en/lb4/Repository.html#access-keyvalue-stores). + +```uuidv4``` is function to from [this](https://www.npmjs.com/package/uuid). + +### PRE_LOCAL_SIGNUP_PROVIDER + +This provides a function that creates the object stored in the JWT token for signup requests. + +Sample implementation for this can be seen [here](./local-presignup.provider.ts) + +### LOCAL_SIGNUP_PROVIDER -LogProvider gives us a seuqence action and a `startTimer` function. In order to -use the sequence action, you must define your own sequence as shown below. +This provides a function that gets the data from the signup token and is responsible for performing all tasks required to signup a user. -**Example: Sequence** +Sample implementation - ```ts -class LogSequence implements SequenceHandler { +export class LocalSignupProvider + implements + Provider> { constructor( - @inject(coreSequenceActions.FIND_ROUTE) protected findRoute: FindRoute, - @inject(coreSequenceActions.PARSE_PARAMS) - protected parseParams: ParseParams, - @inject(coreSequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod, - @inject(coreSequenceActions.SEND) protected send: Send, - @inject(coreSequenceActions.REJECT) protected reject: Reject, - // We get the logger injected by the LogProvider here - @inject(ExtensionStarterBindings.LOG_ACTION) protected logger: LogFn, + @service(UserService) + private readonly userService: UserService, ) {} - async handle(context: RequestContext) { - const {request, response} = context; - - // We define these variable outside so they can be accessed by logger. - let args: any = []; - let result: any; - - // Optionally start timing the sequence using the timer - // function available via LogFn - const start = this.logger.startTimer(); - - try { - const route = this.findRoute(request); - args = await this.parseParams(request, route); - result = await this.invoke(route, args); - this.send(response, result); - } catch (error) { - result = error; // so we can log the error message in the logger - this.reject(context, error); - } - - // We call the logger function given to us by LogProvider - this.logger(request, args, result, start); + value(): UserSignupFn { + return async (model: UserSignupDto, tokenInfo?: AnyObject) => { + if (!model.userData) { + throw new HttpErrors.BadRequest('userData missing'); + } + if (tokenInfo?.email && model.email === tokenInfo.email) { + await this.userService.updateUser(model.userData, model.email); + } else { + throw new HttpErrors.BadRequest('Invalid Email'); + } + }; } } + ``` -Once a sequence has been written, we can just use that in our Application as -follows: +### BEARER_SIGNUP_VERIFY_PROVIDER -**Example: Application** +The provider for this key is used to verify a signup token generated by the signup endpoint. + +```ts + this.bind(VerifyBindings.BEARER_SIGNUP_VERIFY_PROVIDER).toProvider( + SignupBearerVerifyProvider, + ); +``` ```ts -const app = new Application({ - sequence: LogSequence, -}); -app.component(LogComponent); +export class SignupBearerVerifyProvider + implements Provider> { + constructor( + ) {} -// Now all requests handled by our sequence will be logged. + value(): VerifyFunction.BearerFn { + return async (token: string) => { + let result: UserInviteDto; + try { + result = verify(token, process.env.JWT_SECRET as string, { + issuer: process.env.JWT_ISSUER, + }) as UserInviteDto; + } catch (error) { + throw new HttpErrors.Unauthorized('TokenExpired'); + } + if (await this.userOpsService.checkUserSignedUp(result.email)) { + throw new HttpErrors.Forbidden('TokenAlreadyUsed'); + } + return result; + }; + } +} ``` ## Related Resources @@ -123,7 +154,4 @@ You can check out the following resource to learn more about providers, components, sequences, and binding keys. - [Providers](http://loopback.io/doc/en/lb4/Creating-components.html#providers) -- [Creating Components](http://loopback.io/doc/en/lb4/Creating-components.html) -- [Using Components](http://loopback.io/doc/en/lb4/Using-components.html) -- [Sequence](http://loopback.io/doc/en/lb4/Sequence.html) - [Binding Keys](http://loopback.io/doc/en/lb4/Decorators.html) diff --git a/services/authentication-service/src/providers/bearer-verify.provider.ts b/services/authentication-service/src/providers/bearer-verify.provider.ts index d48e25c655..8dcfa6a702 100644 --- a/services/authentication-service/src/providers/bearer-verify.provider.ts +++ b/services/authentication-service/src/providers/bearer-verify.provider.ts @@ -15,6 +15,7 @@ export class SignupBearerVerifyProvider try { result = verify(token, process.env.JWT_SECRET as string, { issuer: process.env.JWT_ISSUER, + algorithms: ['HS256'], }) as SignupRequest; } catch (error) { this.logger.error(JSON.stringify(error)); diff --git a/services/authentication-service/src/providers/code-reader.provider.ts b/services/authentication-service/src/providers/code-reader.provider.ts new file mode 100644 index 0000000000..08bef4e87b --- /dev/null +++ b/services/authentication-service/src/providers/code-reader.provider.ts @@ -0,0 +1,8 @@ +import {Provider} from '@loopback/core'; +import {CodeReaderFn} from './types'; + +export class OauthCodeReaderProvider implements Provider { + value(): CodeReaderFn { + return async token => token; + } +} diff --git a/services/authentication-service/src/providers/code-writer.provider.ts b/services/authentication-service/src/providers/code-writer.provider.ts new file mode 100644 index 0000000000..198bf5a880 --- /dev/null +++ b/services/authentication-service/src/providers/code-writer.provider.ts @@ -0,0 +1,8 @@ +import {Provider} from '@loopback/core'; +import {CodeWriterFn} from './types'; + +export class CodeWriterProvider implements Provider { + value(): CodeWriterFn { + return async token => token; + } +} diff --git a/services/authentication-service/src/providers/index.ts b/services/authentication-service/src/providers/index.ts index 90b22e3419..1c062e30bb 100644 --- a/services/authentication-service/src/providers/index.ts +++ b/services/authentication-service/src/providers/index.ts @@ -10,3 +10,5 @@ export * from './jwt-payload.provider'; export * from './bearer-verify.provider'; export * from './local-presignup.provider'; export * from './local-signup.provider'; +export * from './code-reader.provider'; +export * from './code-writer.provider'; diff --git a/services/authentication-service/src/providers/keys.ts b/services/authentication-service/src/providers/keys.ts index cb0b7f2d7a..3a10a7cb3d 100644 --- a/services/authentication-service/src/providers/keys.ts +++ b/services/authentication-service/src/providers/keys.ts @@ -9,6 +9,8 @@ import { KeyCloakPostVerifyFn, KeyCloakPreVerifyFn, KeyCloakSignUpFn, + CodeReaderFn, + CodeWriterFn, } from './types'; export namespace SignUpBindings { @@ -45,3 +47,13 @@ export namespace VerifyBindings { `sf.bearer.signupverify.provider`, ); } + +export namespace AuthCodeBindings { + export const CODEWRITER_PROVIDER = BindingKey.create( + 'sf.keycloack.codewriter.provider', + ); + + export const CODEREADER_PROVIDER = BindingKey.create( + 'sf.oauth.codereader.provider', + ); +} diff --git a/services/authentication-service/src/providers/types.ts b/services/authentication-service/src/providers/types.ts index 36974a924f..40973a1bbb 100644 --- a/services/authentication-service/src/providers/types.ts +++ b/services/authentication-service/src/providers/types.ts @@ -44,6 +44,14 @@ export interface KeyCloakPostVerifyFn { (profile: KeycloakProfile, user: IAuthUser | null): Promise; } +export interface CodeWriterFn { + (token: string): Promise; +} + +export interface CodeReaderFn { + (token: string): Promise; +} + export interface IDeviceInfo { userAgent?: string; deviceId?: string;