mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-10-11 04:09:05 +02:00
chore(deps): update Fosite
This commit is contained in:
@@ -56,7 +56,7 @@ cd ../.. && pnpm test # = playwright test in tests/
|
||||
|
||||
- **Config:** global `common.EnvConfig` (caarlos0/env); any secret var supports a `*_FILE` variant.
|
||||
- **Logging:** stdlib `log/slog` only (bridged to OpenTelemetry). No zerolog/logrus in app code.
|
||||
- `go.mod` pins a **fork** of fosite (`replace github.com/ory/fosite => github.com/pocket-id/fosite`).
|
||||
- Fosite comes from Pocket ID's **fork** `github.com/pocket-id/fosite`, not `github.com/ory/fosite`. It ports upstream fixes from `ory/hydra`.
|
||||
|
||||
## Frontend (SvelteKit)
|
||||
|
||||
|
||||
+21
-25
@@ -35,9 +35,9 @@ require (
|
||||
github.com/lmittmann/tint v1.2.1
|
||||
github.com/mattn/go-isatty v0.0.24
|
||||
github.com/mileusna/useragent v1.3.5
|
||||
github.com/ory/fosite v0.49.1-0.20250703093431-a5f0b09bf31c
|
||||
github.com/oschwald/maxminddb-golang/v2 v2.7.0
|
||||
github.com/pires/go-proxyproto v0.15.0
|
||||
github.com/pocket-id/fosite v1.4.0
|
||||
github.com/quic-go/quic-go v0.63.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.12.1
|
||||
@@ -45,16 +45,16 @@ require (
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.71.0
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.71.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.72.0
|
||||
go.opentelemetry.io/otel v1.47.0
|
||||
go.opentelemetry.io/otel/sdk v1.47.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.22.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.47.0
|
||||
go.opentelemetry.io/otel/trace v1.47.0
|
||||
golang.org/x/crypto v0.57.0
|
||||
golang.org/x/crypto v0.58.0
|
||||
golang.org/x/image v0.46.0
|
||||
golang.org/x/sync v0.24.0
|
||||
golang.org/x/text v0.42.0
|
||||
golang.org/x/text v0.43.0
|
||||
gorm.io/driver/postgres v1.6.3
|
||||
gorm.io/gorm v1.31.2
|
||||
gorm.io/plugin/opentelemetry v0.1.16
|
||||
@@ -85,7 +85,6 @@ require (
|
||||
github.com/bytedance/sonic/loader v0.5.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.7 // indirect
|
||||
github.com/cristalhq/jwt/v5 v5.4.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.4.2 // indirect
|
||||
github.com/disintegration/gift v1.2.1 // indirect
|
||||
github.com/dsoprea/go-exif v0.0.0-20230826092837-6579e82b732d // indirect
|
||||
@@ -121,8 +120,7 @@ require (
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/google/go-tpm v0.9.8 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.31.0 // indirect
|
||||
github.com/h2non/filetype v1.1.3 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
@@ -131,7 +129,7 @@ require (
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jaegertracing/jaeger-idl v0.12.0 // indirect
|
||||
github.com/jaegertracing/jaeger-idl v0.14.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -186,39 +184,39 @@ require (
|
||||
go.mongodb.org/mongo-driver/v2 v2.9.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.71.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.71.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.46.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.37.3 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.72.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.47.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.47.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.38.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.22.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.22.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.47.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.47.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.68.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.22.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.47.0 // indirect
|
||||
go.opentelemetry.io/otel/log v1.47.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.47.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.11.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.5 // indirect
|
||||
golang.org/x/arch v0.31.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba // indirect
|
||||
golang.org/x/mod v0.41.0 // indirect
|
||||
golang.org/x/net v0.59.0 // indirect
|
||||
golang.org/x/mod v0.42.0 // indirect
|
||||
golang.org/x/net v0.61.0 // indirect
|
||||
golang.org/x/oauth2 v0.37.0 // indirect
|
||||
golang.org/x/sys v0.48.0 // indirect
|
||||
golang.org/x/sys v0.49.0 // indirect
|
||||
golang.org/x/time v0.16.0 // indirect
|
||||
golang.org/x/tools v0.50.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260918162117-cecb64721679 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679 // indirect
|
||||
google.golang.org/grpc v1.83.2 // indirect
|
||||
golang.org/x/tools v0.52.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 // indirect
|
||||
google.golang.org/grpc v1.84.0 // indirect
|
||||
google.golang.org/protobuf v1.36.12 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 // indirect
|
||||
@@ -226,5 +224,3 @@ require (
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.12.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/ory/fosite => github.com/pocket-id/fosite v1.3.0
|
||||
|
||||
+48
-50
@@ -221,10 +221,8 @@ github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFe
|
||||
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 h1:/Tnpcb2E0Pz/tN9s3bfEY2Q8ePCEX9iuS+cneUwncnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0/go.mod h1:zOBXOsUaBSjKgmH4OGzV1esUpR3oUSCPYVd2cUBjKYY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.31.0 h1:Bd7KaOxzULLxtZ/K5s1aLbWhR0+5RToO65TXHsf3bqQ=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.31.0/go.mod h1:nN7ts3dFXKtCZWc//yfkpcQNKJABg16/uDVAZpLDalo=
|
||||
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
|
||||
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
@@ -255,8 +253,8 @@ github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg=
|
||||
github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jaegertracing/jaeger-idl v0.12.0 h1:FDk3ezIqKk7n9/gzxG9NNjDWzZZLh0GiCxhF4H1LRNU=
|
||||
github.com/jaegertracing/jaeger-idl v0.12.0/go.mod h1:wWzFftH47XtPRkOM25NPNZ7zBhREWB5HtZBsWj25eW0=
|
||||
github.com/jaegertracing/jaeger-idl v0.14.0 h1:qfeFswJMftWq2CJKvpws5Zlcpfnnmf9+LmDwTYOUMPo=
|
||||
github.com/jaegertracing/jaeger-idl v0.14.0/go.mod h1:XGC1/asZXDZTJdN5ZUooZROTlAc6tsbW6sxtF0PNODk=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
@@ -394,8 +392,8 @@ github.com/pires/go-proxyproto v0.15.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pocket-id/fosite v1.3.0 h1:lHs3bYhK3Xo7bKYcxSfNWN4hmSLO4gSLsQwwtl4oA0M=
|
||||
github.com/pocket-id/fosite v1.3.0/go.mod h1:v0FwUcx6Xd7xu/V6hLbIqtFfqRSWcJRJl1f8t0cnIuU=
|
||||
github.com/pocket-id/fosite v1.4.0 h1:nCCc8rqui1ffUEoH4Xv1XAQZqcXYIUE0Fe4dzLiPh9k=
|
||||
github.com/pocket-id/fosite v1.4.0/go.mod h1:1zQyPDsHITYiDgzNEVvZcDho56KLb+MWSP6OM3u3s1c=
|
||||
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
|
||||
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
|
||||
github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo=
|
||||
@@ -454,12 +452,12 @@ github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWD
|
||||
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
|
||||
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/gjson v1.20.0 h1:+agJ3rEzKcCXKDKo0ml26UROcpcAlnZyjq+TjbY5Fto=
|
||||
github.com/tidwall/gjson v1.20.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
|
||||
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
|
||||
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.2 h1:dz1jrRuE7or/74V490B4/GP1pZm5WKlt2bgCP5A83w8=
|
||||
github.com/tidwall/pretty v1.2.2/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ=
|
||||
@@ -495,16 +493,16 @@ go.opentelemetry.io/contrib/exporters/autoexport v0.71.0 h1:VCsJbp0YLyPtx2tu5Vgv
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.71.0/go.mod h1:qxZqn7e10f6ajmMCkg/47rMS7qQYfaOl2nj/4aytHUQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.71.0 h1:TMTU0sQyqsF1QU+/Q4LAZlLOx1L3FJDbk5N2RVB1nx4=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.71.0/go.mod h1:QzTELfxkj/tFEZSD22OPPwLet5nIPmcdmZPeISk4C8M=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.71.0 h1:oFNJW32h2SXnET7XXstgT7pVh4vN+jW+GfiIaBguIZE=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.71.0/go.mod h1:+H3sPOFwag14eMHTPMElZtV0e4YfVZ/85KgrKUCB5FI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0 h1:3g7B90UzBltIDKq1/5mrTGxTnOFDV0ICOhLoxiZ8jlg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0/go.mod h1:Ef8SuTh59BT7+ofpDxN9z+yOlc4t2GjLmKDgYNJL/NU=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.46.0 h1:OFVqWObn7xLIbOjE/koO0LS9fZJNgAyBD0msA+UQAoc=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.46.0/go.mod h1:t/d64xy7xuuEDJN/4ThqohLgRhIuQxL9y7P1v02bYuM=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0 h1:uxl0SGcmuBkHj/Adl9oftEAyiawQBPL5RzMAmt/Yvq4=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0/go.mod h1:LiOkxCIvoLofmRps7f8l0NkBtmObnAyQ5trteFs6wj8=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.37.3 h1:20rKrm6q8YlSVwVObflwKd2abo9f8b3WsxJ6YTyQtE8=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.37.3/go.mod h1:2yFxWbgN2VupcMTWu57donCZ9I1lALhawQjNAK7Xmm4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.72.0 h1:jva1c3z2ZFEQ5sTvnLG2tBALNehO+QvdXKQii6eKRoo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.72.0/go.mod h1:3pjFS5EnOVfjvYO6/NMdtJFHFQR+8uiGtrZ965nZP4w=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.72.0 h1:LxwW/9ctSCv+QkE/cLR7M91ZIkXNMqJtEMi1vCw9U8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.72.0/go.mod h1:tOsftB4SslBwwErVEPaenU2RpThXWPIU8DoJHEC4dyw=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.47.0 h1:vlKDmtjhe1R0d7kdov/+KVTKWOKeGLyohB+iXoDPRMQ=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.47.0/go.mod h1:0zRiXIfXU30PKYMsdbqYbGK8iHF8KqyPi0qdXT2wAuE=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.47.0 h1:2lDw6AKPV33/7Qw9oN5YdxuSJIlUz7q3tkfSlJX5rh0=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.47.0/go.mod h1:y1ORt/QAquBL+O3I06KE7iMENp9p05iBqaV4xNF3J7k=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.38.0 h1:8aH+9AGEhOpbDKahZkwWcxiwoMYH+rlRRz5nD33ttrI=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.38.0/go.mod h1:ZiDcJub/DU2OwJWQrGYhVB9rz6QlGgq4RYgmargUSwY=
|
||||
go.opentelemetry.io/otel v1.47.0 h1:j7ALJ/zgkS7Z6aeJW09p8VC9804bC+PpeTfCD4XPnOM=
|
||||
go.opentelemetry.io/otel v1.47.0/go.mod h1:8wS9O2qfXrYrzp6hIF/HOYJJf/wIhFPhR2xLuP+iXQU=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||
@@ -517,12 +515,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0 h1:qkD
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0/go.mod h1:tkipS4DRzmpAmvg+Gw4++O1IdDq6TVDnvnYU6cmbQVs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.46.0 h1:AP23h/mFgb/lc7tdck1Kfn9qxsM8TAeNPCU5C3pzaps=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.46.0/go.mod h1:K4EqCe1b4kGk5WR690ntg9LaBfsPoV32FwthbyoptuA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 h1:OFnwLJr+pF3iHrlGSzbxyuo6/6HyBlnlN1CWEJmBVcw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0/go.mod h1:716wFneO0ov19A2beH5hjfh9AK5z/VWNAtDijp1Y0/g=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.47.0 h1:julhjPeUH/q/7hinbSdDdqt5h7Zw9YWmRlWRhI0jd54=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.47.0/go.mod h1:Ao2mz688LH/tFf0yMAenidq6k2YNSx6SIY2q6jDACck=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 h1:w53CDeOA/Kurp7yRsegSr6pbbr759dOvJ+yNmWM6Hxs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0/go.mod h1:BOmGMCbAtvcJiSJ+hLuhgPLdDbimnraSl8irz3iY8sY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0 h1:KrC1YrQeSt46ITMWAbgQx1M1eV1/1TKzttrBzymPmss=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0/go.mod h1:zDSEzoEqsOrgBeGvH66KRgxh90VonFyJqBHA0Pk3+rM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.47.0 h1:aXZXsZ012wOgVkqaiQv+Z/d8V0xKjmg70F6m4CE94lc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.47.0/go.mod h1:ziu1gUIJhAaxM3EV1e3Ralk5AAyL1UOYz3lJJ4VSI38=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.68.0 h1:QOf2IftqQwITVRJpnn0M7M9ZCbgWfxz4P7i9C9yc2N4=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.68.0/go.mod h1:bgSvqu2TWGXiz7yr5UTMfObH8oqxJWHTnubQ3ef9BO4=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.22.0 h1:kvMAiLEudKmk+CSG+iYbU8vTUGNNDaf/V09OO5lrTwI=
|
||||
@@ -531,8 +529,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.46.0 h1:PR9eAf7o0dQs3h
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.46.0/go.mod h1:2Z4KyNdH1uuzivdinyfGsxzNNT/Rl45pwtVwfYVI0xk=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0 h1:KdRxPiAoMptR3vfWzvjjvutTsSiwbC2uG0496rzZNfo=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0/go.mod h1:K/qSA+3G7Eovxi4K09wzrAgkWRnosS0DAOZeEpve7sM=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.46.0 h1:7y0nqfbwuPdaYKwm35PRMRMOa8iYu1SXxnAJNNR2o1M=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.46.0/go.mod h1:MGmDLXGsdDzWBOt0y5VcW2u5hRsFV4MzylPvvNkQ9qw=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.47.0 h1:4oTg347RRFG5HYiDFr6vnzj3BzsT5BNnSB1n6a4wAcg=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.47.0/go.mod h1:nZy5oQ8jLItEWTbifyWwwfcOSf/8wLabOwq+PI0oAKg=
|
||||
go.opentelemetry.io/otel/log v1.47.0 h1:cOTS1CcLbSQeZKanGJ+0JpF/+t4PELi3O3bbl2lqCcI=
|
||||
go.opentelemetry.io/otel/log v1.47.0/go.mod h1:9byitSQ5pLC6PpqwGXjqdMKya6ZTswHRZh2vvXT33nw=
|
||||
go.opentelemetry.io/otel/metric v1.47.0 h1:4PptaldXx3Eat1XjMZ68pPJEs5wrhlemctZE9a3UdWY=
|
||||
@@ -549,8 +547,8 @@ go.opentelemetry.io/otel/sdk/metric v1.47.0 h1:lfISg2j93VT6yqdk9OfUaZmw/GfcZqCCV
|
||||
go.opentelemetry.io/otel/sdk/metric v1.47.0/go.mod h1:ypLp+mW1Nt2x+Szt3b5/i1syodyts49lMOwxpDI3VGw=
|
||||
go.opentelemetry.io/otel/trace v1.47.0 h1:JOjX/Oci8K94QHddo+bbfya/Ai/nf6/dt9ZfrFNWSrM=
|
||||
go.opentelemetry.io/otel/trace v1.47.0/go.mod h1:jNaSLa2PZEYFG6fRjJABAu+bw4FS08uDmPg28lTghu0=
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk=
|
||||
go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E=
|
||||
go.opentelemetry.io/proto/otlp v1.11.1 h1:SCrPqH9NE5CmBrOqpjNCiT0X5mGwMyGERXdogfR7Yjw=
|
||||
go.opentelemetry.io/proto/otlp v1.11.1/go.mod h1:wq8W4aSf6bOy8RZyESOeQFr9Pu7wydWX/TY4sgvrTPg=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
@@ -571,8 +569,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
|
||||
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
|
||||
golang.org/x/crypto v0.58.0 h1:COkYLr4k7nDI4r6QtMML2AfzeIswWHAJthLS6K/M/54=
|
||||
golang.org/x/crypto v0.58.0/go.mod h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w=
|
||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba h1:Ck8QetSgk912qxWLMCKxd0in+aiyBQyDSMae6e/xmpU=
|
||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba/go.mod h1:50RgIsmK7OwqzTTeqcSXQW8SswW0o8fRcDxmqGluJ8E=
|
||||
golang.org/x/image v0.46.0 h1:b1+oYj0Jbp6K5MDT4i4/eZpYlk3V8SJhhDKh6LBHAyQ=
|
||||
@@ -585,8 +583,8 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
|
||||
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
|
||||
golang.org/x/mod v0.42.0 h1:ICeL3t2L30ljSPHHxDnR4fqVcBt/zR2zJAb9juavmQg=
|
||||
golang.org/x/mod v0.42.0/go.mod h1:u5fzIrRInkL8MaO1cbRkUHT64v303YIT5KEqpNr7jRs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -606,8 +604,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
|
||||
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
|
||||
golang.org/x/net v0.61.0 h1:RR+6j/BTBCrggOLugxa+66R8FvoN6MHlzDlZIbN9YFw=
|
||||
golang.org/x/net v0.61.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
|
||||
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
|
||||
@@ -637,8 +635,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
|
||||
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
|
||||
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
|
||||
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -659,8 +657,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
|
||||
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
|
||||
golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc=
|
||||
golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s=
|
||||
golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=
|
||||
golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -672,8 +670,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=
|
||||
golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=
|
||||
golang.org/x/tools v0.52.0 h1:ryxg4U63oaUYk7uOLTF37n43f4qgtGvqV4Ioit1BaEs=
|
||||
golang.org/x/tools v0.52.0/go.mod h1:ItcP5UNaVGG+Yc4eIYmaFLNJ4soEopkx5Y2d4lcEurs=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -681,12 +679,12 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260918162117-cecb64721679 h1:FEp7JNE32DTAwbnI/ixagnmj7Xm1eTONofGEUXFjZ4w=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260918162117-cecb64721679/go.mod h1:52bV8FLAQ9Qmcqaq9ECLmuEHZthk+6OPV45aKBBrsNw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679 h1:KmqdJU4vrNcxy/6qdg3JduZtalEXrJLspVltnR1cE+8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679/go.mod h1:OaIUM3+LpYcK2GXM4FTmhWoIq371Owdr+Cc7/BsYHHc=
|
||||
google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
|
||||
google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8 h1:cFbkNigDInw+wVTXc+CyhUsoHGJCw0BR6mlNoRVfre0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8/go.mod h1:QK6p7IgD7IZEZJBhhSUCib5X2vMOzlrGCGUw2XyVDh0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 h1:0SXBqli5dnuCKMjI/X3FM226zEaEa0GUcSCJtN1vL2o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8/go.mod h1:OaIUM3+LpYcK2GXM4FTmhWoIq371Owdr+Cc7/BsYHHc=
|
||||
google.golang.org/grpc v1.84.0 h1:soMyaPJ8pAak5PIQ0DGBUir0XRo2fRoMqhNWMLlLxO0=
|
||||
google.golang.org/grpc v1.84.0/go.mod h1:ljCht0DrxQrXBDRTZp52Qxh3Ffk8CdYm2sj4O2QN2C0=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
)
|
||||
|
||||
// NewAccessTokenStrategy applies Pocket ID's identity-audience policy to the provided access token strategy
|
||||
func NewAccessTokenStrategy(coreStrategy fositeoauth2.CoreStrategy, issuer string) fositeoauth2.CoreStrategy {
|
||||
func NewAccessTokenStrategy(accessTokenStrategy fositeoauth2.AccessTokenStrategy, issuer string) fositeoauth2.AccessTokenStrategy {
|
||||
return identityAudienceAccessTokenStrategy{
|
||||
CoreStrategy: coreStrategy,
|
||||
issuer: issuer,
|
||||
AccessTokenStrategy: accessTokenStrategy,
|
||||
issuer: issuer,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,10 @@ func (r identityAudienceRequester) GetGrantedAudience() fosite.Arguments {
|
||||
|
||||
// identityAudienceAccessTokenStrategy wraps the access token strategy so an access token granted an identity scope also lists the issuer in its audience, keeping the self-contained JWT consistent with what is persisted for introspection and userinfo
|
||||
type identityAudienceAccessTokenStrategy struct {
|
||||
fositeoauth2.CoreStrategy
|
||||
fositeoauth2.AccessTokenStrategy
|
||||
issuer string
|
||||
}
|
||||
|
||||
func (s identityAudienceAccessTokenStrategy) GenerateAccessToken(ctx context.Context, requester fosite.Requester) (string, string, error) {
|
||||
return s.CoreStrategy.GenerateAccessToken(ctx, withIdentityAudience(requester, s.issuer))
|
||||
return s.AccessTokenStrategy.GenerateAccessToken(ctx, withIdentityAudience(requester, s.issuer))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package oidc
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/authz"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"slices"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/lestrrat-go/jwx/v4/jwa"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/authz"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils/cookie"
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDeviceCodeExchangeConsumesOpenIDConnectSession(t *testing.T) {
|
||||
const (
|
||||
userID = "test-user"
|
||||
clientID = "test-client"
|
||||
)
|
||||
service, store, provider, userCode, deviceCode := newTestDeviceServiceWithCode(t, clientID, userID, false, nil)
|
||||
require.NoError(t, service.acceptDeviceCode(t.Context(), userCode, userID, "phr", time.Now().UTC(), "", requestMeta{}))
|
||||
|
||||
signature, err := provider.deviceStrategy.DeviceCodeSignature(t.Context(), deviceCode)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The approved authorization keeps an OpenID Connect session that expires together with the device code
|
||||
var deviceSession, openIDSession OAuth2Session
|
||||
require.NoError(t, store.db.First(&deviceSession, "kind = ? AND key = ?", sessionKindDeviceCode, signature).Error)
|
||||
require.NoError(t, store.db.First(&openIDSession, "kind = ? AND key = ?", sessionKindOpenID, signature).Error)
|
||||
require.NotNil(t, deviceSession.ExpiresAt)
|
||||
require.NotNil(t, openIDSession.ExpiresAt)
|
||||
require.True(t, deviceSession.ExpiresAt.ToTime().Equal(openIDSession.ExpiresAt.ToTime()))
|
||||
|
||||
// The token exchange issues an ID token and consumes the OpenID Connect session
|
||||
response, err := exchangeDeviceCode(t, provider, clientID, deviceCode)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, response.GetExtra("id_token"))
|
||||
|
||||
var count int64
|
||||
require.NoError(t, store.db.Model(&OAuth2Session{}).Where("kind = ?", sessionKindOpenID).Count(&count).Error)
|
||||
require.Zero(t, count)
|
||||
require.NoError(t, store.db.Model(&OAuth2Session{}).Where("kind = ? AND request_id = ?", sessionKindAccessToken, deviceSession.RequestID).Count(&count).Error)
|
||||
require.EqualValues(t, 1, count)
|
||||
|
||||
// A replayed device code is rejected before an OpenID Connect session could be reused
|
||||
_, err = exchangeDeviceCode(t, provider, clientID, deviceCode)
|
||||
require.ErrorIs(t, err, fosite.ErrInvalidGrant)
|
||||
|
||||
// The replay revokes the access token that the first exchange issued
|
||||
require.NoError(t, store.db.Model(&OAuth2Session{}).Where("kind = ? AND request_id = ?", sessionKindAccessToken, deviceSession.RequestID).Count(&count).Error)
|
||||
require.Zero(t, count)
|
||||
}
|
||||
|
||||
func TestStoreInvalidateDeviceCodeSessionReportsLostRaceAsInvalidGrant(t *testing.T) {
|
||||
_, store, provider, _, deviceCode := newTestDeviceServiceWithCode(t, "test-client", "test-user", false, nil)
|
||||
|
||||
signature, err := provider.deviceStrategy.DeviceCodeSignature(t.Context(), deviceCode)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The first redemption wins and a concurrent second one must not mint another token set
|
||||
require.NoError(t, store.InvalidateDeviceCodeSession(t.Context(), signature))
|
||||
require.ErrorIs(t, store.InvalidateDeviceCodeSession(t.Context(), signature), fosite.ErrInvalidGrant)
|
||||
}
|
||||
|
||||
// exchangeDeviceCode redeems the device code at the token endpoint like a polling device would
|
||||
func exchangeDeviceCode(t *testing.T, provider *oidcProvider, clientID, deviceCode string) (fosite.AccessResponder, error) {
|
||||
t.Helper()
|
||||
|
||||
form := url.Values{
|
||||
"grant_type": {string(fosite.GrantTypeDeviceCode)},
|
||||
"device_code": {deviceCode},
|
||||
"client_id": {clientID},
|
||||
}
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/api/oidc/token", strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
accessRequest, err := provider.NewAccessRequest(t.Context(), req, NewEmptySession())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return provider.NewAccessResponse(t.Context(), accessRequest)
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/rfc8628"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/fosite/handler/rfc8628"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
@@ -135,6 +135,9 @@ func (s *deviceService) acceptDeviceCode(ctx context.Context, userCode, userID,
|
||||
|
||||
session := NewAuthenticatedSession(userID, authenticationMethod, authenticationTime, request.GetRequestedAt())
|
||||
|
||||
// Keep the lifetimes of the pending device authorization, so its codes and the OpenID Connect session created below still expire
|
||||
copyDeviceCodeExpiry(request.GetSession(), session)
|
||||
|
||||
if err = s.claimsService.applyIDTokenClaims(ctx, session, request.GetGrantedScopes()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -166,6 +169,18 @@ func (s *deviceService) acceptDeviceCode(ctx context.Context, userCode, userID,
|
||||
})
|
||||
}
|
||||
|
||||
// copyDeviceCodeExpiry copies the device and user code expiry from the pending device authorization's session to the session that replaces it
|
||||
func copyDeviceCodeExpiry(from fosite.Session, to *Session) {
|
||||
if from == nil {
|
||||
return
|
||||
}
|
||||
for _, tokenType := range []fosite.TokenType{fosite.DeviceCode, fosite.UserCode} {
|
||||
if expiresAt := from.GetExpiresAt(tokenType); !expiresAt.IsZero() {
|
||||
to.SetExpiresAt(tokenType, expiresAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *deviceService) loadDeviceAuthorizationUser(ctx context.Context, userID string) (model.User, error) {
|
||||
tx := s.db.Begin()
|
||||
defer func() {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
testutils "github.com/pocket-id/pocket-id/backend/internal/utils/testing"
|
||||
|
||||
@@ -3,7 +3,7 @@ package oidc
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ory/fosite/handler/rfc8628"
|
||||
"github.com/pocket-id/fosite/handler/rfc8628"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/lestrrat-go/jwx/v4/jwk"
|
||||
"github.com/lestrrat-go/jwx/v4/jws"
|
||||
"github.com/lestrrat-go/jwx/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
jwkutils "github.com/pocket-id/pocket-id/backend/internal/utils/jwk"
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/lestrrat-go/jwx/v4/jwa"
|
||||
"github.com/lestrrat-go/jwx/v4/jwk"
|
||||
"github.com/lestrrat-go/jwx/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
)
|
||||
|
||||
type introspectionHandler struct {
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/lestrrat-go/jwx/v4/jwa"
|
||||
"github.com/lestrrat-go/jwx/v4/jwk"
|
||||
"github.com/lestrrat-go/jwx/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
)
|
||||
|
||||
type parHandler struct {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
jwxjwt "github.com/lestrrat-go/jwx/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/fosite/compose"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite/handler/openid"
|
||||
"github.com/pocket-id/fosite/token/jwt"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
)
|
||||
@@ -65,15 +65,12 @@ func newProvider(store *Store, authenticator *federatedClientAuthenticator, sign
|
||||
return SigningKeyFromSigner(signer)
|
||||
}
|
||||
sig := newJWTSigner(keyGetter)
|
||||
coreStrategy := compose.NewOAuth2HMACStrategy(fositeConfig)
|
||||
deviceStrategy := &deviceStrategy{DefaultDeviceStrategy: compose.NewDeviceStrategy(fositeConfig)}
|
||||
defaultAccessTokenStrategy := &fositeoauth2.DefaultJWTStrategy{
|
||||
Signer: sig,
|
||||
HMACSHAStrategy: coreStrategy,
|
||||
Config: fositeConfig,
|
||||
}
|
||||
rfc9068AccessTokenStrategy := &fositeoauth2.RFC9068JWTStrategy{
|
||||
DefaultJWTStrategy: defaultAccessTokenStrategy,
|
||||
DefaultJWTStrategy: &fositeoauth2.DefaultJWTStrategy{
|
||||
Signer: sig,
|
||||
Config: fositeConfig,
|
||||
},
|
||||
}
|
||||
|
||||
// Apply Pocket ID's identity-audience policy outside Fosite's reusable RFC 9068 token profile
|
||||
@@ -85,11 +82,12 @@ func newProvider(store *Store, authenticator *federatedClientAuthenticator, sign
|
||||
provider := compose.Compose(
|
||||
fositeConfig,
|
||||
store,
|
||||
&compose.CommonStrategy{
|
||||
CoreStrategy: accessTokenStrategy,
|
||||
RFC8628CodeStrategy: deviceStrategy,
|
||||
OpenIDConnectTokenStrategy: idTokenStrategy,
|
||||
Signer: sig,
|
||||
&strategyProvider{
|
||||
opaque: compose.NewOAuth2HMACStrategy(fositeConfig),
|
||||
accessToken: accessTokenStrategy,
|
||||
device: deviceStrategy,
|
||||
idToken: idTokenStrategy,
|
||||
Signer: sig,
|
||||
},
|
||||
compose.OAuth2AuthorizeExplicitFactory,
|
||||
compose.OAuth2ClientCredentialsGrantFactory,
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/lestrrat-go/jwx/v4/jwa"
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
|
||||
testutils "github.com/pocket-id/pocket-id/backend/internal/utils/testing"
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/fosite/compose"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"time"
|
||||
"uuid"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pocket-id/fosite"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite/handler/openid"
|
||||
fositejwt "github.com/pocket-id/fosite/token/jwt"
|
||||
)
|
||||
|
||||
var _ openid.Session = (*Session)(nil)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/pocket-id/fosite/token/jwt"
|
||||
)
|
||||
|
||||
// SigningKeyFromSigner wraps the raw signing key in a *jose.JSONWebKey that carries the
|
||||
|
||||
@@ -10,12 +10,11 @@ import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/handler/pkce"
|
||||
"github.com/ory/fosite/handler/rfc8628"
|
||||
fositestorage "github.com/ory/fosite/storage"
|
||||
"github.com/pocket-id/fosite"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite/handler/openid"
|
||||
"github.com/pocket-id/fosite/handler/pkce"
|
||||
"github.com/pocket-id/fosite/handler/rfc8628"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
|
||||
"gorm.io/gorm"
|
||||
@@ -35,14 +34,17 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
_ fosite.Storage = (*Store)(nil)
|
||||
_ fosite.PARStorage = (*Store)(nil)
|
||||
_ fositeoauth2.CoreStorage = (*Store)(nil)
|
||||
_ fositeoauth2.TokenRevocationStorage = (*Store)(nil)
|
||||
_ rfc8628.RFC8628CoreStorage = (*Store)(nil)
|
||||
_ openid.OpenIDConnectRequestStorage = (*Store)(nil)
|
||||
_ pkce.PKCERequestStorage = (*Store)(nil)
|
||||
_ fositestorage.Transactional = (*Store)(nil)
|
||||
_ fosite.Storage = (*Store)(nil)
|
||||
_ fosite.ClientManager = (*Store)(nil)
|
||||
_ fosite.PARStorageProvider = (*Store)(nil)
|
||||
_ fositeoauth2.AuthorizeCodeStorageProvider = (*Store)(nil)
|
||||
_ fositeoauth2.AccessTokenStorageProvider = (*Store)(nil)
|
||||
_ fositeoauth2.RefreshTokenStorageProvider = (*Store)(nil)
|
||||
_ fositeoauth2.TokenRevocationStorageProvider = (*Store)(nil)
|
||||
_ rfc8628.DeviceAuthStorageProvider = (*Store)(nil)
|
||||
_ openid.OpenIDConnectRequestStorageProvider = (*Store)(nil)
|
||||
_ pkce.PKCERequestStorageProvider = (*Store)(nil)
|
||||
_ fosite.Transactional = (*Store)(nil)
|
||||
)
|
||||
|
||||
// NewStore creates the fosite storage. Exported for packages that need to seed or
|
||||
@@ -88,7 +90,7 @@ type storedRequester struct {
|
||||
DefaultResponseMode fosite.ResponseModeType `json:"default_response_mode,omitempty"`
|
||||
}
|
||||
|
||||
// Satisfies fosite.Storage
|
||||
// Satisfies fosite.ClientManager
|
||||
|
||||
func (s *Store) GetClient(ctx context.Context, id string) (fosite.Client, error) {
|
||||
tx := s.dbFor(ctx)
|
||||
@@ -324,14 +326,14 @@ func (s *Store) firstClientByID(ctx context.Context, id string) (model.OidcClien
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// Satisfies fositeoauth2.CoreStorage
|
||||
// Satisfies fositeoauth2.AuthorizeCodeStorage, fositeoauth2.AccessTokenStorage and fositeoauth2.RefreshTokenStorage
|
||||
|
||||
func (s *Store) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) error {
|
||||
return s.upsertSession(ctx, sessionKindAuthorizeCode, code, request, "", true, fosite.AuthorizeCode)
|
||||
func (s *Store) CreateAuthorizeCodeSession(ctx context.Context, signature string, request fosite.Requester) error {
|
||||
return s.upsertSession(ctx, sessionKindAuthorizeCode, signature, request, "", true, fosite.AuthorizeCode)
|
||||
}
|
||||
|
||||
func (s *Store) GetAuthorizeCodeSession(ctx context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
|
||||
request, active, err := s.getRequesterSession(ctx, sessionKindAuthorizeCode, code)
|
||||
func (s *Store) GetAuthorizeCodeSession(ctx context.Context, _ string, signature string, _ fosite.Session) (fosite.Requester, error) {
|
||||
request, active, err := s.getRequesterSession(ctx, sessionKindAuthorizeCode, signature)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -341,8 +343,14 @@ func (s *Store) GetAuthorizeCodeSession(ctx context.Context, code string, _ fosi
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (s *Store) InvalidateAuthorizeCodeSession(ctx context.Context, code string) error {
|
||||
return s.deactivateSession(ctx, sessionKindAuthorizeCode, code)
|
||||
func (s *Store) InvalidateAuthorizeCodeSession(ctx context.Context, _ string, signature string) error {
|
||||
err := s.deactivateSession(ctx, sessionKindAuthorizeCode, signature)
|
||||
|
||||
// The code was active when the token request read it, so a missing active row means a concurrent request redeemed it first
|
||||
if errors.Is(err, fosite.ErrNotFound) {
|
||||
return fosite.ErrInvalidGrant.WithHint("The authorization code has already been used.")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) CreateAccessTokenSession(ctx context.Context, signature string, request fosite.Requester) error {
|
||||
@@ -524,19 +532,25 @@ func (s *Store) CreatePKCERequestSession(ctx context.Context, signature string,
|
||||
return s.upsertSession(ctx, sessionKindPKCE, signature, requester, "", true, fosite.AuthorizeCode)
|
||||
}
|
||||
|
||||
func (s *Store) GetPKCERequestSession(ctx context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
|
||||
func (s *Store) GetPKCERequestSession(ctx context.Context, _ string, signature string, _ fosite.Session) (fosite.Requester, error) {
|
||||
request, _, err := s.getRequesterSession(ctx, sessionKindPKCE, signature)
|
||||
return request, err
|
||||
}
|
||||
|
||||
func (s *Store) DeletePKCERequestSession(ctx context.Context, signature string) error {
|
||||
func (s *Store) DeletePKCERequestSession(ctx context.Context, _ string, signature string) error {
|
||||
return s.deleteSession(ctx, sessionKindPKCE, signature)
|
||||
}
|
||||
|
||||
// Satisfies openid.OpenIDConnectRequestStorage
|
||||
|
||||
func (s *Store) CreateOpenIDConnectSession(ctx context.Context, authorizeCode string, requester fosite.Requester) error {
|
||||
return s.upsertSession(ctx, sessionKindOpenID, authorizeCode, requester, "", true, fosite.AuthorizeCode)
|
||||
// Sessions of the device authorization grant are keyed by the device code signature and expire together with the device code
|
||||
// An expiry ensures the cleanup job removes sessions whose code is never redeemed
|
||||
expiresAtKey := fosite.AuthorizeCode
|
||||
if session := requester.GetSession(); session != nil && session.GetExpiresAt(fosite.AuthorizeCode).IsZero() {
|
||||
expiresAtKey = fosite.DeviceCode
|
||||
}
|
||||
return s.upsertSession(ctx, sessionKindOpenID, authorizeCode, requester, "", true, expiresAtKey)
|
||||
}
|
||||
|
||||
func (s *Store) GetOpenIDConnectSession(ctx context.Context, authorizeCode string, _ fosite.Requester) (fosite.Requester, error) {
|
||||
@@ -584,7 +598,7 @@ func (s *Store) DeletePARSession(ctx context.Context, requestURI string) error {
|
||||
return s.deleteSession(ctx, sessionKindPAR, requestURI)
|
||||
}
|
||||
|
||||
// Satisfies rfc8628.RFC8628CoreStorage
|
||||
// Satisfies rfc8628.DeviceAuthStorage
|
||||
|
||||
func (s *Store) CreateDeviceAuthSession(ctx context.Context, deviceCodeSignature, userCodeSignature string, request fosite.DeviceRequester) error {
|
||||
requestData, err := s.encodeDeviceRequester(request)
|
||||
@@ -633,7 +647,8 @@ func (s *Store) InvalidateDeviceCodeSession(ctx context.Context, signature strin
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return fosite.ErrNotFound
|
||||
// The device code was active when the token request read it, so a concurrent request redeemed it first
|
||||
return fosite.ErrInvalidGrant.WithHint("The device code has already been used.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -709,30 +724,9 @@ func (s *Store) AcceptDeviceCodeSessionByUserCodeSignature(ctx context.Context,
|
||||
return deviceCodeSignature, err
|
||||
}
|
||||
|
||||
// Satisfies fositestorage.Transactional
|
||||
|
||||
func (s *Store) BeginTX(ctx context.Context) (context.Context, error) {
|
||||
tx := s.db.WithContext(ctx).Begin()
|
||||
if tx.Error != nil {
|
||||
return ctx, tx.Error
|
||||
}
|
||||
return contextWithTx(ctx, tx), nil
|
||||
}
|
||||
|
||||
func (s *Store) Commit(ctx context.Context) error {
|
||||
tx, ok := ctx.Value(txContextKey{}).(*gorm.DB)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return tx.Commit().Error
|
||||
}
|
||||
|
||||
func (s *Store) Rollback(ctx context.Context) error {
|
||||
tx, ok := ctx.Value(txContextKey{}).(*gorm.DB)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return tx.Rollback().Error
|
||||
// Satisfies fosite.Transactional
|
||||
func (s *Store) Transaction(ctx context.Context, fn func(ctx context.Context) error) error {
|
||||
return withTx(ctx, s.db, fn)
|
||||
}
|
||||
|
||||
func (s *Store) upsertSession(ctx context.Context, kind string, key string, requester fosite.Requester, accessTokenSignature string, active bool, expiresAtKey fosite.TokenType) error {
|
||||
@@ -1104,3 +1098,41 @@ func expiresAt(session fosite.Session, tokenType fosite.TokenType) *datatype.Dat
|
||||
func (s *Store) dbFor(ctx context.Context) *gorm.DB {
|
||||
return dbFromContext(ctx, s.db)
|
||||
}
|
||||
|
||||
// Fosite reaches every storage through a provider accessor, and Store implements all of them itself
|
||||
|
||||
func (s *Store) FositeClientManager() fosite.ClientManager {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) AuthorizeCodeStorage() fositeoauth2.AuthorizeCodeStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) AccessTokenStorage() fositeoauth2.AccessTokenStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) RefreshTokenStorage() fositeoauth2.RefreshTokenStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) TokenRevocationStorage() fositeoauth2.TokenRevocationStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) OpenIDConnectRequestStorage() openid.OpenIDConnectRequestStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) PKCERequestStorage() pkce.PKCERequestStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) DeviceAuthStorage() rfc8628.DeviceAuthStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) PARStorage() fosite.PARStorage {
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pocket-id/fosite"
|
||||
fositejwt "github.com/pocket-id/fosite/token/jwt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
@@ -69,8 +69,9 @@ func TestStoreInvalidateAuthorizeCodeSessionIsAtomic(t *testing.T) {
|
||||
store := NewStore(db, nil)
|
||||
|
||||
const (
|
||||
clientID = "code-client"
|
||||
code = "auth-code-single-use"
|
||||
clientID = "code-client"
|
||||
code = "auth-code-single-use"
|
||||
signature = "auth-code-single-use-signature"
|
||||
)
|
||||
require.NoError(t, db.Create(&model.OidcClient{Base: model.Base{ID: clientID}, Name: "Code Client"}).Error)
|
||||
|
||||
@@ -84,17 +85,17 @@ func TestStoreInvalidateAuthorizeCodeSessionIsAtomic(t *testing.T) {
|
||||
Form: url.Values{},
|
||||
Session: session,
|
||||
}
|
||||
require.NoError(t, store.CreateAuthorizeCodeSession(t.Context(), code, request))
|
||||
require.NoError(t, store.CreateAuthorizeCodeSession(t.Context(), signature, request))
|
||||
|
||||
// First invalidation wins.
|
||||
require.NoError(t, store.InvalidateAuthorizeCodeSession(t.Context(), code))
|
||||
require.NoError(t, store.InvalidateAuthorizeCodeSession(t.Context(), code, signature))
|
||||
|
||||
// A second invalidation of the now-inactive code fails closed: a racing token request
|
||||
// cannot proceed to issue a second set of tokens from the same code.
|
||||
require.ErrorIs(t, store.InvalidateAuthorizeCodeSession(t.Context(), code), fosite.ErrNotFound)
|
||||
// cannot proceed to issue a second set of tokens from the same code, and the client gets invalid_grant.
|
||||
require.ErrorIs(t, store.InvalidateAuthorizeCodeSession(t.Context(), code, signature), fosite.ErrInvalidGrant)
|
||||
|
||||
// Reads of the consumed code report it as invalidated so fosite triggers reuse handling.
|
||||
_, err := store.GetAuthorizeCodeSession(t.Context(), code, nil)
|
||||
_, err := store.GetAuthorizeCodeSession(t.Context(), code, signature, nil)
|
||||
require.ErrorIs(t, err, fosite.ErrInvalidatedAuthorizeCode)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
"github.com/pocket-id/fosite/handler/openid"
|
||||
"github.com/pocket-id/fosite/handler/rfc8628"
|
||||
"github.com/pocket-id/fosite/token/jwt"
|
||||
)
|
||||
|
||||
// strategyProvider hands every Fosite handler the token strategy it needs
|
||||
type strategyProvider struct {
|
||||
opaque fositeoauth2.CoreStrategy
|
||||
accessToken fositeoauth2.AccessTokenStrategy
|
||||
device *deviceStrategy
|
||||
idToken openid.OpenIDConnectTokenStrategy
|
||||
|
||||
jwt.Signer
|
||||
}
|
||||
|
||||
var (
|
||||
_ fositeoauth2.AuthorizeCodeStrategyProvider = (*strategyProvider)(nil)
|
||||
_ fositeoauth2.AccessTokenStrategyProvider = (*strategyProvider)(nil)
|
||||
_ fositeoauth2.RefreshTokenStrategyProvider = (*strategyProvider)(nil)
|
||||
_ openid.OpenIDConnectTokenStrategyProvider = (*strategyProvider)(nil)
|
||||
_ rfc8628.DeviceRateLimitStrategyProvider = (*strategyProvider)(nil)
|
||||
_ rfc8628.DeviceCodeStrategyProvider = (*strategyProvider)(nil)
|
||||
_ rfc8628.UserCodeStrategyProvider = (*strategyProvider)(nil)
|
||||
_ jwt.Signer = (*strategyProvider)(nil)
|
||||
)
|
||||
|
||||
func (s *strategyProvider) AuthorizeCodeStrategy() fositeoauth2.AuthorizeCodeStrategy {
|
||||
return s.opaque
|
||||
}
|
||||
|
||||
func (s *strategyProvider) AccessTokenStrategy() fositeoauth2.AccessTokenStrategy {
|
||||
return s.accessToken
|
||||
}
|
||||
|
||||
func (s *strategyProvider) RefreshTokenStrategy() fositeoauth2.RefreshTokenStrategy {
|
||||
return s.opaque
|
||||
}
|
||||
|
||||
func (s *strategyProvider) OpenIDConnectTokenStrategy() openid.OpenIDConnectTokenStrategy {
|
||||
return s.idToken
|
||||
}
|
||||
|
||||
func (s *strategyProvider) DeviceRateLimitStrategy() rfc8628.DeviceRateLimitStrategy {
|
||||
return s.device
|
||||
}
|
||||
|
||||
func (s *strategyProvider) DeviceCodeStrategy() rfc8628.DeviceCodeStrategy {
|
||||
return s.device
|
||||
}
|
||||
|
||||
func (s *strategyProvider) UserCodeStrategy() rfc8628.UserCodeStrategy {
|
||||
return s.device
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"slices"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
)
|
||||
|
||||
type tokenHandler struct {
|
||||
|
||||
@@ -15,10 +15,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/fosite/compose"
|
||||
fositeoauth2 "github.com/pocket-id/fosite/handler/oauth2"
|
||||
fositejwt "github.com/pocket-id/fosite/token/jwt"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/model"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/pocket-id/fosite"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
|
||||
@@ -20,9 +20,9 @@ import (
|
||||
"github.com/lestrrat-go/jwx/v4/jwa"
|
||||
"github.com/lestrrat-go/jwx/v4/jwk"
|
||||
"github.com/lestrrat-go/jwx/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pocket-id/fosite"
|
||||
"github.com/pocket-id/fosite/compose"
|
||||
fositejwt "github.com/pocket-id/fosite/token/jwt"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apikey"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
|
||||
"gorm.io/gorm"
|
||||
@@ -905,20 +905,14 @@ func seededRefreshTokenFixture(userID string, clientID string, fixtureRefreshTok
|
||||
}
|
||||
|
||||
func (s *TestService) SignAccessToken(ctx context.Context, userID, clientID string, expired bool) (string, error) {
|
||||
globalSecret, err := oidc.DeriveGlobalSecret(common.EnvConfig.EncryptionKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fositeConfig := &fosite.Config{
|
||||
GlobalSecret: globalSecret,
|
||||
AccessTokenLifespan: AccessTokenDuration,
|
||||
AccessTokenIssuer: common.EnvConfig.AppURL,
|
||||
}
|
||||
coreStrategy := compose.NewOAuth2HMACStrategy(fositeConfig)
|
||||
keyGetter := func(context.Context) (interface{}, error) {
|
||||
return oidc.SigningKeyFromSigner(s.jwtService)
|
||||
}
|
||||
strategy := oidc.NewAccessTokenStrategy(compose.NewOAuth2RFC9068JWTStrategy(keyGetter, coreStrategy, fositeConfig), common.EnvConfig.AppURL)
|
||||
strategy := oidc.NewAccessTokenStrategy(compose.NewOAuth2RFC9068JWTStrategy(keyGetter, fositeConfig), common.EnvConfig.AppURL)
|
||||
|
||||
expiresAt := time.Now().UTC().Add(AccessTokenDuration)
|
||||
if expired {
|
||||
|
||||
@@ -24,6 +24,8 @@ services:
|
||||
ENCRYPTION_KEY: test-encryption-key
|
||||
FILE_BACKEND: ${FILE_BACKEND}
|
||||
OUTBOUND_ALLOWED_HOSTS_BACKCHANNEL_LOGOUT: private,loopback,host.docker.internal
|
||||
OUTBOUND_ALLOWED_HOSTS_SCIM: private,loopback,host.docker.internal
|
||||
OUTBOUND_ALLOWED_HOSTS_FEDERATED_JWKS: private,loopback,host.docker.internal
|
||||
volumes:
|
||||
- pocket-id-test-data:/app/data
|
||||
build:
|
||||
|
||||
Reference in New Issue
Block a user