From 8108c176d611eea52d0417a6fe63fcb18e74e2f3 Mon Sep 17 00:00:00 2001 From: xXLXx Date: Sat, 25 Jun 2022 22:23:05 +0800 Subject: [PATCH 1/4] feat: update docs to 0.7.8 from 0.7.7 This has no generated mkdocs yet --- docs/advance/helpers.md | 18 ++++++++++++++++++ docs/basics/middleware.md | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/docs/advance/helpers.md b/docs/advance/helpers.md index 650de82..ae4e16c 100644 --- a/docs/advance/helpers.md +++ b/docs/advance/helpers.md @@ -169,6 +169,16 @@ const validFields = [ enumValues: ["abc", "def", "xyz"], required: true, }, + { key: "someFunc", type: "function", required: true }, + { key: "someJson", type: "json", required: true }, + { key: "someObjectCollection", type: "object", required: true, isCollection: true }, + { + key: "someEnumCollection", + type: "enum", + enumValues: ["abc", "def", "xyz"], + required: true, + isCollection: true + }, ]; const toValidate1 = { @@ -182,6 +192,10 @@ const toValidate1 = { someEmail: "email@mail.com", someArray: ["aaa", "bbb", "ccc"], someEnum: "def", + someFunc: () => 'bar', + someJson: "{\"foo\":\"bar\",\"isTest\":1}", + someObjectCollection: [{ "foo": "bar", "isTest": 1 }, [{ "another": "object" }], + someEnumCollection: ["def", "abc", "abc"], }; const validated = validateFields(toValidate1, validFields)); @@ -198,6 +212,10 @@ const validated = validateFields(toValidate1, validFields)); someEmail: "email@mail.com", someArray: ["aaa", "bbb", "ccc"], someEnum: "def", + someFunc: () => 'bar', + someJson: "{\"foo\":\"bar\",\"isTest\":1}", + someObjectCollection: [{ "foo": "bar", "isTest": 1 }, [{ "another": "object" }], + someEnumCollection: ["def", "abc", "abc"], } */ ``` diff --git a/docs/basics/middleware.md b/docs/basics/middleware.md index 0450265..3ce282c 100644 --- a/docs/basics/middleware.md +++ b/docs/basics/middleware.md @@ -66,6 +66,25 @@ The successfuly response will be formatted in this way } ``` +### Http No Output + +This middleware normalizes all HTTP requests, handles, and formats success and error responses to make sure it always returns a success 200 with no body. + +**Usage** + +```js +import middy from '@middy/core'; +import httpNoOutputMiddleware from "Middlewares/httpNoOutputMiddleware"; + +const originalHandler = event => { + return event.input; +}; + +export const handler = middy(originalHandler); + +handler.use(httpNoOutputMiddleware()); +``` + ### Normalize SQS Message This middleware will normalize records coming from sqs message event. The `Records` object in the `handler.event` will be normalized into `handler.event.collection`. This middleware executes _before_ the handler is called. From ff5c8dc8b94f3161be14f635edfb5d0ba6d33811 Mon Sep 17 00:00:00 2001 From: xXLXx Date: Mon, 11 Jul 2022 11:08:11 +0800 Subject: [PATCH 2/4] feat: update documentation for middlewares --- docs/basics/middleware.md | 152 ----------------------- docs/basics/middlewares/auth.md | 105 ++++++++++++++++ docs/basics/middlewares/event-parsing.md | 20 +++ docs/basics/middlewares/http.md | 74 +++++++++++ docs/basics/middlewares/introduction.md | 21 ++++ mkdocs.yml | 6 +- 6 files changed, 225 insertions(+), 153 deletions(-) delete mode 100644 docs/basics/middleware.md create mode 100644 docs/basics/middlewares/auth.md create mode 100644 docs/basics/middlewares/event-parsing.md create mode 100644 docs/basics/middlewares/http.md create mode 100644 docs/basics/middlewares/introduction.md diff --git a/docs/basics/middleware.md b/docs/basics/middleware.md deleted file mode 100644 index 3ce282c..0000000 --- a/docs/basics/middleware.md +++ /dev/null @@ -1,152 +0,0 @@ -# Middleware - -Middlewares can be executed before or after a request, usually handled by the handlers. This will be useful for cases where an action is required prior to reaching the handler, or when an action is required to execute prior to the returning of the response. - -Middlewares require [Middy npm](https://www.npmjs.com/package/middy) to work. - -Middlewares should be written in the `src/middlewares/` directory. - -## Available Middlewares - -Lesgo! comes with 3 pre-existing middlewares. - -You may also import other ready-made middlewares from the [Middy repository](https://www.npmjs.com/package/middy#available-middlewares). - -### Http - -This middleware normalizes all HTTP requests, handles, and formats success and error responses, and should be used for all HTTP endpoints. Will also provide any or both JSON body and url querystring parameters into a single `event.input`. This middleware will also populate with `event.auth.sub` when JWT is used and presented with the `Authorization` header. - -**Usage** - -```js -import middy from '@middy/core'; -import httpMiddleware from "Middlewares/httpMiddleware"; - -const originalHandler = event => { - return event.input; -}; - -export const handler = middy(originalHandler); - -handler.use(httpMiddleware()); -``` - -#### Success Response - -The successfuly response will be formatted in this way -```json -{ - "status": "success", - "data": {}, - "_meta": {} -} -``` - -#### Error Response - -The successfuly response will be formatted in this way -```json -{ - "status": "error", - "data": null, - "error": { - "code": "Core/users/getUser::USER_NOT_EXIST", - "message": "UserException: User does not exist", - "details": { - "err": { - "name": "UserException", - "message": "User not found", - "statusCode": 404, - "code": "Core/users/getUser::USER_NOT_EXIST", - "extra": {} - } - } - }, - "_meta": {} -} -``` - -### Http No Output - -This middleware normalizes all HTTP requests, handles, and formats success and error responses to make sure it always returns a success 200 with no body. - -**Usage** - -```js -import middy from '@middy/core'; -import httpNoOutputMiddleware from "Middlewares/httpNoOutputMiddleware"; - -const originalHandler = event => { - return event.input; -}; - -export const handler = middy(originalHandler); - -handler.use(httpNoOutputMiddleware()); -``` - -### Normalize SQS Message - -This middleware will normalize records coming from sqs message event. The `Records` object in the `handler.event` will be normalized into `handler.event.collection`. This middleware executes _before_ the handler is called. - -**Usage** - -```js -import middy from '@middy/core'; -import normalizeSQSMessage from "Middlewares/normalizeSQSMessage"; - -const originalHandler = event => { - return event.collection; -}; - -export const handler = middy(originalHandler); - -handler.use(normalizeSQSMessage()); -``` - -### Verify JWT - -This middleware will verify any JWT passed to the `Authorization` header of the http request. The decoded JWT can be accesed through `handler.event.decodedJwt`. If the JWT is verified, `handler.event.auth.sub` is set to the JWT's sub, else a `403` response will be thrown. - -**Configuration** - -The JWT configuration for your application is located at `src/config/jwt.js`. Or copy [this file](https://raw.githubusercontent.com/reflex-media/lesgo/master/src/config/jwt.js) to that path. - -You may also simply update the respective environment files in `config/environments/*` as such: - -```apache -# SHA256 JWT secret key, used to verify the token passed to "Authorization" header -JWT_SECRET="" - -# Leave empty if you don't want the issuer to be validated -JWT_ISS_SHOULD_VALIDATE= - -# Comma-separated list of domains to validate -JWT_ISS_DOMAINS="" - -# Leave empty if you don't want the custom claims to be validated -JWT_CUSTOM_CLAIMS_SHOULD_VALIDATE= - -# List of custom claims to valdiate. -# Visit https://auth0.com/docs/tokens/jwt-claims for more info -JWT_CUSTOM_CLAIMS_DATA="" -``` - -**Usage** - -```js -import middy from '@middy/core'; -import verifyJwtTokenMiddleware from "Middlewares/verifyJwtTokenMiddleware"; - -const originalHandler = event => { - return event.collection; -}; - -export const handler = middy(originalHandler); - -handler.use(verifyJwtTokenMiddleware()); -``` - -## Custom Middlewares - -You can write your own custom middleware with [Middy](https://www.npmjs.com/package/middy#writing-a-middleware). diff --git a/docs/basics/middlewares/auth.md b/docs/basics/middlewares/auth.md new file mode 100644 index 0000000..afa6ea9 --- /dev/null +++ b/docs/basics/middlewares/auth.md @@ -0,0 +1,105 @@ +These middlewares can be utilized as a layer of authentication before going through your HTTP requests. + +## Verify JWT + +This middleware will verify any JWT passed to the `Authorization` header of the http request. The decoded JWT can be accesed through `handler.event.decodedJwt`. If the JWT is verified, `handler.event.auth.sub` is set to the JWT's sub, else a `403` response will be thrown. + +**Configuration** + +The JWT configuration for your application is located at `src/config/jwt.js`. Or copy [this file](https://raw.githubusercontent.com/reflex-media/lesgo/master/src/config/jwt.js) to that path. + +You may also simply update the respective environment files in `config/environments/*` as such: + +```apache +# SHA256 JWT secret key, used to verify the token passed to "Authorization" header +JWT_SECRET="" + +# Leave empty if you don't want the issuer to be validated +JWT_ISS_SHOULD_VALIDATE= + +# Comma-separated list of domains to validate +JWT_ISS_DOMAINS="" + +# Leave empty if you don't want the custom claims to be validated +JWT_CUSTOM_CLAIMS_SHOULD_VALIDATE= + +# List of custom claims to valdiate. +# Visit https://auth0.com/docs/tokens/jwt-claims for more info +JWT_CUSTOM_CLAIMS_DATA="" +``` + +**Usage** + +```js +import middy from '@middy/core'; +import verifyJwtTokenMiddleware from "Middlewares/verifyJwtTokenMiddleware"; + +const originalHandler = event => { + return event.collection; +}; + +export const handler = middy(originalHandler); + +handler.use(verifyJwtTokenMiddleware()); +``` + +## Basic Auth + +This middleware will verify any basic auth passed to the `Authorization` header of the http request. Throws `Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY` when a basic auth cannot be found in the clients list configuration. + +**Configuration** + +The basic auth configuration for your application is located at `src/config/client.js`. Or copy [this file](https://raw.githubusercontent.com/reflex-media/lesgo/master/src/config/client.js) to that path. + +**Usage** + +```js +import middy from '@middy/core'; +import basicAuthMiddleware from "Middlewares/basicAuthMiddleware"; + +const originalHandler = event => { + return event.collection; +}; + +export const handler = middy(originalHandler); + +handler.use(basicAuthMiddleware()); + +// or + +handler.use(basicAuthMiddleware({ + // When set to false, disables throwing on failure + blacklistMode: false, + + // This is set as an override for Config/client.js when needed + client: { + myApp: { + key: 'myappkeystring', + secret: 'myappsecretstring' + } + } +})); +``` + +## Client Auth + +This middleware will verify key passed to `x-client-id` header of the http request and sets the match to `handler.event.platform`. Throws `Middlewares/clientAuthMiddleware::INVALID_CLIENT_ID` when a basic auth cannot be found in the clients list configuration. + +**Configuration** + +The basic auth configuration for your application is located at `src/config/client.js`. Or copy [this file](https://raw.githubusercontent.com/reflex-media/lesgo/master/src/config/client.js) to that path. + +**Usage** + +```js +import middy from '@middy/core'; +import clientAuthMiddleware from "Middlewares/clientAuthMiddleware"; + +const originalHandler = event => { + return event.collection; +}; + +export const handler = middy(originalHandler); + +handler.use(clientAuthMiddleware()); +``` \ No newline at end of file diff --git a/docs/basics/middlewares/event-parsing.md b/docs/basics/middlewares/event-parsing.md new file mode 100644 index 0000000..8f3cb03 --- /dev/null +++ b/docs/basics/middlewares/event-parsing.md @@ -0,0 +1,20 @@ +These middlewares can be utilized for parsing data from specific services such as AWS Services, and just instead directly accessing it from a single list of recors inside `handler.event.collection`. + +## Normalize SQS Message + +This middleware will normalize records coming from sqs message event. The `Records` object in the `handler.event` will be normalized into `handler.event.collection`. This middleware executes _before_ the handler is called. + +**Usage** + +```js +import middy from '@middy/core'; +import normalizeSQSMessage from "Middlewares/normalizeSQSMessage"; + +const originalHandler = event => { + return event.collection; +}; + +export const handler = middy(originalHandler); + +handler.use(normalizeSQSMessage()); +``` \ No newline at end of file diff --git a/docs/basics/middlewares/http.md b/docs/basics/middlewares/http.md new file mode 100644 index 0000000..b026e60 --- /dev/null +++ b/docs/basics/middlewares/http.md @@ -0,0 +1,74 @@ +These middlewares can be utilized to parse HTTP requests and output HTTP in different specific formats. + +## Http + +This middleware normalizes all HTTP requests, handles, and formats success and error responses, and should be used for all HTTP endpoints. Will also provide any or both JSON body and url querystring parameters into a single `event.input`. This middleware will also populate with `event.auth.sub` when JWT is used and presented with the `Authorization` header. + +**Usage** + +```js +import middy from '@middy/core'; +import httpMiddleware from "Middlewares/httpMiddleware"; + +const originalHandler = event => { + return event.input; +}; + +export const handler = middy(originalHandler); + +handler.use(httpMiddleware()); +``` + +#### Success Response + +The successfuly response will be formatted in this way +```json +{ + "status": "success", + "data": {}, + "_meta": {} +} +``` + +#### Error Response + +The successfuly response will be formatted in this way +```json +{ + "status": "error", + "data": null, + "error": { + "code": "Core/users/getUser::USER_NOT_EXIST", + "message": "UserException: User does not exist", + "details": { + "err": { + "name": "UserException", + "message": "User not found", + "statusCode": 404, + "code": "Core/users/getUser::USER_NOT_EXIST", + "extra": {} + } + } + }, + "_meta": {} +} +``` + +## Http No Output + +This middleware normalizes all HTTP requests, handles, and formats success and error responses to make sure it always returns a success 200 with no body. + +**Usage** + +```js +import middy from '@middy/core'; +import httpNoOutputMiddleware from "Middlewares/httpNoOutputMiddleware"; + +const originalHandler = event => { + return event.input; +}; + +export const handler = middy(originalHandler); + +handler.use(httpNoOutputMiddleware()); +``` \ No newline at end of file diff --git a/docs/basics/middlewares/introduction.md b/docs/basics/middlewares/introduction.md new file mode 100644 index 0000000..6d43574 --- /dev/null +++ b/docs/basics/middlewares/introduction.md @@ -0,0 +1,21 @@ +# Middlewares + +Middlewares can be executed before or after a request, usually handled by the handlers. This will be useful for cases where an action is required prior to reaching the handler, or when an action is required to execute prior to the returning of the response. + +Middlewares require [Middy npm](https://www.npmjs.com/package/middy) to work. + +Middlewares should be written in the `src/middlewares/` directory. + +## Available Middlewares + +Lesgo! comes with pre-existing middlewares. + +- [HTTP Middlewares](/lesgo-docs/basics/middlewares/http) +- [Event Parsing Middlewares](/lesgo-docs/basics/middlewares/event-parsing) +- [Auth Middlewares](/lesgo-docs/basics/middlewares/auth) + +You may also import other ready-made middlewares from the [Middy repository](https://www.npmjs.com/package/middy#available-middlewares). + +## Custom Middlewares + +You can write your own custom middleware with [Middy](https://www.npmjs.com/package/middy#writing-a-middleware). diff --git a/mkdocs.yml b/mkdocs.yml index 3c9efeb..ed3e110 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,7 +53,11 @@ nav: - Deployment: getting-started/deployment.md - Available Scripts: getting-started/available-scripts.md - The Basics: - - Middleware: basics/middleware.md + - Middlewares: + - Introduction: basics/middlewares/introduction.md + - HTTP Middlewares: basics/middlewares/http.md + - Event Parsing Middlewares: basics/middlewares/event-parsing.md + - Auth Middlewares: basics/middlewares/auth.md - Error Handling: basics/error-handling.md - Logging: basics/logging.md - Digging Deeper: From e0dd9e91eb5de83ea3f67ae830710a771f90c8d1 Mon Sep 17 00:00:00 2001 From: xXLXx Date: Sat, 23 Jul 2022 14:18:58 +0800 Subject: [PATCH 3/4] feat: update description for client auth middleware --- docs/basics/middlewares/auth.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/basics/middlewares/auth.md b/docs/basics/middlewares/auth.md index afa6ea9..bb7b303 100644 --- a/docs/basics/middlewares/auth.md +++ b/docs/basics/middlewares/auth.md @@ -47,6 +47,9 @@ handler.use(verifyJwtTokenMiddleware()); This middleware will verify any basic auth passed to the `Authorization` header of the http request. Throws `Middlewares/basicAuthMiddleware::AUTH_INVALID_CLIENT_OR_SECRET_KEY` when a basic auth cannot be found in the clients list configuration. +This middleware can be used together with `clientAuthMiddleware`, as long as `clientAuthMiddleware` is declared first. +This is to allow the middleware to identify the matched `handler.event.platform`. + **Configuration** The basic auth configuration for your application is located at `src/config/client.js`. Or copy [this file](https://raw.githubusercontent.com/reflex-media/lesgo/master/src/config/client.js) to that path. @@ -68,9 +71,6 @@ handler.use(basicAuthMiddleware()); // or handler.use(basicAuthMiddleware({ - // When set to false, disables throwing on failure - blacklistMode: false, - // This is set as an override for Config/client.js when needed client: { myApp: { @@ -83,7 +83,7 @@ handler.use(basicAuthMiddleware({ ## Client Auth -This middleware will verify key passed to `x-client-id` header of the http request and sets the match to `handler.event.platform`. Throws `Middlewares/clientAuthMiddleware::INVALID_CLIENT_ID` when a basic auth cannot be found in the clients list configuration. +This middleware will verify key passed to `x-client-id` header of the http request and sets the matched key to `handler.event.platform`. Throws `Middlewares/clientAuthMiddleware::INVALID_CLIENT_ID` when a basic auth cannot be found in the clients list configuration. **Configuration** From 6a561a0bc60440809f28e4ec4e1a731fa36363fd Mon Sep 17 00:00:00 2001 From: xXLXx Date: Tue, 16 Aug 2022 16:39:28 +0800 Subject: [PATCH 4/4] feat: update docs for new options added to lesgo --- docs/basics/middlewares/auth.md | 2 +- docs/basics/middlewares/http.md | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/basics/middlewares/auth.md b/docs/basics/middlewares/auth.md index bb7b303..fc2c7aa 100644 --- a/docs/basics/middlewares/auth.md +++ b/docs/basics/middlewares/auth.md @@ -2,7 +2,7 @@ These middlewares can be utilized as a layer of authentication before going thro ## Verify JWT -This middleware will verify any JWT passed to the `Authorization` header of the http request. The decoded JWT can be accesed through `handler.event.decodedJwt`. If the JWT is verified, `handler.event.auth.sub` is set to the JWT's sub, else a `403` response will be thrown. +This middleware will verify any JWT passed to the `Authorization` header of the http request. If the JWT is verified, the decoded JWT can be accesed through `handler.event.decodedJwt`, else a `403` response will be thrown. **Configuration** diff --git a/docs/basics/middlewares/http.md b/docs/basics/middlewares/http.md index b026e60..672b9fa 100644 --- a/docs/basics/middlewares/http.md +++ b/docs/basics/middlewares/http.md @@ -54,6 +54,35 @@ The successfuly response will be formatted in this way } ``` +#### Custom Response + +Or you can override the response by passing a function +```js +handler.use(httpMiddleware({ + formatError: (options) => { + return JSON.stringify({ + status: 'error', + data: null, + error: { + code: options.error.code || 'UNHANDLED_ERROR', + message: options.error.name + ? `${options.error.name}: ${options.error.message}` + : options.error.message || options.error, + details: options.error.extra || '', + }, + _meta: options.debugMode ? options.event : {}, + }); + }, + formatSuccess: (options) => { + return JSON.stringify({ + status: 'success', + data: options.response, + _meta: options.debugMode ? options.event : {}, + }) + } +})); +``` + ## Http No Output This middleware normalizes all HTTP requests, handles, and formats success and error responses to make sure it always returns a success 200 with no body. @@ -71,4 +100,30 @@ const originalHandler = event => { export const handler = middy(originalHandler); handler.use(httpNoOutputMiddleware()); +``` + +**Enabling Output** + +By default, a response will be returned when debug is turned on either by passing `debug=1` as a query parameter such as: + +``` +http://my.api.com/v1/upload?debug=1 +``` + +or by passing `debugMode` as an option such as: + +```js +handler.use(httpNoOutputMiddleware({ + debugMode: true +})); +``` + +But this can be overriden by passing `allowResponse` as an option + +```js +handler.use(httpNoOutputMiddleware({ + allowResponse: (options) => { + return false; + } +})); ``` \ No newline at end of file