all repos

onasty @ c685a654684618188c618d65966a689f8b2dab39

a one-time notes service
13 files changed, 96 insertions(+), 32 deletions(-)
feat: add cors (#115)

* feat(config): add CORS options

* chore: go get gin's cors middlware

* feat(http): add cors middleware

* fixup! feat(config): add CORS options

* fixup! feat(http): add cors middleware

* fix: e2e tests

* fix: ignore cors.Config struct

* chore(golangci-lint): disable exhaustruct for more cases
Author: Smirnov Oleksandr ss2316544@gmail.com
Committed by: GitHub noreply@github.com
Committed at: 2025-05-23 16:59:35 +0300
Parent: a705387
M .env.example
···
        5
        5
         

      
        6
        6
         HTTP_PORT=8000

      
        7
        7
         

      
        
        8
        +CORS_ALLOWED_ORIGINS=http://localhost:3000,http://onasty.localhost

      
        
        9
        +CORS_MAX_AGE=12h

      
        
        10
        +

      
        8
        11
         METRICS_ENABLED=true

      
        9
        12
         METRICS_PORT=8001

      
        10
        13
         

      
M .golangci.yaml
···
        79
        79
             exhaustruct:

      
        80
        80
               exclude:

      
        81
        81
                 - log/slog\.HandlerOptions

      
        82
        
        -        - net/http\.Server

      
        
        82
        +        - net/http\.(Server|Client|Response)

      
        83
        83
                 - github.com/golang-jwt/jwt/v5\.RegisteredClaims

      
        
        84
        +        - github.com/gin-contrib/cors\.Config

      
        
        85
        +        - github.com/prometheus/client_golang/prometheus\.(CounterOpts|HistogramOpts)

      
        84
        86
         

      
        85
        87
             funlen:

      
        86
        88
               lines: 100

      
M cmd/server/main.go
···
        129
        129
         	handler := httptransport.NewTransport(

      
        130
        130
         		usersrv,

      
        131
        131
         		notesrv,

      
        
        132
        +		cfg.CORSAllowedOrigins,

      
        
        133
        +		cfg.CORSMaxAge,

      
        132
        134
         		rateLimiterConfig,

      
        133
        135
         	)

      
        134
        136
         

      
M e2e/e2e_test.go
···
        137
        137
         		Burst: 1000,

      
        138
        138
         	}

      
        139
        139
         

      
        140
        
        -	handler := httptransport.NewTransport(usersrv, notesrv, ratelimitCfg)

      
        
        140
        +	handler := httptransport.NewTransport(

      
        
        141
        +		usersrv,

      
        
        142
        +		notesrv,

      
        
        143
        +		cfg.CORSAllowedOrigins,

      
        
        144
        +		cfg.CORSMaxAge,

      
        
        145
        +		ratelimitCfg,

      
        
        146
        +	)

      
        141
        147
         	e.router = handler.Handler()

      
        142
        148
         }

      
        143
        149
         

      
M go.mod
···
        27
        27
         	github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect

      
        28
        28
         	github.com/Microsoft/go-winio v0.6.2 // indirect

      
        29
        29
         	github.com/beorn7/perks v1.0.1 // indirect

      
        30
        
        -	github.com/bytedance/sonic v1.11.6 // indirect

      
        31
        
        -	github.com/bytedance/sonic/loader v0.1.1 // indirect

      
        
        30
        +	github.com/bytedance/sonic v1.13.2 // indirect

      
        
        31
        +	github.com/bytedance/sonic/loader v0.2.4 // indirect

      
        32
        32
         	github.com/cenkalti/backoff/v4 v4.2.1 // indirect

      
        33
        33
         	github.com/cespare/xxhash/v2 v2.3.0 // indirect

      
        34
        
        -	github.com/cloudwego/base64x v0.1.4 // indirect

      
        
        34
        +	github.com/cloudwego/base64x v0.1.5 // indirect

      
        35
        35
         	github.com/cloudwego/iasm v0.2.0 // indirect

      
        36
        36
         	github.com/containerd/log v0.1.0 // indirect

      
        37
        37
         	github.com/containerd/platforms v0.2.1 // indirect

      ···
        44
        44
         	github.com/docker/go-units v0.5.0 // indirect

      
        45
        45
         	github.com/ebitengine/purego v0.8.2 // indirect

      
        46
        46
         	github.com/felixge/httpsnoop v1.0.4 // indirect

      
        47
        
        -	github.com/gabriel-vasile/mimetype v1.4.3 // indirect

      
        48
        
        -	github.com/gin-contrib/sse v0.1.0 // indirect

      
        
        47
        +	github.com/gabriel-vasile/mimetype v1.4.8 // indirect

      
        
        48
        +	github.com/gin-contrib/cors v1.7.5 // indirect

      
        
        49
        +	github.com/gin-contrib/sse v1.0.0 // indirect

      
        49
        50
         	github.com/go-chi/chi/v5 v5.2.1 // indirect

      
        50
        51
         	github.com/go-logr/logr v1.4.2 // indirect

      
        51
        52
         	github.com/go-logr/stdr v1.2.2 // indirect

      
        52
        53
         	github.com/go-ole/go-ole v1.2.6 // indirect

      
        53
        54
         	github.com/go-playground/locales v0.14.1 // indirect

      
        54
        55
         	github.com/go-playground/universal-translator v0.18.1 // indirect

      
        55
        
        -	github.com/go-playground/validator/v10 v10.20.0 // indirect

      
        56
        
        -	github.com/goccy/go-json v0.10.2 // indirect

      
        
        56
        +	github.com/go-playground/validator/v10 v10.26.0 // indirect

      
        
        57
        +	github.com/goccy/go-json v0.10.5 // indirect

      
        57
        58
         	github.com/gogo/protobuf v1.3.2 // indirect

      
        58
        59
         	github.com/google/uuid v1.6.0 // indirect

      
        59
        60
         	github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect

      ···
        71
        72
         	github.com/jackc/puddle/v2 v2.2.2 // indirect

      
        72
        73
         	github.com/json-iterator/go v1.1.12 // indirect

      
        73
        74
         	github.com/klauspost/compress v1.18.0 // indirect

      
        74
        
        -	github.com/klauspost/cpuid/v2 v2.2.7 // indirect

      
        
        75
        +	github.com/klauspost/cpuid/v2 v2.2.10 // indirect

      
        75
        76
         	github.com/leodido/go-urn v1.4.0 // indirect

      
        76
        77
         	github.com/lib/pq v1.10.9 // indirect

      
        77
        78
         	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect

      ···
        93
        94
         	github.com/nats-io/nuid v1.0.1 // indirect

      
        94
        95
         	github.com/opencontainers/go-digest v1.0.0 // indirect

      
        95
        96
         	github.com/opencontainers/image-spec v1.1.1 // indirect

      
        96
        
        -	github.com/pelletier/go-toml/v2 v2.2.2 // indirect

      
        
        97
        +	github.com/pelletier/go-toml/v2 v2.2.3 // indirect

      
        97
        98
         	github.com/pkg/errors v0.9.1 // indirect

      
        98
        99
         	github.com/pmezard/go-difflib v1.0.0 // indirect

      
        99
        100
         	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect

      ···
        113
        114
         	go.opentelemetry.io/otel/metric v1.35.0 // indirect

      
        114
        115
         	go.opentelemetry.io/otel/trace v1.35.0 // indirect

      
        115
        116
         	go.uber.org/atomic v1.9.0 // indirect

      
        116
        
        -	golang.org/x/arch v0.8.0 // indirect

      
        
        117
        +	golang.org/x/arch v0.15.0 // indirect

      
        117
        118
         	golang.org/x/crypto v0.37.0 // indirect

      
        118
        119
         	golang.org/x/net v0.38.0 // indirect

      
        119
        120
         	golang.org/x/sync v0.13.0 // indirect

      
        120
        121
         	golang.org/x/sys v0.32.0 // indirect

      
        121
        122
         	golang.org/x/text v0.24.0 // indirect

      
        122
        
        -	google.golang.org/protobuf v1.36.5 // indirect

      
        
        123
        +	google.golang.org/protobuf v1.36.6 // indirect

      
        123
        124
         	gopkg.in/yaml.v3 v3.0.1 // indirect

      
        124
        125
         )

      
M go.sum
···
        19
        19
         github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=

      
        20
        20
         github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=

      
        21
        21
         github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=

      
        
        22
        +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=

      
        
        23
        +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=

      
        22
        24
         github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=

      
        23
        25
         github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=

      
        
        26
        +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=

      
        
        27
        +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=

      
        24
        28
         github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=

      
        25
        29
         github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=

      
        26
        30
         github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=

      
        27
        31
         github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=

      
        28
        32
         github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=

      
        29
        33
         github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=

      
        
        34
        +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=

      
        
        35
        +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=

      
        30
        36
         github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=

      
        31
        37
         github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=

      
        32
        38
         github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=

      ···
        63
        69
         github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=

      
        64
        70
         github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=

      
        65
        71
         github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=

      
        
        72
        +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=

      
        
        73
        +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=

      
        
        74
        +github.com/gin-contrib/cors v1.7.5 h1:cXC9SmofOrRg0w9PigwGlHG3ztswH6bqq4vJVXnvYMk=

      
        
        75
        +github.com/gin-contrib/cors v1.7.5/go.mod h1:4q3yi7xBEDDWKapjT2o1V7mScKDDr8k+jZ0fSquGoy0=

      
        66
        76
         github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=

      
        67
        77
         github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=

      
        
        78
        +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=

      
        
        79
        +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=

      
        68
        80
         github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=

      
        69
        81
         github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=

      
        70
        82
         github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=

      ···
        86
        98
         github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=

      
        87
        99
         github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=

      
        88
        100
         github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=

      
        
        101
        +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=

      
        
        102
        +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=

      
        89
        103
         github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=

      
        90
        104
         github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=

      
        91
        105
         github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=

      
        
        106
        +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=

      
        
        107
        +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=

      
        92
        108
         github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=

      
        93
        109
         github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=

      
        94
        110
         github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=

      ···
        177
        193
         github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=

      
        178
        194
         github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=

      
        179
        195
         github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=

      
        
        196
        +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=

      
        
        197
        +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=

      
        180
        198
         github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=

      
        181
        199
         github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=

      
        182
        200
         github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=

      ···
        248
        266
         github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=

      
        249
        267
         github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=

      
        250
        268
         github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=

      
        
        269
        +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=

      
        
        270
        +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=

      
        251
        271
         github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

      
        252
        272
         github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

      
        253
        273
         github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

      ···
        353
        373
         golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=

      
        354
        374
         golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=

      
        355
        375
         golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=

      
        
        376
        +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=

      
        
        377
        +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=

      
        356
        378
         golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

      
        357
        379
         golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=

      
        358
        380
         golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=

      ···
        447
        469
         google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=

      
        448
        470
         google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=

      
        449
        471
         google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=

      
        
        472
        +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=

      
        
        473
        +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=

      
        450
        474
         gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

      
        451
        475
         gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

      
        452
        476
         gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

      
M internal/config/config.go
···
        4
        4
         	"errors"

      
        5
        5
         	"os"

      
        6
        6
         	"strconv"

      
        
        7
        +	"strings"

      
        7
        8
         	"time"

      
        8
        9
         )

      
        9
        10
         

      ···
        11
        12
         	AppEnv  string

      
        12
        13
         	AppURL  string

      
        13
        14
         	NatsURL string

      
        
        15
        +

      
        
        16
        +	CORSAllowedOrigins []string

      
        
        17
        +	CORSMaxAge         time.Duration

      
        14
        18
         

      
        15
        19
         	HTTPPort            int

      
        16
        20
         	HTTPWriteTimeout    time.Duration

      ···
        60
        64
         		AppEnv:  getenvOrDefault("APP_ENV", "debug"),

      
        61
        65
         		AppURL:  getenvOrDefault("APP_URL", ""),

      
        62
        66
         		NatsURL: getenvOrDefault("NATS_URL", ""),

      
        
        67
        +

      
        
        68
        +		CORSAllowedOrigins: strings.Split(getenvOrDefault("CORS_ALLOWED_ORIGINS", "*"), ","),

      
        
        69
        +		CORSMaxAge:         mustParseDuration(getenvOrDefault("CORS_MAX_AGE", "12h")),

      
        63
        70
         

      
        64
        71
         		HTTPPort:            mustGetenvOrDefaultInt("HTTP_PORT", 3000),

      
        65
        72
         		HTTPWriteTimeout:    mustParseDuration(getenvOrDefault("HTTP_WRITE_TIMEOUT", "10s")),

      
M internal/metrics/http_metrics.go
···
        8
        8
         )

      
        9
        9
         

      
        10
        10
         var (

      
        11
        
        -	successfulHTTPRequest = promauto.NewCounterVec(prometheus.CounterOpts{ //nolint:exhaustruct

      
        
        11
        +	successfulHTTPRequest = promauto.NewCounterVec(prometheus.CounterOpts{

      
        12
        12
         		Name:        "http_successful_requests_total",

      
        13
        13
         		Help:        "the total number of successful http requests",

      
        14
        14
         		ConstLabels: map[string]string{"status": "success"},

      
        15
        15
         	}, []string{"method", "uri"})

      
        16
        16
         

      
        17
        
        -	failedHTTPRequest = promauto.NewCounterVec(prometheus.CounterOpts{ //nolint:exhaustruct

      
        
        17
        +	failedHTTPRequest = promauto.NewCounterVec(prometheus.CounterOpts{

      
        18
        18
         		Name:        "http_failed_requests_total",

      
        19
        19
         		Help:        "the total number of failed http requests",

      
        20
        20
         		ConstLabels: map[string]string{"status": "failure"},

      
        21
        21
         	}, []string{"method", "uri"})

      
        22
        22
         

      
        23
        
        -	latencyHTTPRequest = promauto.NewHistogramVec(prometheus.HistogramOpts{ //nolint:exhaustruct

      
        
        23
        +	latencyHTTPRequest = promauto.NewHistogramVec(prometheus.HistogramOpts{

      
        24
        24
         		Name:    "http_request_latency_seconds",

      
        25
        25
         		Help:    "the latency of http requests in seconds",

      
        26
        26
         		Buckets: prometheus.DefBuckets,

      
M internal/oauth/github_test.go
···
        35
        35
         	userLogin := "testing"

      
        36
        36
         

      
        37
        37
         	resp := fmt.Sprintf(`{"id":%s, "email":"%s", "login":"%s"}`, userID, userEmail, userLogin)

      
        38
        
        -	client := &http.Client{ //nolint:exhaustruct

      
        
        38
        +	client := &http.Client{

      
        39
        39
         		Transport: mockClient(func(req *http.Request) (*http.Response, error) {

      
        40
        40
         			if req.Method == http.MethodPost {

      
        41
        
        -				return &http.Response{ //nolint:exhaustruct

      
        
        41
        +				return &http.Response{

      
        42
        42
         					StatusCode: http.StatusOK,

      
        43
        43
         					Header:     http.Header{"Content-Type": []string{"application/json"}},

      
        44
        44
         					Body: io.NopCloser(

      ···
        48
        48
         					),

      
        49
        49
         				}, nil

      
        50
        50
         			}

      
        51
        
        -			return &http.Response{ //nolint:exhaustruct

      
        
        51
        +			return &http.Response{

      
        52
        52
         				StatusCode: http.StatusOK,

      
        53
        53
         				Header:     http.Header{"Content-Type": []string{"application/json"}},

      
        54
        54
         				Body:       io.NopCloser(strings.NewReader(resp)),

      ···
        67
        67
         }

      
        68
        68
         

      
        69
        69
         func TestGitHubProvider_ExchangeCode_tokenExcahnge_error(t *testing.T) {

      
        70
        
        -	client := &http.Client{ //nolint:exhaustruct

      
        
        70
        +	client := &http.Client{

      
        71
        71
         		Transport: mockClient(func(req *http.Request) (*http.Response, error) {

      
        72
        72
         			if req.Method == http.MethodPost {

      
        73
        
        -				return &http.Response{ //nolint:exhaustruct

      
        
        73
        +				return &http.Response{

      
        74
        74
         					StatusCode: http.StatusBadRequest,

      
        75
        75
         					Body:       io.NopCloser(strings.NewReader("")),

      
        76
        76
         				}, nil

      
M internal/oauth/google_test.go
···
        28
        28
         	sub := "1234567890"

      
        29
        29
         	email := "testemail@mail.com"

      
        30
        30
         	resp := fmt.Sprintf(`{"sub":"%s", "email":"%s","email_verified":true}`, sub, email)

      
        31
        
        -	client := &http.Client{ //nolint:exhaustruct

      
        
        31
        +	client := &http.Client{

      
        32
        32
         		Transport: mockClient(func(req *http.Request) (*http.Response, error) {

      
        33
        33
         			if req.Method == http.MethodPost {

      
        34
        
        -				return &http.Response{ //nolint:exhaustruct

      
        
        34
        +				return &http.Response{

      
        35
        35
         					StatusCode: http.StatusOK,

      
        36
        36
         					Header:     http.Header{"Content-Type": []string{"application/json"}},

      
        37
        37
         					Body: io.NopCloser(

      ···
        41
        41
         					),

      
        42
        42
         				}, nil

      
        43
        43
         			}

      
        44
        
        -			return &http.Response{ //nolint:exhaustruct

      
        
        44
        +			return &http.Response{

      
        45
        45
         				StatusCode: http.StatusOK,

      
        46
        46
         				Header:     http.Header{"Content-Type": []string{"application/json"}},

      
        47
        47
         				Body:       io.NopCloser(strings.NewReader(resp)),

      
M internal/transport/http/http.go
···
        2
        2
         

      
        3
        3
         import (

      
        4
        4
         	"net/http"

      
        
        5
        +	"time"

      
        5
        6
         

      
        6
        7
         	"github.com/gin-gonic/gin"

      
        7
        8
         	"github.com/olexsmir/onasty/internal/service/notesrv"

      ···
        15
        16
         	usersrv usersrv.UserServicer

      
        16
        17
         	notesrv notesrv.NoteServicer

      
        17
        18
         

      
        18
        
        -	ratelimitCfg ratelimit.Config

      
        
        19
        +	corsAllowedOrigins []string

      
        
        20
        +	corsMaxAge         time.Duration

      
        
        21
        +	ratelimitCfg       ratelimit.Config

      
        19
        22
         }

      
        20
        23
         

      
        21
        24
         func NewTransport(

      
        22
        25
         	us usersrv.UserServicer,

      
        23
        26
         	ns notesrv.NoteServicer,

      
        
        27
        +	corsAllowedOrigins []string,

      
        
        28
        +	corsMaxAge time.Duration,

      
        24
        29
         	ratelimitCfg ratelimit.Config,

      
        25
        30
         ) *Transport {

      
        26
        31
         	return &Transport{

      
        27
        
        -		usersrv:      us,

      
        28
        
        -		notesrv:      ns,

      
        29
        
        -		ratelimitCfg: ratelimitCfg,

      
        
        32
        +		usersrv:            us,

      
        
        33
        +		notesrv:            ns,

      
        
        34
        +		corsAllowedOrigins: corsAllowedOrigins,

      
        
        35
        +		corsMaxAge:         corsMaxAge,

      
        
        36
        +		ratelimitCfg:       ratelimitCfg,

      
        30
        37
         	}

      
        31
        38
         }

      
        32
        39
         

      ···
        35
        42
         	r.Use(

      
        36
        43
         		gin.Recovery(),

      
        37
        44
         		reqid.Middleware(),

      
        38
        
        -		t.logger(),

      
        
        45
        +		t.loggerMiddleware(),

      
        
        46
        +		t.corsMiddleware(),

      
        39
        47
         		ratelimit.MiddlewareWithConfig(t.ratelimitCfg),

      
        40
        48
         	)

      
        41
        49
         

      
M internal/transport/http/middlewares.go
···
        4
        4
         	"log/slog"

      
        5
        5
         	"time"

      
        6
        6
         

      
        
        7
        +	"github.com/gin-contrib/cors"

      
        7
        8
         	"github.com/gin-gonic/gin"

      
        8
        9
         )

      
        9
        10
         

      
        10
        
        -func (t *Transport) logger() gin.HandlerFunc {

      
        
        11
        +func (t *Transport) corsMiddleware() gin.HandlerFunc {

      
        
        12
        +	return cors.New(cors.Config{

      
        
        13
        +		AllowOrigins:     t.corsAllowedOrigins,

      
        
        14
        +		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE"},

      
        
        15
        +		AllowHeaders:     []string{"Authorization", "Content-Type"},

      
        
        16
        +		AllowCredentials: true,

      
        
        17
        +		MaxAge:           t.corsMaxAge,

      
        
        18
        +	})

      
        
        19
        +}

      
        
        20
        +

      
        
        21
        +func (t *Transport) loggerMiddleware() gin.HandlerFunc {

      
        11
        22
         	return func(c *gin.Context) {

      
        12
        23
         		start := time.Now()

      
        13
        24
         		path := c.Request.URL.Path

      
M mailer/metrics.go
···
        9
        9
         )

      
        10
        10
         

      
        11
        11
         var (

      
        12
        
        -	emailSentSuccessfully = promauto.NewCounter(prometheus.CounterOpts{ //nolint:exhaustruct

      
        
        12
        +	emailSentSuccessfully = promauto.NewCounter(prometheus.CounterOpts{

      
        13
        13
         		Name: "mail_sent_total",

      
        14
        14
         		Help: "the total number of successfully sent email",

      
        15
        15
         	})

      
        16
        16
         

      
        17
        
        -	emailFailedToSend = promauto.NewCounterVec(prometheus.CounterOpts{ //nolint:exhaustruct

      
        
        17
        +	emailFailedToSend = promauto.NewCounterVec(prometheus.CounterOpts{

      
        18
        18
         		Name: "mail_failed_total",

      
        19
        19
         		Help: "the total number of email that failed to send",

      
        20
        20
         	}, []string{"request_id"})