{
  "name": "CrudApiGetId",
  "nodes": [
    {
      "parameters": {
        "jsCode": "const item = $input.item;\n\nif(item.json === undefined || item.json === null){\n  item.json = {};\n}\n\n\nconst crypto = require('crypto');\n\nconst secretKey = 'seu-segredo-secreto';\n\n\nfunction base64UrlDecode(data) {\n  let base64 = data.replace(/-/g, '+').replace(/_/g, '/');\n  \n  while (base64.length % 4) {\n    base64 += '=';\n  }\n  return Buffer.from(base64, 'base64').toString('utf8');\n}\n\n\ntry {\n  \n  const authHeader = $json.headers['authorization'];\n\n  if (!authHeader || !authHeader.startsWith('Bearer ')) {\n    throw new Error('Authorization header missing or invalid');\n  }\n\n \n  const token = authHeader.split(' ')[1];\n\n  \n  const [encodedHeader, encodedPayload, signature] = token.split('.');\n\n  if (!encodedHeader || !encodedPayload || !signature) {\n    throw new Error('Invalid token format');\n  }\n\n \n  const dataToSign = `${encodedHeader}.${encodedPayload}`;\n  const expectedSignature = crypto\n    .createHmac('sha256', secretKey)\n    .update(dataToSign)\n    .digest('base64url');\n\n  \n  const sigBuffer = Buffer.from(signature, 'base64url');\n  const expectedSigBuffer = Buffer.from(expectedSignature, 'base64url');\n\n  if (sigBuffer.length !== expectedSigBuffer.length || !crypto.timingSafeEqual(sigBuffer, expectedSigBuffer)) {\n    throw new Error('Invalid signature');\n  }\n\n  \n  const payload = JSON.parse(base64UrlDecode(encodedPayload));\n  const nowInSeconds = Math.floor(Date.now() / 1000);\n\n  if (payload.exp < nowInSeconds) {\n    throw new Error('Token has expired');\n  }\n\n \n  item.json.auth_user = payload;\n  item.json.isValid = true;\n\n} catch (Error) {\n\n  item.json.isValid = false;\n  item.json.errorDetails = Error.message;\n}\n\nreturn item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        64,
        0
      ],
      "id": "31eeb6ac-1626-431a-8d75-b4196ed40bff",
      "name": "token_Validation",
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "953bbc3b-1c4c-47eb-bd04-bf466211ddf1",
              "leftValue": "={{ $json.isValid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        240,
        0
      ],
      "id": "2f417964-0fb8-4d01-960c-2b614238accd",
      "name": "token_Is_Valid"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"type\": \"https://example.com/probs/internal-error\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"Ocorreu um erro interno inesperado ao processar sua solicita\u00e7\u00e3o.\",\n  \"instance\": \"/api/messages/:id\",\n  \"request_id\": \"req_xyz987\"\n}",
        "options": {
          "responseCode": 500
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        240,
        176
      ],
      "id": "849022c9-6fc6-42c5-965a-899a8e1710e9",
      "name": "error_500"
    },
    {
      "parameters": {
        "jsCode": "const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\nconst returnItems = [];\n\nfor (const item of $input.all()) {\n  try {\n    if (item.json === undefined || item.json === null) {\n      item.json = {};\n    }\n    \n    const id = item.json.params.id;\n    \n    if (!id || !uuidRegex.test(id)) {\n      item.json.id_validation_error = {\n          type: \"https://example.com/probs/invalid-parameter\",\n          title: \"Invalid Parameter\",\n          status: 400, \n          detail: \"The 'id' parameter in the URL is missing or not a valid UUID.\",\n          instance: item.json.webhookUrl || 'webhookUrl_not_found'\n      };\n    } else {\n      item.json.id_validation_error = null;\n    }\n    \n  } catch (error) {\n    item.json.id_validation_error = {\n        type: \"https://example.com/probs/internal-error\",\n        title: \"Internal Server Error\",\n        status: 500,\n        detail: \"An unexpected error occurred during ID validation: \" + error.message\n    };\n  }\n  \n  returnItems.push(item);\n}\n\nreturn returnItems;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        416,
        0
      ],
      "id": "1ec75ef2-8a12-4092-a13e-7b0dc317ce08",
      "name": "id_Validation",
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n\"title\": \"unauthorized\",\n\"status\": 401,\n\"detail\": \"invalid or expired token\"\n}",
        "options": {
          "responseCode": 401
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        416,
        176
      ],
      "id": "989bd47f-c7e6-444d-a0d5-686f85bbeeb2",
      "name": "error_401"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "b0f6aaeb-31b6-4938-95fc-96aa583810a9",
              "leftValue": "={{ $json.id_validation_error }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        608,
        0
      ],
      "id": "5a4e3d52-d843-447d-bf1c-c0e7919e8267",
      "name": "id_Validation_Error_Is_Not_Empty"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"type\": \"https://example.com/probs/internal-error\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"Ocorreu um erro interno inesperado ao processar sua solicita\u00e7\u00e3o.\",\n  \"instance\": \"/api/messages/:id\",\n  \"request_id\": \"req_xyz987\"\n}",
        "options": {
          "responseCode": 500
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        608,
        176
      ],
      "id": "f39b357e-470f-442c-9476-d8cceeb1189c",
      "name": "error_500_"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "Select * from messages where id = &1 Limit 1",
        "options": {
          "queryReplacement": "={{ $json.params.id }}"
        }
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        816,
        0
      ],
      "id": "dffeb86a-4aa7-491a-805d-a18770ca8664",
      "name": "Execute a SQL query",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"status\": \"200\",\n  \"title\": \"success\"\n}",
        "options": {
          "responseCode": 200
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        976,
        0
      ],
      "id": "ac9f8633-97c0-4946-859f-0ccd5dda6253",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "httpMethod": "={{ $request.method === 'OPTIONS' ? 'OPTIONS' : 'GET' }}",
        "path": "api/messages-detail/:id",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -272,
        0
      ],
      "id": "c5a35507-7a09-499c-b8c6-b1e3dcba5134",
      "name": "Webhook"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "d8fedf0d-f825-4996-8f31-efa5cb2cf795",
              "leftValue": "={{ $json.httpMethod }}",
              "rightValue": "OPTIONS",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -112,
        0
      ],
      "id": "c16fc494-ba7c-4173-be7d-33088cc2df10",
      "name": "http_Method_Is_Option"
    },
    {
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "http://localhost:5173"
              },
              {
                "name": "Access-Control-Allow-Methods",
                "value": "GET, POST, PUT, DELETE, PATCH, OPTIONS"
              },
              {
                "name": "Access-Control-Allow-Headers",
                "value": "Authorization, Content-Type, Accept"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        64,
        176
      ],
      "id": "77305238-049f-4bd2-afed-c4831808e5f0",
      "name": "response_Headers_Cors"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n\"type\": \"https://example.com/probs/invalid-input\",\n  \"title\": \"Invalid input\",\n  \"status\": 400,\n  \"detail\": \"One or more fields failed validation\",\n  \"instance\": \"/api/messages\"\n}",
        "options": {
          "responseCode": 400
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        816,
        176
      ],
      "id": "460a9c40-b65d-4c92-b437-8f8777488653",
      "name": "error_400"
    }
  ],
  "connections": {
    "token_Validation": {
      "main": [
        [
          {
            "node": "token_Is_Valid",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error_500",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "token_Is_Valid": {
      "main": [
        [
          {
            "node": "id_Validation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error_401",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "id_Validation": {
      "main": [
        [
          {
            "node": "id_Validation_Error_Is_Not_Empty",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error_500_",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "id_Validation_Error_Is_Not_Empty": {
      "main": [
        [
          {
            "node": "error_400",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Execute a SQL query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute a SQL query": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "http_Method_Is_Option",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "http_Method_Is_Option": {
      "main": [
        [
          {
            "node": "response_Headers_Cors",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "token_Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a9a9a093-739f-4d1f-b578-287722afce84",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "Sjbcvh4t0XR6msMx",
  "tags": []
}