Repository: RaposoG/key-haven-back
Pull request #16: feat(docs): Adicionado multi docs [scalar, redoc, swagger]
Author: login: MatheusVp2
Created: 2025-03-20T13:08:19Z | Merged: 2025-03-20T14:04:04Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Novos Recursos / Documentação**
  - Foram adicionadas novas rotas que integram a documentação da API. Agora, os usuários podem acessar interfaces interativas (incluindo visualizações inspiradas em Swagger, Redoc e Scalar) para consultar as especificações da API e suas funcionalidades.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/go.mod b/go.mod
index ac6c9a1..c78dcf8 100644
--- a/go.mod
+++ b/go.mod
@@ -7,47 +7,46 @@ require (
 	github.com/MarceloPetrucio/go-scalar-api-reference v0.0.0-20240521013641-ce5d2efe0e06
 	github.com/go-playground/validator/v10 v10.25.0
 	github.com/gofiber/fiber/v3 v3.0.0-beta.4
-	github.com/golang-jwt/jwt/v5 v5.2.1
 	github.com/google/uuid v1.6.0
 	github.com/joho/godotenv v1.5.1
 	github.com/redis/go-redis/v9 v9.7.1
+	github.com/swaggo/swag v1.16.4
 	go.mongodb.org/mongo-driver v1.17.3
 	go.uber.org/fx v1.23.0
 	golang.org/x/crypto v0.36.0
 )
 
-// Add other dependencies as needed
-
-require github.com/swaggo/swag v1.16.4
-
 require (
 	aidanwoods.dev/go-result v0.3.1 // indirect
 	github.com/KyleBanks/depth v1.2.1 // indirect
+	github.com/PuerkitoBio/purell v1.1.1 // indirect
+	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
 	github.com/andybalholm/brotli v1.1.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.8 // indirect
-	github.com/go-openapi/jsonpointer v0.21.1 // indirect
-	github.com/go-openapi/jsonreference v0.21.0 // indirect
-	github.com/go-openapi/spec v0.21.0 // indirect
-	github.com/go-openapi/swag v0.23.1 // indirect
+	github.com/go-openapi/jsonpointer v0.19.5 // indirect
+	github.com/go-openapi/jsonreference v0.19.6 // indirect
+	github.com/go-openapi/spec v0.20.4 // indirect
+	github.com/go-openapi/swag v0.19.15 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect
-	github.com/gofiber/schema v1.3.0 // indirect
+	github.com/gofiber/schema v1.2.0 // indirect
 	github.com/gofiber/utils/v2 v2.0.0-beta.7 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
-	github.com/klauspost/compress v1.18.0 // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/leodido/go-urn v1.4.0 // indirect
-	github.com/mailru/easyjson v0.9.0 // indirect
-	github.com/mattn/go-colorable v0.1.14 // indirect
+	github.com/mailru/easyjson v0.7.6 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/montanaflynn/stats v0.7.1 // indirect
 	github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
 	github.com/tinylib/msgp v1.2.5 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
-	github.com/valyala/fasthttp v1.59.0 // indirect
+	github.com/valyala/fasthttp v1.58.0 // indirect
+	github.com/valyala/tcplisten v1.0.0 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
@@ -56,10 +55,10 @@ require (
 	go.uber.org/dig v1.18.0 // indirect
 	go.uber.org/multierr v1.10.0 // indirect
 	go.uber.org/zap v1.26.0 // indirect
-	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/net v0.34.0 // indirect
 	golang.org/x/sync v0.12.0 // indirect
 	golang.org/x/sys v0.31.0 // indirect
 	golang.org/x/text v0.23.0 // indirect
-	golang.org/x/tools v0.31.0 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
+	golang.org/x/tools v0.22.0 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 638127c..fbcb2ca 100644
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,10 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc
 github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
 github.com/MarceloPetrucio/go-scalar-api-reference v0.0.0-20240521013641-ce5d2efe0e06 h1:W4Yar1SUsPmmA51qoIRb174uDO/Xt3C48MB1YX9Y3vM=
 github.com/MarceloPetrucio/go-scalar-api-reference v0.0.0-20240521013641-ce5d2efe0e06/go.mod h1:/wotfjM8I3m8NuIHPz3S8k+CCYH80EqDT8ZeNLqMQm0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
 github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
 github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
@@ -14,6 +18,8 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
 github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
@@ -22,14 +28,16 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv
 github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
 github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
 github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
-github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
-github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
-github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
-github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
-github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
-github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
-github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
-github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
+github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
+github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
+github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
+github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -40,12 +48,10 @@ github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0
 github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
 github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
 github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
-github.com/gofiber/schema v1.3.0 h1:K3F3wYzAY+aivfCCEHPufCthu5/13r/lzp1nuk6mr3Q=
-github.com/gofiber/schema v1.3.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
+github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
+github.com/gofiber/schema v1.2.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
 github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ=
 github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
-github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
-github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
@@ -56,30 +62,37 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
 github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
-github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
-github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
-github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
-github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
-github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
 github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
 github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
-github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
@@ -88,8 +101,10 @@ github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
 github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI=
-github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU=
+github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
+github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
+github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
+github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@@ -120,22 +135,25 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
 golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
-golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
-golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
+golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
 golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
 golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
@@ -143,6 +161,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
@@ -150,11 +169,17 @@ golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
-golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/middleware/handler.go b/internal/middleware/handler.go
index 9361abf..565998f 100644
--- a/internal/middleware/handler.go
+++ b/internal/middleware/handler.go
@@ -1,7 +1,7 @@
 package middleware
 
 import (
-	"key-haven-back/pkg/crypto"
+	"key-haven-back/pkg/secret"
 
 	"github.com/gofiber/fiber/v3"
 )
@@ -23,9 +23,9 @@ func IsAuthenticatedHandler(c fiber.Ctx) error {
 	}
 
 	// Validate token
-	claims, err := crypto.ValidateToken(tokenJwt)
+	claims, err := secret.ValidateToken(tokenJwt)
 	if err != nil {
-		if err == crypto.ErrTokenExpired {
+		if err == secret.ErrTokenExpired {
 			return c.Status(401).JSON(fiber.Map{
 				"message": "Token expired",
 			})
diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go
index bc8fd28..4722ec5 100644
--- a/internal/service/auth_service.go
+++ b/internal/service/auth_service.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"key-haven-back/internal/model"
 	"key-haven-back/internal/repository"
-	"key-haven-back/pkg/crypto"
+	"key-haven-back/pkg/secret"
 	"time"
 )
 
@@ -36,12 +36,12 @@ func (s *authService) Login(ctx context.Context, request *model.LoginRequest) (*
 		return nil, err
 	}
 
-	valid, err := crypto.VerifyPassword(user.Password, request.Password)
+	valid, err := secret.VerifyPassword(user.Password, request.Password)
 	if err != nil || !valid {
 		return nil, repository.ErrInvalidCredentials
 	}
 
-	token, err := crypto.GenerateToken(user.ID, user.Email, 24*time.Hour)
+	token, err := secret.GenerateToken(user.ID, user.Email, 24*time.Hour)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/service/user_service.go b/internal/service/user_service.go
index 1ab0fc9..600cbe0 100644
--- a/internal/service/user_service.go
+++ b/internal/service/user_service.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"key-haven-back/internal/model"
 	"key-haven-back/internal/repository"
-	"key-haven-back/pkg/crypto"
+	"key-haven-back/pkg/secret"
 )
 
 // UserService defines the interface for user-related operations
@@ -33,7 +33,7 @@ func (s *userService) CreateUser(ctx context.Context, request *model.CreateUserR
 	user := model.NewUser(request)
 
 	// Hash the password
-	hashedPassword, err := crypto.HashPassword(request.Password)
+	hashedPassword, err := secret.HashPassword(request.Password)
 	if err != nil {
 		return nil, err
 	}
@@ -68,7 +68,7 @@ func (s *userService) GetUserByEmail(ctx context.Context, email string) (*model.
 
 // UpdatePassword updates a user's password
 func (s *userService) UpdatePassword(ctx context.Context, userID, password string) error {
-	hashedPassword, err := crypto.HashPassword(password)
+	hashedPassword, err := secret.HashPassword(password)
 	if err != nil {
 		return err
 	}
diff --git a/main.go b/main.go
index f32991c..39fd0f5 100644
--- a/main.go
+++ b/main.go
@@ -8,6 +8,7 @@ import (
 	"key-haven-back/internal/repository"
 	"key-haven-back/internal/router"
 	"key-haven-back/internal/service"
+	"key-haven-back/pkg/docs"
 	error_handler "key-haven-back/pkg/error"
 	"key-haven-back/pkg/validator"
 	"log"
@@ -72,6 +73,7 @@ func main() {
 	// Authentication routes
 	router.RegisterRoutes(app, authHandler)
 	router.RegisterSwaggerRoutes(app)
+	docs.RegisterDocsRouter(app)
 
 	// Start the server
 	log.Fatal(app.Listen(":8080"))
diff --git a/pkg/docs/handler.go b/pkg/docs/handler.go
new file mode 100644
index 0000000..567e8a1
--- /dev/null
+++ b/pkg/docs/handler.go
@@ -0,0 +1,55 @@
+package docs
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"os"
+	"path"
+
+	"github.com/gofiber/fiber/v3"
+)
+
+type Provider struct {
+	Url  string
+	Name string
+}
+
+func RegisterDocsRouter(app *fiber.App) {
+	app.Get("/public/openapi.json", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+		filename := path.Join(dir, "pkg", "docs", "swagger.json")
+		return ctx.SendFile(filename)
+	})
+
+	app.Get("/docs", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+
+		name := ctx.Query("name", "scalar")
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		tmpl, err := template.ParseFiles(filename)
+		if err != nil {
+			fmt.Println("ParseFiles error")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
+		}
+
+		provider := &Provider{
+			Url:  "http://localhost:8080/public/openapi.json",
+			Name: name,
+		}
+
+		var bufferHtml bytes.Buffer
+		if err := tmpl.Execute(&bufferHtml, provider); err != nil {
+			fmt.Println("Execute Replace Text")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
+		}
+
+		return ctx.Type("html").SendString(bufferHtml.String())
+	})
+}
diff --git a/pkg/docs/redoc.html b/pkg/docs/redoc.html
new file mode 100644
index 0000000..d518653
--- /dev/null
+++ b/pkg/docs/redoc.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>Redoc</title>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
+
+    <style>
+        body {
+            margin: 0;
+            padding: 0;
+        }
+    </style>
+</head>
+
+<body>
+    <redoc spec-url='{{.Url}}'></redoc>
+    <script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/pkg/docs/scalar.html b/pkg/docs/scalar.html
new file mode 100644
index 0000000..bd137dd
--- /dev/null
+++ b/pkg/docs/scalar.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+
+<head>
+    <title>Scalar API Reference</title>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+</head>
+
+<body>
+    <div id="app"></div>
+
+    <!-- Load the Script -->
+    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
+
+    <!-- Initialize the Scalar API Reference -->
+    <script>
+        Scalar.createApiReference('#app', {
+            url: '{{.Url}}',
+            proxyUrl: 'https://proxy.scalar.com',
+        })
+    </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/pkg/docs/swagger.html b/pkg/docs/swagger.html
new file mode 100644
index 0000000..86e430d
--- /dev/null
+++ b/pkg/docs/swagger.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta name="description" content="SwaggerUI" />
+    <title>SwaggerUI</title>
+    <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
+</head>
+
+<body>
+    <div id="swagger-ui"></div>
+    <script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
+    <script>
+        window.onload = () => {
+            window.ui = SwaggerUIBundle({
+                url: '{{.Url}}',
+                dom_id: '#swagger-ui',
+            });
+        };
+    </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/pkg/docs/swagger.json b/pkg/docs/swagger.json
new file mode 100644
index 0000000..458fb75
--- /dev/null
+++ b/pkg/docs/swagger.json
@@ -0,0 +1,235 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "description": "This is the API for Key Haven",
+        "title": "Key Haven API",
+        "contact": {},
+        "version": "1.0"
+    },
+    "host": "localhost:8080",
+    "basePath": "/",
+    "paths": {
+        "/auth/login": {
+            "post": {
+                "description": "Authenticates a user and returns a token",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "User login",
+                "parameters": [
+                    {
+                        "description": "User login data",
+                        "name": "request",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/model.LoginRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/model.LoginResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid request body",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Invalid email or password",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal server error",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/auth/logout": {
+            "post": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "description": "Logs out the user by clearing the authentication cookie",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "User logout",
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/handler.MessageResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/auth/register": {
+            "post": {
+                "description": "Creates a new user account",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "Register a new user",
+                "parameters": [
+                    {
+                        "description": "User registration data",
+                        "name": "request",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/model.CreateUserRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "Created",
+                        "schema": {
+                            "$ref": "#/definitions/model.User"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid request body",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "409": {
+                        "description": "Email already in use",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal server error",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "handler.ErrorResponse": {
+            "type": "object",
+            "properties": {
+                "message": {
+                    "type": "string"
+                }
+            }
+        },
+        "handler.MessageResponse": {
+            "type": "object",
+            "properties": {
+                "message": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.CreateUserRequest": {
+            "type": "object",
+            "required": [
+                "email",
+                "firstName",
+                "password"
+            ],
+            "properties": {
+                "email": {
+                    "type": "string"
+                },
+                "firstName": {
+                    "type": "string"
+                },
+                "password": {
+                    "type": "string",
+                    "minLength": 12
+                }
+            }
+        },
+        "model.LoginRequest": {
+            "type": "object",
+            "required": [
+                "email",
+                "password"
+            ],
+            "properties": {
+                "email": {
+                    "type": "string"
+                },
+                "password": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.LoginResponse": {
+            "type": "object",
+            "properties": {
+                "token": {
+                    "type": "string"
+                },
+                "user": {
+                    "$ref": "#/definitions/model.User"
+                }
+            }
+        },
+        "model.User": {
+            "type": "object",
+            "properties": {
+                "created_at": {
+                    "type": "string"
+                },
+                "email": {
+                    "type": "string"
+                },
+                "first_name": {
+                    "type": "string"
+                },
+                "id": {
+                    "type": "string"
+                },
+                "last_login_at": {
+                    "type": "string"
+                },
+                "updated_at": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/pkg/crypto/argon.go b/pkg/secret/argon.go
similarity index 99%
rename from pkg/crypto/argon.go
rename to pkg/secret/argon.go
index 051872d..9c04d99 100644
--- a/pkg/crypto/argon.go
+++ b/pkg/secret/argon.go
@@ -1,4 +1,4 @@
-package crypto
+package secret
 
 import (
 	"crypto/rand"
diff --git a/pkg/secret/authenticator.go b/pkg/secret/authenticator.go
deleted file mode 100644
index a9135d6..0000000
--- a/pkg/secret/authenticator.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package secret
-
-import (
-	"key-haven-back/config"
-	"time"
-
-	"github.com/golang-jwt/jwt/v5"
-)
-
-func makeClaims(userID string, roles []string) jwt.MapClaims {
-	return jwt.MapClaims{
-		"sub":   userID,
-		"roles": roles,
-		"exp":   time.Now().Add(time.Minute * 15).Unix(),
-	}
-}
-
-func CreateJwtToken(userID string, roles []string) (string, error) {
-	secret := config.GetEnvOrDefault("JWT_SECRET", "secret")
-	claims := makeClaims(userID, roles)
-	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
-	return token.SignedString([]byte(secret))
-}
-
-func ParseJwtToken(tokenString string, claims jwt.Claims) error {
-	secret := config.GetEnvOrDefault("JWT_SECRET", "secret")
-	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
-		return []byte(secret), nil
-	})
-
-	if err != nil {
-		return err
-	}
-
-	if !token.Valid {
-		return jwt.ErrSignatureInvalid
-	}
-
-	return nil
-}
diff --git a/pkg/crypto/paseto.go b/pkg/secret/paseto.go
similarity index 99%
rename from pkg/crypto/paseto.go
rename to pkg/secret/paseto.go
index 522b192..38f04b2 100644
--- a/pkg/crypto/paseto.go
+++ b/pkg/secret/paseto.go
@@ -1,4 +1,4 @@
-package crypto
+package secret
 
 import (
 	"crypto/rand"
diff --git a/pkg/secret/password.go b/pkg/secret/password.go
deleted file mode 100644
index d433c37..0000000
--- a/pkg/secret/password.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package secret
-
-import (
-	"fmt"
-
-	"golang.org/x/crypto/bcrypt"
-)
-
-func HashPassword(password string) (string, error) {
-	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
-	if err != nil {
-		return "", fmt.Errorf("error hashing password: %w", err)
-	}
-	return string(hashedPassword), nil
-}
-
-func ComparePassword(hashedPassword, password string) error {
-	return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
-}


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 6**

<details>
<summary>🔭 Outside diff range comments (2)</summary><blockquote>

<details>
<summary>pkg/docs/swagger.go (1)</summary><blockquote>

`1-2`: _🛠️ Refactor suggestion_

**Arquivo com declaração de pacote vazia.**

Este arquivo contém apenas a declaração do pacote `docs` sem nenhuma implementação. Embora isso não seja um erro técnico, é considerado uma prática ruim ter arquivos quase vazios no projeto.

Recomendações:
1. Adicione documentação explicando o propósito deste arquivo
2. Implemente as funções relacionadas ao Swagger neste arquivo
3. Ou combine-o com outros arquivos relacionados no pacote docs

A modularidade é importante, mas arquivos vazios comprometem a manutenção do código.

</blockquote></details>
<details>
<summary>pkg/docs/redoc.go (1)</summary><blockquote>

`1-2`: _🛠️ Refactor suggestion_

**Arquivo com declaração de pacote vazia.**

Este arquivo contém apenas a declaração do pacote `docs` sem nenhuma implementação. Assim como o arquivo swagger.go, este padrão compromete a organização do código.

Recomendações:
1. Adicione documentação explicando o propósito específico deste arquivo
2. Implemente as funções relacionadas ao Redoc neste arquivo
3. Ou considere consolidar a funcionalidade em um único arquivo no pacote docs

Arquivos vazios aumentam a complexidade desnecessária do projeto e dificultam a manutenção.

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (6)</summary><blockquote>

<details>
<summary>pkg/secret/argon.go (1)</summary><blockquote>

`52-91`: **Implementação da função VerifyPassword**  
A função realiza a verificação do hash utilizando comparação em tempo constante, seguindo boas práticas de segurança. Recomenda-se ampliar a cobertura de testes unitários para cenários de sucesso e falha.

</blockquote></details>
<details>
<summary>pkg/secret/paseto.go (1)</summary><blockquote>

`94-138`: **Implementação da função ValidateToken**  
A função valida o token e extrai os claims de forma adequada. Note que a verificação do erro de expiração depende de uma string literal ("token has expired"), o que pode ser vulnerável a mudanças futuras.

</blockquote></details>
<details>
<summary>pkg/docs/swagger.html (1)</summary><blockquote>

`1-25`: **Documento HTML para SwaggerUI**  
A estrutura do HTML está consistente com as necessidades do Swagger UI, integrando os estilos e scripts externos de forma correta. Recomenda-se adicionar uma nova linha ao final do arquivo para cumprir as convenções de formatação do código.

</blockquote></details>
<details>
<summary>pkg/docs/swagger.json (1)</summary><blockquote>

`181-182`: **Boa prática de validação de senha**

A definição de um comprimento mínimo de 12 caracteres para senhas é uma excelente prática de segurança. Considere adicionar validações adicionais para garantir senhas fortes.


Considere adicionar mais validações para garantir senhas mais fortes:

```diff
"password": {
    "type": "string",
-   "minLength": 12
+   "minLength": 12,
+   "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{12,}$",
+   "description": "Senha deve conter pelo menos 12 caracteres, incluindo uma letra maiúscula, uma letra minúscula, um número e um caractere especial"
}
```

</blockquote></details>
<details>
<summary>pkg/docs/handler.go (2)</summary><blockquote>

`13-16`: **Melhore a nomenclatura e documentação da estrutura Provider.**

A estrutura `Provider` está exportada, mas carece de comentários de documentação. Além disso, o campo `Url` deveria ser escrito como `URL` de acordo com as convenções de nomenclatura Go para acrônimos.


```diff
-type Provider struct {
-	Url  string
-	Name string
-}
+// Provider contém informações necessárias para renderizar a documentação API
+type Provider struct {
+	URL  string
+	Name string
+}
```

---

`18-55`: **Refatore os handlers anônimos em funções nomeadas.**

Os manipuladores de rota atuais são definidos como funções anônimas longas, diminuindo a legibilidade e dificultando a manutenção do código. Extrair para funções nomeadas melhoraria significativamente a organização do código.


Considere refatorar as funções anônimas em funções nomeadas:

```go
func RegisterDocsRouter(app *fiber.App) {
	app.Get("/public/openapi.json", serveOpenAPIJSON)
	app.Get("/docs", serveDocs)
}

func serveOpenAPIJSON(ctx fiber.Ctx) error {
	dir, err := os.Getwd()
	if err != nil {
		return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
	}
	filename := path.Join(dir, "pkg", "docs", "swagger.json")
	return ctx.SendFile(filename)
}

func serveDocs(ctx fiber.Ctx) error {
	// Implementação atual da função de documentação
	// ...
}
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 5e98611672d029c63f6dcf75182ec66786978737 and e4002a29a6de4fa272a25f7c0d79717eef4a3666.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `go.sum` is excluded by `!**/*.sum`

</details>

<details>
<summary>📒 Files selected for processing (17)</summary>

* `go.mod` (2 hunks)
* `internal/middleware/handler.go` (2 hunks)
* `internal/service/auth_service.go` (2 hunks)
* `internal/service/user_service.go` (3 hunks)
* `main.go` (2 hunks)
* `pkg/docs/handler.go` (1 hunks)
* `pkg/docs/redoc.go` (1 hunks)
* `pkg/docs/redoc.html` (1 hunks)
* `pkg/docs/scalar.go` (1 hunks)
* `pkg/docs/scalar.html` (1 hunks)
* `pkg/docs/swagger.go` (1 hunks)
* `pkg/docs/swagger.html` (1 hunks)
* `pkg/docs/swagger.json` (1 hunks)
* `pkg/secret/argon.go` (1 hunks)
* `pkg/secret/authenticator.go` (0 hunks)
* `pkg/secret/paseto.go` (1 hunks)
* `pkg/secret/password.go` (0 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (2)</summary>

* pkg/secret/password.go
* pkg/secret/authenticator.go

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (1)</summary>

<details>
<summary>`**/*.*`: Seja extremamente rigoroso na revisão de código. 
Exija que os desenvolvedores sigam estritamente os melhores padrões de projeto. 
Assegure que o código seja de fácil lei...</summary>

> `**/*.*`: Seja extremamente rigoroso na revisão de código. 
> Exija que os desenvolvedores sigam estritamente os melhores padrões de projeto. 
> Assegure que o código seja de fácil leitura, com nomes de variáveis claros, descritivos e consistentes que reflitam suas funções. 
> Garanta o uso estrito do Go com tipagem explícita, evitando o uso desnecessário de interface{}. 
> Proíba funções aninhadas desnecessariamente. 
> Assegure a modularidade e a separação de responsabilidades. 
> Limite o número de parâmetros em funções; refatore para diminuir a complexidade quando necessário. 
> Proíba o uso de fmt.Println no código. 
> Evite nomes de variáveis genéricos como temp, data, item, test, teste; prefira nomes que descrevam claramente o propósito da variável.
> 

- `pkg/docs/scalar.go`
- `pkg/docs/swagger.go`
- `pkg/docs/redoc.go`
- `pkg/secret/argon.go`
- `pkg/docs/scalar.html`
- `pkg/secret/paseto.go`
- `pkg/docs/redoc.html`
- `internal/service/auth_service.go`
- `main.go`
- `internal/middleware/handler.go`
- `internal/service/user_service.go`
- `pkg/docs/swagger.json`
- `pkg/docs/swagger.html`
- `pkg/docs/handler.go`
- `go.mod`

</details>

</details><details>
<summary>🧬 Code Definitions (3)</summary>

<details>
<summary>main.go (1)</summary><blockquote>

<details>
<summary>pkg/docs/handler.go (1) (1)</summary>

* `RegisterDocsRouter` (18-55)

</details>

</blockquote></details>
<details>
<summary>internal/middleware/handler.go (1)</summary><blockquote>

<details>
<summary>pkg/secret/paseto.go (2) (2)</summary>

* `ValidateToken` (95-138)
* `ErrTokenExpired` (17-17)

</details>

</blockquote></details>
<details>
<summary>internal/service/user_service.go (1)</summary><blockquote>

<details>
<summary>pkg/secret/argon.go (1) (1)</summary>

* `HashPassword` (29-50)

</details>

</blockquote></details>

</details><details>
<summary>🪛 Checkov (3.2.334)</summary>

<details>
<summary>pkg/docs/swagger.json</summary>

[HIGH] 1-234: Ensure that security requirement defined in securityDefinitions - version 2.0 files

(CKV_OPENAPI_6)

---

[HIGH] 1-234: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

---

[HIGH] 1-234: Ensure that security operations is not empty.

(CKV_OPENAPI_5)

---

[HIGH] 1-234: Ensure that securityDefinitions is defined and not empty - version 2.0 files

(CKV_OPENAPI_1)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (22)</summary><blockquote>

<details>
<summary>pkg/secret/argon.go (2)</summary>

`1-1`: **Atualização do nome do pacote**  
A alteração de `package crypto` para `package secret` foi realizada corretamente, assegurando a consistência com a nova convenção de nomenclatura para funções de segurança.

---

`29-50`: **Implementação da função HashPassword**  
A função gera um salt aleatório e aplica o algoritmo Argon2id de forma segura, com uma formatação clara do hash retornado.

</details>
<details>
<summary>pkg/secret/paseto.go (4)</summary>

`1-1`: **Atualização do nome do pacote**  
A mudança de `package crypto` para `package secret` foi aplicada de forma consistente, alinhando-se com o novo padrão de segurança adotado no projeto.

---

`30-57`: **Função getOrCreateSymmetricKey**  
A função obtém ou gera uma chave simétrica de forma apropriada. Contudo, avalie o impacto de gerar uma nova chave como fallback, pois isso pode invalidar tokens existentes em ambiente de produção.

---

`59-92`: **Implementação da função GenerateToken**  
A função valida os parâmetros de entrada e configura corretamente os claims padrão e customizados para geração do token PASETO, garantindo segurança.

---

`140-149`: **Implementação da função RefreshToken**  
A função reutiliza os claims existentes para gerar um novo token com expiração atualizada, mantendo a simplicidade e clareza na reutilização da lógica.

</details>
<details>
<summary>pkg/docs/redoc.html (1)</summary>

`1-23`: **Documento HTML para Redoc**  
O arquivo HTML está bem estruturado e utiliza os recursos (como Google Fonts e estilos) de forma apropriada. Certifique-se que o placeholder `{{.Url}}` seja corretamente substituído pela URL da especificação durante a renderização.

</details>
<details>
<summary>pkg/docs/scalar.go (1)</summary>

`1-2`: **Novo pacote 'docs'**  
A declaração do novo pacote `docs` está correta. Como este arquivo inicia a organização dos recursos de documentação, planeje a adição de funções e rotas que sirvam os diferentes formatos de documentação de maneira modular e clara.

</details>
<details>
<summary>main.go (2)</summary>

`11-11`: **Importação adicionada corretamente.**

A importação do pacote `docs` está bem posicionada junto com os outros pacotes internos do projeto.

---

`76-76`: **Registro do roteador de documentação implementado adequadamente.**

A chamada para `docs.RegisterDocsRouter(app)` está posicionada corretamente após os registros de rotas de autenticação e Swagger.

Observação: O fluxo de execução está lógico, fornecendo acesso à documentação da API em múltiplos formatos (scalar, redoc, swagger) conforme os objetivos do PR.

</details>
<details>
<summary>internal/service/user_service.go (3)</summary>

`7-7`: **Refatoração de pacote de segurança.**

A alteração da importação de `crypto` para `secret` faz parte de uma refatoração mais ampla para centralizar funcionalidades criptográficas. Esta mudança melhora a organização do código.

---

`36-36`: **Atualização consistente da chamada de função de hash.**

A mudança de `crypto.HashPassword` para `secret.HashPassword` é consistente com a alteração da importação. A função continua utilizando o algoritmo Argon2id para hashing de senhas, mantendo a segurança do sistema.

---

`71-71`: **Função de hash atualizada consistentemente.**

A atualização da chamada de função neste ponto mantém a consistência em todo o serviço de usuário, garantindo que todas as operações de hash de senha utilizem o mesmo pacote `secret`.

</details>
<details>
<summary>internal/service/auth_service.go (3)</summary>

`7-7`: **Boa prática na troca do pacote de criptografia**

A alteração do pacote `crypto` para `secret` é uma mudança positiva que promove uma melhor organização do código, desde que o pacote `secret` mantenha as mesmas garantias de segurança.

---

`39-39`: **Verificação consistente de senha**

A alteração para `secret.VerifyPassword` mantém a funcionalidade original com uma organização de código mais clara.

---

`44-44`: **Geração de token consistente**

A mudança para `secret.GenerateToken` mantém a mesma assinatura e comportamento, o que é essencial para preservar a compatibilidade da API.

</details>
<details>
<summary>internal/middleware/handler.go (3)</summary>

`4-4`: **Migração consistente para o pacote secret**

A alteração do pacote `crypto` para `secret` mantém consistência com as outras mudanças no projeto, o que é uma boa prática de refatoração.

---

`26-26`: **Validação de token consistente**

A mudança para `secret.ValidateToken` mantém a mesma assinatura e comportamento da função original, garantindo compatibilidade com o restante do código.

---

`28-28`: **Tratamento de erro consistente**

A verificação correta do erro específico `secret.ErrTokenExpired` mantém o comportamento original da aplicação em relação a tokens expirados.

</details>
<details>
<summary>pkg/docs/swagger.json (1)</summary>

`66-70`: **Boa prática de segurança implementada**

A aplicação correta de requisitos de segurança no endpoint de logout é uma boa prática. Entretanto, é necessário definir o esquema de segurança correspondente conforme mencionado no comentário anterior.

</details>
<details>
<summary>go.mod (2)</summary>

`13-13`: **Adição apropriada de dependência para documentação Swagger.**

A adição da dependência `github.com/swaggo/swag` é apropriada para suportar a nova funcionalidade de documentação API. Certifique-se de que a utilização do pacote esteja alinhada com as melhores práticas.

---

`22-63`: <details>
<summary>✅ Verification successful</summary>

**Certifique-se de que as dependências indiretas estão sendo utilizadas corretamente.**

As várias dependências indiretas adicionadas para suporte à documentação OpenAPI são apropriadas, mas verifique se não há dependências redundantes ou desnecessárias que poderiam ser removidas para manter o projeto mais enxuto.


É recomendável verificar regularmente as dependências com `go mod tidy` para garantir que todas as dependências indiretas sejam necessárias:

---

🏁 Script executed:

```shell
#!/bin/bash
# Verificar e otimizar dependências
go mod tidy

# Exibir dependências atuais para revisão
go list -m all
```

Length of output: 6745

---



</details>

**Ação: Revisar dependências indiretas no go.mod**

Após a execução do `go mod tidy` e a verificação com `go list -m all`, foi constatado que as dependências indiretas listadas (linhas 22-63 no go.mod) estão devidamente gerenciadas e não há evidência de dependências redundantes ou desnecessárias. Mantenha a prática de usar o `go mod tidy` regularmente para preservar a limpeza e a eficiência do projeto.

- Confirmação de que as dependências necessárias para suporte à documentação OpenAPI estão sendo utilizadas corretamente.
- As dependências gerenciadas pelo go mod estão consistentes com o uso atual do projeto.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T13:15:47Z
user: login: vinirossado
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-20T13:19:55Z
user: login: lkgiovani
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-20T14:03:19Z
user: login: coderabbitai[bot]
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:03:52Z

Review comments:
diff_hunk: @@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+
+<head>
+    <title>Scalar API Reference</title>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+</head>
+
+<body>
+    <div id="app"></div>
+
+    <!-- Load the Script -->
+    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
+
+    <!-- Initialize the Scalar API Reference -->
+    <script>
+        Scalar.createApiReference('#app', {
+            url: '{{.Url}}',
+            proxyUrl: 'https://proxy.scalar.com',
+        })
+    </script>
+</body>
+
+</html>
path: pkg/docs/scalar.html
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Implementação adequada do Scalar API Reference**

A implementação do Scalar API Reference segue as boas práticas de HTML e carregamento de recursos externos. 

Alguns pontos a considerar:
1. O uso de CDN para carregamento do script é adequado, mas considere adicionar um atributo de integridade (SRI) para garantir que o script não seja alterado maliciosamente.
2. A template string `{{.Url}}` indica que este é um template que será processado pelo servidor.


Considere adicionar atributos de integridade SRI para o script externo:

```diff
-    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference" integrity="sha384-HASH_AQUI" crossorigin="anonymous"></script>
```

---

🌐 Web query:

```web
What is the latest integrity hash for @scalar/api-reference CDN?
```

💡 Result:

To determine the latest integrity hash for the `@scalar/api-reference` CDN script, you can generate it using Subresource Integrity (SRI) tools, as the current search results don't explicitly list updated hashes. Here's how to obtain/verify it:

1. **Retrieve the latest CDN URL**  
   The standard CDN script URL is:
   ```html
   <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
   ```

2. **Generate the SRI hash**  
   Calculate the hash using OpenSSL or online SRI generators. For example:
   ```bash
   curl -s https://cdn.jsdelivr.net/npm/@scalar/api-reference | openssl dgst -sha384 -binary | openssl base64 -A
   ```

3. **Validate with official sources**  
   Check the [jsDelivr package page](https://www.jsdelivr.com/package/npm/@scalar/api-reference)[10] or [cdnjs library page](https://cdnjs.com/libraries/scalar-api-reference)[12], which typically display SRI hashes for each version under "Copy SRI" buttons next to version listings.

**Note**: Integrity hashes change with every package update. Always:
- Use the SHA384 algorithm (recommended balance of security/performance)[2]
- Ensure HTTPS is used for CDN resources
- Regularly update hashes when upgrading versions

For production use, automate hash verification through your build process rather than hardcoding values manually[2][5].

Citations:

- 1: https://classic.yarnpkg.com/en/package/@scalar/api-reference
- 2: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
- 3: https://guides.scalar.com/scalar/scalar-api-references/net-integration
- 4: https://docs.blackberry.com/content/dam/docs-blackberry-com/release-pdfs/en/blackberry-ues/Cylance_Endpoint_Security_Setup_Guide.pdf
- 5: https://github.com/scalar/scalar/blob/main/documentation/configuration.md
- 6: https://www.cisco.com/c/dam/en/us/td/docs/wireless/ucc/smi/2020-02/OpenSource/CiscoUltraCloudPlatform-202002-1601314047.pdf
- 7: https://firebase.google.com/docs/auth/admin/errors
- 8: https://www.contentful.com/developers/docs/references/graphql/
- 9: https://scalar.com
- 10: https://www.jsdelivr.com/package/npm/@scalar/api-reference
- 11: https://github.com/scalar/scalar
- 12: https://cdnjs.com/libraries/scalar-api-reference
- 13: https://huma.rocks/features/api-docs/

---



</details>

**Atenção: Implementar integridade SRI no carregamento do script**

- O uso do CDN para carregar o script do Scalar API Reference está adequado, mas é importante adicionar o atributo de integridade para reforçar a segurança contra alterações maliciosas.
- Como o hash de integridade varia conforme a versão do pacote, recomenda-se gerar o valor correto utilizando ferramentas de SRI. Por exemplo, você pode obter o hash com o seguinte comando:
  
  ```bash
  curl -s https://cdn.jsdelivr.net/npm/@scalar/api-reference | openssl dgst -sha384 -binary | openssl base64 -A
  ```

- Caso opte por referências oficiais, valide se a versão utilizada está listada com o hash SRI nos sites do [jsDelivr](https://www.jsdelivr.com/package/npm/@scalar/api-reference) ou [cdnjs](https://cdnjs.com/libraries/scalar-api-reference).
- Mantenha o template `{{.Url}}`, que será processado pelo servidor como esperado.

**Diff sugerido:**
```diff
-    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference" integrity="sha384-HASH_AQUI" crossorigin="anonymous"></script>
```

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,235 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "description": "This is the API for Key Haven",
+        "title": "Key Haven API",
+        "contact": {},
+        "version": "1.0"
+    },
+    "host": "localhost:8080",
+    "basePath": "/",
+    "paths": {
+        "/auth/login": {
+            "post": {
+                "description": "Authenticates a user and returns a token",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "User login",
+                "parameters": [
+                    {
+                        "description": "User login data",
+                        "name": "request",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/model.LoginRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/model.LoginResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid request body",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Invalid email or password",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal server error",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/auth/logout": {
+            "post": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "description": "Logs out the user by clearing the authentication cookie",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "User logout",
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/handler.MessageResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/auth/register": {
+            "post": {
+                "description": "Creates a new user account",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Auth"
+                ],
+                "summary": "Register a new user",
+                "parameters": [
+                    {
+                        "description": "User registration data",
+                        "name": "request",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/model.CreateUserRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "Created",
+                        "schema": {
+                            "$ref": "#/definitions/model.User"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid request body",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "409": {
+                        "description": "Email already in use",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal server error",
+                        "schema": {
+                            "$ref": "#/definitions/handler.ErrorResponse"
+                        }
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "handler.ErrorResponse": {
+            "type": "object",
+            "properties": {
+                "message": {
+                    "type": "string"
+                }
+            }
+        },
+        "handler.MessageResponse": {
+            "type": "object",
+            "properties": {
+                "message": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.CreateUserRequest": {
+            "type": "object",
+            "required": [
+                "email",
+                "firstName",
+                "password"
+            ],
+            "properties": {
+                "email": {
+                    "type": "string"
+                },
+                "firstName": {
+                    "type": "string"
+                },
+                "password": {
+                    "type": "string",
+                    "minLength": 12
+                }
+            }
+        },
+        "model.LoginRequest": {
+            "type": "object",
+            "required": [
+                "email",
+                "password"
+            ],
+            "properties": {
+                "email": {
+                    "type": "string"
+                },
+                "password": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.LoginResponse": {
+            "type": "object",
+            "properties": {
+                "token": {
+                    "type": "string"
+                },
+                "user": {
+                    "$ref": "#/definitions/model.User"
+                }
+            }
+        },
+        "model.User": {
+            "type": "object",
+            "properties": {
+                "created_at": {
+                    "type": "string"
+                },
+                "email": {
+                    "type": "string"
+                },
+                "first_name": {
+                    "type": "string"
+                },
+                "id": {
+                    "type": "string"
+                },
+                "last_login_at": {
+                    "type": "string"
+                },
+                "updated_at": {
+                    "type": "string"
+                }
+            }
+        }
+    }
path: pkg/docs/swagger.json
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Adicione definições de segurança no Swagger**

A documentação Swagger está bem estruturada, mas faltam definições de segurança adequadas. Você está usando `ApiKeyAuth` nos endpoints (por exemplo, em `/auth/logout`), mas não definiu o esquema de segurança correspondente.


Adicione a seção `securityDefinitions` para definir corretamente o esquema de segurança `ApiKeyAuth` e aplique configurações de segurança global:

```diff
{
    "swagger": "2.0",
    "info": {
        "description": "This is the API for Key Haven",
        "title": "Key Haven API",
        "contact": {},
        "version": "1.0"
    },
    "host": "localhost:8080",
    "basePath": "/",
+   "securityDefinitions": {
+       "ApiKeyAuth": {
+           "type": "apiKey",
+           "name": "Authorization",
+           "in": "header",
+           "description": "Authentication token with format: Bearer {token}"
+       }
+   },
+   "security": [
+       {
+           "ApiKeyAuth": []
+       }
+   ],
    "paths": {
```

Esta alteração corrige os quatro problemas críticos de segurança identificados na análise estática:
1. CKV_OPENAPI_1: Definição de `securityDefinitions`
2. CKV_OPENAPI_4: Campo de segurança global
3. CKV_OPENAPI_5: Operações de segurança não vazias
4. CKV_OPENAPI_6: Requisitos de segurança definidos


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
{
    "swagger": "2.0",
    "info": {
        "description": "This is the API for Key Haven",
        "title": "Key Haven API",
        "contact": {},
        "version": "1.0"
    },
    "host": "localhost:8080",
    "basePath": "/",
    "securityDefinitions": {
        "ApiKeyAuth": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header",
            "description": "Authentication token with format: Bearer {token}"
        }
    },
    "security": [
        {
            "ApiKeyAuth": []
        }
    ],
    "paths": {
        "/auth/login": {
            "post": {
                "description": "Authenticates a user and returns a token",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "User login",
                "parameters": [
                    {
                        "description": "User login data",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/model.LoginRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/model.LoginResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid request body",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    },
                    "401": {
                        "description": "Invalid email or password",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    },
                    "500": {
                        "description": "Internal server error",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/auth/logout": {
            "post": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "description": "Logs out the user by clearing the authentication cookie",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "User logout",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/handler.MessageResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/auth/register": {
            "post": {
                "description": "Creates a new user account",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Register a new user",
                "parameters": [
                    {
                        "description": "User registration data",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/model.CreateUserRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/model.User"
                        }
                    },
                    "400": {
                        "description": "Invalid request body",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    },
                    "409": {
                        "description": "Email already in use",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    },
                    "500": {
                        "description": "Internal server error",
                        "schema": {
                            "$ref": "#/definitions/handler.ErrorResponse"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "handler.ErrorResponse": {
            "type": "object",
            "properties": {
                "message": {
                    "type": "string"
                }
            }
        },
        "handler.MessageResponse": {
            "type": "object",
            "properties": {
                "message": {
                    "type": "string"
                }
            }
        },
        "model.CreateUserRequest": {
            "type": "object",
            "required": [
                "email",
                "firstName",
                "password"
            ],
            "properties": {
                "email": {
                    "type": "string"
                },
                "firstName": {
                    "type": "string"
                },
                "password": {
                    "type": "string",
                    "minLength": 12
                }
            }
        },
        "model.LoginRequest": {
            "type": "object",
            "required": [
                "email",
                "password"
            ],
            "properties": {
                "email": {
                    "type": "string"
                },
                "password": {
                    "type": "string"
                }
            }
        },
        "model.LoginResponse": {
            "type": "object",
            "properties": {
                "token": {
                    "type": "string"
                },
                "user": {
                    "$ref": "#/definitions/model.User"
                }
            }
        },
        "model.User": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "email": {
                    "type": "string"
                },
                "first_name": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "last_login_at": {
                    "type": "string"
                },
                "updated_at": {
                    "type": "string"
                }
            }
        }
    }
}
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Checkov (3.2.334)</summary>

[HIGH] 1-234: Ensure that security requirement defined in securityDefinitions - version 2.0 files

(CKV_OPENAPI_6)

---

[HIGH] 1-234: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

---

[HIGH] 1-234: Ensure that security operations is not empty.

(CKV_OPENAPI_5)

---

[HIGH] 1-234: Ensure that securityDefinitions is defined and not empty - version 2.0 files

(CKV_OPENAPI_1)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+package docs
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"os"
+	"path"
+
+	"github.com/gofiber/fiber/v3"
+)
+
+type Provider struct {
+	Url  string
+	Name string
+}
+
+func RegisterDocsRouter(app *fiber.App) {
+	app.Get("/public/openapi.json", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+		filename := path.Join(dir, "pkg", "docs", "swagger.json")
+		return ctx.SendFile(filename)
+	})
+
+	app.Get("/docs", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+
+		name := ctx.Query("name", "scalar")
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		tmpl, err := template.ParseFiles(filename)
path: pkg/docs/handler.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Valide o parâmetro 'name' para evitar vulnerabilidades de path traversal.**

O valor do parâmetro `name` é utilizado diretamente na construção do caminho do arquivo sem validação adequada, o que pode levar a vulnerabilidades de segurança.


```diff
-		name := ctx.Query("name", "scalar")
-		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		name := ctx.Query("name", "scalar")
+		// Permitir apenas valores válidos
+		allowedDocs := map[string]bool{"scalar": true, "redoc": true, "swagger": true}
+		if !allowedDocs[name] {
+			name = "scalar" // Valor padrão seguro
+		}
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
		name := ctx.Query("name", "scalar")
		// Permitir apenas valores válidos
		allowedDocs := map[string]bool{"scalar": true, "redoc": true, "swagger": true}
		if !allowedDocs[name] {
			name = "scalar" // Valor padrão seguro
		}
		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
		tmpl, err := template.ParseFiles(filename)
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+package docs
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"os"
+	"path"
+
+	"github.com/gofiber/fiber/v3"
+)
+
+type Provider struct {
+	Url  string
+	Name string
+}
+
+func RegisterDocsRouter(app *fiber.App) {
+	app.Get("/public/openapi.json", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+		filename := path.Join(dir, "pkg", "docs", "swagger.json")
+		return ctx.SendFile(filename)
+	})
+
+	app.Get("/docs", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+
+		name := ctx.Query("name", "scalar")
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		tmpl, err := template.ParseFiles(filename)
+		if err != nil {
+			fmt.Println("ParseFiles error")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
+		}
+
+		provider := &Provider{
+			Url:  "http://localhost:8080/public/openapi.json",
+			Name: name,
path: pkg/docs/handler.go
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Remova a URL hardcoded e utilize informações do contexto.**

A URL hardcoded `http://localhost:8080` não funcionará em ambientes de produção ou outros ambientes. Considere obter a URL base do próprio contexto da requisição.


```diff
-			Url:  "http://localhost:8080/public/openapi.json",
+			Url:  fmt.Sprintf("%s://%s/public/openapi.json", ctx.Protocol(), ctx.Hostname()),
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
			Url:  fmt.Sprintf("%s://%s/public/openapi.json", ctx.Protocol(), ctx.Hostname()),
			Name: name,
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+package docs
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"os"
+	"path"
+
+	"github.com/gofiber/fiber/v3"
+)
+
+type Provider struct {
+	Url  string
+	Name string
+}
+
+func RegisterDocsRouter(app *fiber.App) {
+	app.Get("/public/openapi.json", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+		filename := path.Join(dir, "pkg", "docs", "swagger.json")
+		return ctx.SendFile(filename)
+	})
+
+	app.Get("/docs", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+
+		name := ctx.Query("name", "scalar")
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		tmpl, err := template.ParseFiles(filename)
+		if err != nil {
+			fmt.Println("ParseFiles error")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
+		}
+
+		provider := &Provider{
+			Url:  "http://localhost:8080/public/openapi.json",
+			Name: name,
+		}
+
+		var bufferHtml bytes.Buffer
+		if err := tmpl.Execute(&bufferHtml, provider); err != nil {
+			fmt.Println("Execute Replace Text")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
path: pkg/docs/handler.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Substitua fmt.Println por um mecanismo de log apropriado.**

Novamente, o uso de `fmt.Println` viola as diretrizes de codificação do projeto.


```diff
-			fmt.Println("Execute Replace Text")
+			// Use um logger apropriado aqui
+			// log.Printf("Erro ao executar template: %v", err)
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
			// Use um logger apropriado aqui
			// log.Printf("Erro ao executar template: %v", err)
			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+package docs
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"os"
+	"path"
+
+	"github.com/gofiber/fiber/v3"
+)
+
+type Provider struct {
+	Url  string
+	Name string
+}
+
+func RegisterDocsRouter(app *fiber.App) {
+	app.Get("/public/openapi.json", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+		filename := path.Join(dir, "pkg", "docs", "swagger.json")
+		return ctx.SendFile(filename)
+	})
+
+	app.Get("/docs", func(ctx fiber.Ctx) error {
+		dir, err := os.Getwd()
+		if err != nil {
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to get current directory: "+err.Error())
+		}
+
+		name := ctx.Query("name", "scalar")
+		filename := path.Join(dir, "pkg", "docs", fmt.Sprintf("%s.html", name))
+		tmpl, err := template.ParseFiles(filename)
+		if err != nil {
+			fmt.Println("ParseFiles error")
+			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
path: pkg/docs/handler.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Substitua fmt.Println por um mecanismo de log apropriado.**

O uso de `fmt.Println` viola as diretrizes de codificação do projeto. Utilize um sistema de log estruturado como o pacote `log` padrão ou uma biblioteca como `zap`.


```diff
-			fmt.Println("ParseFiles error")
+			// Use um logger apropriado aqui
+			// log.Printf("Erro ao analisar arquivo de template: %v", err)
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
			// Use um logger apropriado aqui
			// log.Printf("Erro ao analisar arquivo de template: %v", err)
			return fiber.NewError(fiber.StatusInternalServerError, "Fail to generate docs: "+err.Error())
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-20T13:15:46Z
author_association: CONTRIBUTOR
path: pkg/docs/scalar.go
user: login: vinirossado
body: is this file really needed?
created_at: 2025-03-20T13:19:54Z
author_association: COLLABORATOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-20T13:08:26Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: skip review by coderabbit.ai -->

> [!IMPORTANT]
> ## Review skipped
> 
> Auto reviews are disabled on base/target branches other than the default branch.
> 
> 
> 
> Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command.
> 
> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.

<!-- end of auto-generated comment: skip review by coderabbit.ai -->
<!-- walkthrough_start -->

<details>
<summary>📝 Walkthrough</summary>

## Walkthrough
Este pull request atualiza o gerenciamento de dependências e ajusta funções de autenticação. No arquivo go.mod, são removidas, adicionadas e atualizadas diversas dependências. Em arquivos de middleware e serviços, as chamadas de funções foram alteradas de `crypto` para `secret`, mantendo a lógica de validação de token, verificação de senha e geração de token. Foram adicionados novos arquivos no pacote `docs`, que introduzem rotas e páginas de documentação (Swagger, Redoc, Scalar) no aplicativo. Por fim, há renomeações de pacotes e remoção de funções relacionadas a JWT e hashing de senhas.

## Changes

| Arquivos | Resumo da Alteração |
|----------|---------------------|
| **go.mod** | Remoção de `github.com/golang-jwt/jwt/v5`, adição de `github.com/swaggo/swag v1.16.4` e atualização de diversas dependências indiretas. |
| **internal/middleware/handler.go**, **internal/service/auth_service.go**, **internal/service/user_service.go** | Atualização de imports e chamadas de funções, substituindo `crypto` por `secret` em validação de token, verificação de senha, geração de token e hash de senhas. |
| **main.go** | Inclusão da importação do pacote `docs` e chamada da função `RegisterDocsRouter` para registrar rotas de documentação. |
| **pkg/docs/handler.go**, **redoc.go**, **redoc.html**, **scalar.go**, **scalar.html**, **swagger.go**, **swagger.html**, **swagger.json** | Criação de novos arquivos para configurar rotas e páginas de documentação da API (Swagger, Redoc, Scalar). |
| **pkg/secret/argon.go**, **pkg/secret/paseto.go** | Alteração do nome do pacote de `crypto` para `secret`. |
| **pkg/secret/authenticator.go**, **pkg/secret/password.go** | Remoção de funções para criação/validação de JWT e para hashing de senhas. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Cliente
    participant App
    participant DocsHandler
    Cliente->>App: Solicita /docs ou /public/openapi.json
    App->>DocsHandler: Encaminha a requisição
    DocsHandler->>FileSystem: Lê o arquivo de documentação (HTML/JSON)
    FileSystem-->>DocsHandler: Retorna o conteúdo do arquivo
    DocsHandler-->>Cliente: Envia documento renderizado
```

## Possibly related PRs
- **RaposoG/key-haven-back#11**: Modificações no go.mod envolvendo dependências indiretas, com foco semelhante em atualização e gerenciamento de dependências.

## Poem
> Eu sou o coelhinho do código, a pular sem parar,  
> Com saltos leves, novas rotas vieram a brilhar.  
> Dependências dançam num compasso animado,  
> De `crypto` para `secret`, o caminho foi trocado.  
> Nos docs, uma festa de páginas a se mostrar,  
> Hop, hop, hop! Vamos juntos celebrar! 🐰  
> Código e coelhice, no CodeRabbit sempre a encantar!

</details>

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=RaposoG/key-haven-back&utm_content=16):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: MatheusVp2
created_at: 2025-03-20T13:08:52Z
body: @coderabbitai full review
author_association: COLLABORATOR
user: login: coderabbitai[bot]
created_at: 2025-03-20T13:08:58Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
<details>
<summary>:white_check_mark: Actions performed</summary>

Full review triggered.

</details>
author_association: CONTRIBUTOR