mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-24 19:09:03 +03:00
Compare commits
30 Commits
v2.2.0
...
fix/callba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ba3a7e13c | ||
|
|
280d603617 | ||
|
|
0678699d0c | ||
|
|
4f82957e13 | ||
|
|
5e2534bd6b | ||
|
|
eb0456a395 | ||
|
|
f0249377ac | ||
|
|
97f2e4eec2 | ||
|
|
adbdfcf9ff | ||
|
|
94a48977ba | ||
|
|
5ab0996475 | ||
|
|
60825c5743 | ||
|
|
310b81c277 | ||
|
|
549b487663 | ||
|
|
6eebecd85a | ||
|
|
1de231f1ff | ||
|
|
aab7e364e8 | ||
|
|
56afebc242 | ||
|
|
bb7b0d5608 | ||
|
|
80558c5625 | ||
|
|
a5629e63d2 | ||
|
|
317879bb37 | ||
|
|
c62533d388 | ||
|
|
0978a89fcc | ||
|
|
53ef61a3e5 | ||
|
|
4811625cdd | ||
|
|
9dbc02e568 | ||
|
|
43a1e4a25b | ||
|
|
e78b16d0c6 | ||
|
|
1967de6828 |
@@ -4,6 +4,6 @@ package frontend
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
func RegisterFrontend(router *gin.Engine) error {
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) error {
|
||||
return ErrFrontendNotIncluded
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterFrontend(router *gin.Engine) error {
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) error {
|
||||
distFS, err := fs.Sub(frontendFS, "dist")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create sub FS: %w", err)
|
||||
@@ -61,7 +61,7 @@ func RegisterFrontend(router *gin.Engine) error {
|
||||
cacheMaxAge := time.Hour * 24
|
||||
fileServer := NewFileServerWithCaching(http.FS(distFS), int(cacheMaxAge.Seconds()))
|
||||
|
||||
router.NoRoute(func(c *gin.Context) {
|
||||
handler := func(c *gin.Context) {
|
||||
path := strings.TrimPrefix(c.Request.URL.Path, "/")
|
||||
|
||||
if strings.HasSuffix(path, "/") {
|
||||
@@ -97,7 +97,9 @@ func RegisterFrontend(router *gin.Engine) error {
|
||||
// Serve other static assets with caching
|
||||
c.Request.URL.Path = "/" + path
|
||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||
})
|
||||
}
|
||||
|
||||
router.NoRoute(rateLimitMiddleware, handler)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
143
backend/go.mod
143
backend/go.mod
@@ -1,24 +1,25 @@
|
||||
module github.com/pocket-id/pocket-id/backend
|
||||
|
||||
go 1.25
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.6
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.6
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0
|
||||
github.com/aws/smithy-go v1.24.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.9
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.9
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0
|
||||
github.com/aws/smithy-go v1.24.1
|
||||
github.com/caarlos0/env/v11 v11.3.1
|
||||
github.com/cenkalti/backoff/v5 v5.0.3
|
||||
github.com/disintegration/imageorient v0.0.0-20180920195336-8147d86e83ec
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dunglas/go-urlpattern v0.0.0-20241020164140-716dfa1c80b1
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6
|
||||
github.com/emersion/go-smtp v0.24.0
|
||||
github.com/gin-contrib/slog v1.2.0
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/glebarez/go-sqlite v1.22.0
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/go-co-op/gocron/v2 v2.19.0
|
||||
github.com/go-co-op/gocron/v2 v2.19.1
|
||||
github.com/go-ldap/ldap/v3 v3.4.12
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-webauthn/webauthn v0.15.0
|
||||
@@ -27,30 +28,31 @@ require (
|
||||
github.com/hashicorp/go-uuid v1.0.3
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.3
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.12
|
||||
github.com/lmittmann/tint v1.1.2
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.4
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.13
|
||||
github.com/lmittmann/tint v1.1.3
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/mileusna/useragent v1.3.5
|
||||
github.com/orandin/slog-gorm v1.4.0
|
||||
github.com/oschwald/maxminddb-golang/v2 v2.1.1
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.11.1
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.64.0
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.64.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0
|
||||
go.opentelemetry.io/otel v1.39.0
|
||||
go.opentelemetry.io/otel/log v0.15.0
|
||||
go.opentelemetry.io/otel/metric v1.39.0
|
||||
go.opentelemetry.io/otel/sdk v1.39.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.15.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0
|
||||
go.opentelemetry.io/otel/trace v1.39.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/image v0.34.0
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.65.0
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0
|
||||
go.opentelemetry.io/otel v1.40.0
|
||||
go.opentelemetry.io/otel/log v0.16.0
|
||||
go.opentelemetry.io/otel/metric v1.40.0
|
||||
go.opentelemetry.io/otel/sdk v1.40.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.16.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0
|
||||
go.opentelemetry.io/otel/trace v1.40.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
golang.org/x/image v0.36.0
|
||||
golang.org/x/net v0.50.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/text v0.32.0
|
||||
golang.org/x/text v0.34.0
|
||||
golang.org/x/time v0.14.0
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
gorm.io/gorm v1.31.1
|
||||
@@ -59,23 +61,24 @@ require (
|
||||
require (
|
||||
github.com/Azure/go-ntlmssp v0.1.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.14.3 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.14.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.4.0 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
@@ -84,22 +87,22 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-webauthn/x v0.1.27 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/go-webauthn/x v0.2.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.19.1 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
|
||||
github.com/google/go-github/v39 v39.2.0 // indirect
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/google/go-tpm v0.9.8 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
@@ -116,56 +119,56 @@ require (
|
||||
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.33 // indirect
|
||||
github.com/lib/pq v1.11.2 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.34 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/nlnwa/whatwg-url v0.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.67.4 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/otlptranslator v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.58.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/segmentio/asm v1.2.1 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
github.com/valyala/fastjson v1.6.7 // indirect
|
||||
github.com/valyala/fastjson v1.6.10 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.64.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.65.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.62.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
golang.org/x/arch v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/oauth2 v0.34.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/grpc v1.78.0 // indirect
|
||||
golang.org/x/arch v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
|
||||
golang.org/x/oauth2 v0.35.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/grpc v1.79.1 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.67.4 // indirect
|
||||
modernc.org/libc v1.68.0 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.42.2 // indirect
|
||||
modernc.org/sqlite v1.46.1 // indirect
|
||||
)
|
||||
|
||||
342
backend/go.sum
342
backend/go.sum
@@ -6,52 +6,55 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=
|
||||
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.9 h1:ktda/mtAydeObvJXlHzyGpK1xcsLaP16zfUPDGoW90A=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.9/go.mod h1:U+fCQ+9QKsLW786BCfEjYRj34VVTbPdsLP3CHSYXMOI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.9 h1:sWvTKsyrMlJGEuj/WgrwilpoJ6Xa1+KhIpGdzw7mMU8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.9/go.mod h1:+J44MBhmfVY/lETFiKI+klz0Vym2aCmIjqgClMmW82w=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 h1:JqcdRG//czea7Ppjb+g/n4o8i/R50aTBHkA7vu0lK+k=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17/go.mod h1:CO+WeGmIdj/MlPel2KwID9Gt7CNq4M65HUfBW97liM0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 h1:MIWra+MSq53CFaXXAywB2qg9YvVZifkk6vEGl/1Qor0=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8/go.mod h1:FsTpJtvC4U1fyDXk7c71XoDv3HlRm8V3NiYLeYLh5YE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 h1:bGeHBsGZx0Dvu/eJC0Lh9adJa3M1xREcndxLNZlve2U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17/go.mod h1:dcW24lbU0CzHusTE8LLHhRLI42ejmINN8Lcr22bwh/g=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 h1:oeu8VPlOre74lBA/PMhxa5vewaMIMmILM+RraSyB8KA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.10 h1:+VTRawC4iVY58pS/lzpo0lnoa/SYNGF4/B/3/U5ro8Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.10/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 h1:0jbJeuEHlwKJ9PfXtpSFc4MF+WIWORdhN1n30ITZGFM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
|
||||
github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0=
|
||||
github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA=
|
||||
github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
|
||||
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
|
||||
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
|
||||
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
|
||||
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
@@ -88,6 +91,8 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dunglas/go-urlpattern v0.0.0-20241020164140-716dfa1c80b1 h1:RW22Y3QjGrb97NUA8yupdFcaqg//+hMI2fZrETBvQ4s=
|
||||
github.com/dunglas/go-urlpattern v0.0.0-20241020164140-716dfa1c80b1/go.mod h1:mnVcdqOeYg0HvT6veRo7wINa1mJ+lC/R4ig2lWcapSI=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 h1:oP4q0fw+fOSWn3DfFi4EXdT+B+gTtzx8GC9xsc26Znk=
|
||||
@@ -98,8 +103,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/slog v1.2.0 h1:vAxZfr7knD1ZYK5+pMJLP52sZXIkJXkcRPa/0dx9hSk=
|
||||
github.com/gin-contrib/slog v1.2.0/go.mod h1:vYK6YltmpsEFkO0zfRMLTKHrWS3DwUSn0TMpT+kMagI=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
@@ -112,8 +117,8 @@ github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GM
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-co-op/gocron/v2 v2.19.0 h1:OKf2y6LXPs/BgBI2fl8PxUpNAI1DA9Mg+hSeGOS38OU=
|
||||
github.com/go-co-op/gocron/v2 v2.19.0/go.mod h1:5lEiCKk1oVJV39Zg7/YG10OnaVrDAV5GGR6O0663k6U=
|
||||
github.com/go-co-op/gocron/v2 v2.19.1 h1:B4iLeA0NB/2iO3EKQ7NfKn5KsQgZfjb2fkvoZJU3yBI=
|
||||
github.com/go-co-op/gocron/v2 v2.19.1/go.mod h1:5lEiCKk1oVJV39Zg7/YG10OnaVrDAV5GGR6O0663k6U=
|
||||
github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=
|
||||
github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -129,20 +134,20 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-webauthn/webauthn v0.15.0 h1:LR1vPv62E0/6+sTenX35QrCmpMCzLeVAcnXeH4MrbJY=
|
||||
github.com/go-webauthn/webauthn v0.15.0/go.mod h1:hcAOhVChPRG7oqG7Xj6XKN1mb+8eXTGP/B7zBLzkX5A=
|
||||
github.com/go-webauthn/x v0.1.27 h1:CLyuB8JGn9xvw0etBl4fnclcbPTwhKpN4Xg32zaSYnI=
|
||||
github.com/go-webauthn/x v0.1.27/go.mod h1:KGYJQAPPgbpDKi4N7zKMGL+Iz6WgxKg3OlhVbPtuJXI=
|
||||
github.com/go-webauthn/x v0.2.1 h1:/oB8i0FhSANuoN+YJF5XHMtppa7zGEYaQrrf6ytotjc=
|
||||
github.com/go-webauthn/x v0.2.1/go.mod h1:Wm0X0zXkzznit4gHj4m82GiBZRMEm+TDUIoJWIQLsE4=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.1 h1:3rG3+v8pkhRqoQ/88NYNMHYVGYztCOCIZ7UQhu7H+NE=
|
||||
github.com/goccy/go-yaml v1.19.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -166,8 +171,8 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
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/grpc-ecosystem/grpc-gateway/v2 v2.27.4 h1:kEISI/Gx67NzH3nJxAmY/dGac80kKZgZt134u7Y/k1s=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4/go.mod h1:6Nz966r3vQYCqIzWsuEl9d7cf7mRhtDmm++sOxlnfxI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
@@ -226,20 +231,20 @@ github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7
|
||||
github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU=
|
||||
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
|
||||
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.3 h1:WjLHWkDkgWXeIUrKi/7lS/sGq2DjkSAwdTbH5RHXAKs=
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.3/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0=
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.12 h1:p25r68Y4KrbBdYjIsQweYxq794CtGCzcrc5dGzJIRjg=
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.12/go.mod h1:HiUSaNmMLXgZ08OmGBaPVvoZQgJVOQphSrGr5zMamS8=
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.4 h1:pXyH2ppK8GYYggygxJ3TvxpCZnbEUWc9qSwRTTApaLA=
|
||||
github.com/lestrrat-go/httprc/v3 v3.0.4/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0=
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk=
|
||||
github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU=
|
||||
github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss=
|
||||
github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=
|
||||
github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs=
|
||||
github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
||||
github.com/lmittmann/tint v1.1.3 h1:Hv4EaHWXQr+GTFnOU4VKf8UvAtZgn0VuKT+G0wFlO3I=
|
||||
github.com/lmittmann/tint v1.1.3/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0=
|
||||
github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=
|
||||
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mileusna/useragent v1.3.5 h1:SJM5NzBmh/hO+4LGeATKpaEX9+b4vcGg2qXGLiNGDws=
|
||||
github.com/mileusna/useragent v1.3.5/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
@@ -257,6 +262,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/nlnwa/whatwg-url v0.5.0 h1:l71cqfqG44+VCQZQX3wD4bwheFWicPxuwaCimLEfpDo=
|
||||
github.com/nlnwa/whatwg-url v0.5.0/go.mod h1:X/ejnFFVbaOWdSul+cnlsSHviCzGZJdvPkgc9zD8IY8=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
@@ -276,16 +283,16 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc=
|
||||
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
|
||||
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
|
||||
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
||||
github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos=
|
||||
github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||
github.com/quic-go/quic-go v0.58.0 h1:ggY2pvZaVdB9EyojxL1p+5mptkuHyX5MOSv4dgWF4Ug=
|
||||
github.com/quic-go/quic-go v0.58.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
@@ -316,62 +323,63 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM=
|
||||
github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||
github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4=
|
||||
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0 h1:eypSOd+0txRKCXPNyqLPsbSfA0jULgJcGmSAdFAnrCM=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0/go.mod h1:CRGvIBL/aAxpQU34ZxyQVFlovVcp67s4cAmQu8Jh9mc=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.64.0 h1:7TYhBCu6Xz6vDJGNtEslWZLuuX2IJ/aH50hBY4MVeUg=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.64.0/go.mod h1:tHQctZfAe7e4PBPGyt3kae6mQFXNpj+iiDJa3ithM50=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.64.0 h1:9pzPj3RFyKOxBAMkM2w84LpT+rdHam1XoFA+QhARiRw=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.64.0/go.mod h1:hlVZx1btWH0XTfXpuGX9dsquB50s+tc3fYFOO5elo2M=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.64.0 h1:7IKZbAYwlwLXAdu7SVPhzTjDjogWZxP4MIa7rovY+PU=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.64.0/go.mod h1:+TF5nf3NIv2X8PGxqfYOaRnAoMM43rUA2C3XsN2DoWA=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.39.0 h1:PI7pt9pkSnimWcp5sQhUA9OzLbc3Ba4sL+VEUTNsxrk=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.39.0/go.mod h1:5gV/EzPnfYIwjzj+6y8tbGW2PKWhcsz5e/7twptRVQY=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 h1:W+m0g+/6v3pa5PgVf2xoFMi5YtNR06WtS7ve5pcvLtM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0/go.mod h1:JM31r0GGZ/GU94mX8hN4D8v6e40aFlUECSQ48HaLgHM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 h1:EKpiGphOYq3CYnIe2eX9ftUkyU+Y8Dtte8OaWyHJ4+I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0/go.mod h1:nWFP7C+T8TygkTjJ7mAyEaFaE7wNfms3nV/vexZ6qt0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf8jF6WbuGQWUVcqgyWtTR0kOOAWY1DYZ+UhvdmQPw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.61.0 h1:cCyZS4dr67d30uDyh8etKM2QyDsQ4zC9ds3bdbrVoD0=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.61.0/go.mod h1:iivMuj3xpR2DkUrUya3TPS/Z9h3dz7h01GxU+fQBRNg=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 h1:0BSddrtQqLEylcErkeFrJBmwFzcqfQq9+/uxfTZq+HE=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0/go.mod h1:87sjYuAPzaRCtdd09GU5gM1U9wQLrrcYrm77mh5EBoc=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 h1:8UPA4IbVZxpsD76ihGOQiFml99GPAEZLohDXvqHdi6U=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0/go.mod h1:MZ1T/+51uIVKlRzGw1Fo46KEWThjlCBZKl2LzY5nv4g=
|
||||
go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY=
|
||||
go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0 h1:yOYhGNPZseueTTvWp5iBD3/CthrmvayUXYEX862dDi4=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0/go.mod h1:CvaNVqIfcybc+7xqZNubbE+26K6P7AKZF/l0lE2kdCk=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.65.0 h1:I/7S/yWobR3QHFLqHsJ8QOndoiFsj1VgHpQiq43KlUI=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.65.0/go.mod h1:jPF6gn3y1E+nozCAEQj3c6NZ8KY+tvAgSVfvoOJUFac=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 h1:2gApdml7SznX9szEKFjKjM4qGcGSvAybYLBY319XG3g=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.65.0/go.mod h1:0QqAGlbHXhmPYACG3n5hNzO5DnEqqtg4VcK5pr22RI0=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0 h1:LSJsvNqhj2sBNFb5NWHbyDK4QJ/skQ2ydjeOZ9OYNZ4=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0/go.mod h1:0Q5ocj6h/+C6KYq8cnl4tDFVd4I1HBdsJ440aeagHos=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.40.0 h1:xariChe8OOVF3rNlfzGFgQc61npQmXhzZj/i82mxMfg=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.40.0/go.mod h1:72WvbdxbOfXaELEQfonFfOL6osvcVjI7uJEE8C2nkrs=
|
||||
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0 h1:ZVg+kCXxd9LtAaQNKBxAvJ5NpMf7LpvEr4MIZqb0TMQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0/go.mod h1:hh0tMeZ75CCXrHd9OXRYxTlCAdxcXioWHFIpYw2rZu8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 h1:djrxvDxAe44mJUrKataUbOhCKhR3F8QCyWucO16hTQs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0/go.mod h1:dt3nxpQEiSoKvfTVxp3TUg5fHPLhKtbcnN3Z1I1ePD0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 h1:NOyNnS19BF2SUDApbOKbDtWZ0IK7b8FJ2uAGdIWOGb0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0/go.mod h1:VL6EgVikRLcJa9ftukrHu/ZkkhFBSo1lzvdBC9CF1ss=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0/go.mod h1:eQqT90eR3X5Dbs1g9YSM30RavwLF725Ris5/XSXWvqE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.62.0 h1:krvC4JMfIOVdEuNPTtQ0ZjCiXrybhv+uOHMfHRmnvVo=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.62.0/go.mod h1:fgOE6FM/swEnsVQCqCnbOfRV4tOnWPg7bVeo4izBuhQ=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 h1:ivlbaajBWJqhcCPniDqDJmRwj4lc6sRT+dCAVKNmxlQ=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0/go.mod h1:u/G56dEKDDwXNCVLsbSrllB2o8pbtFLUC4HpR66r2dc=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 h1:ZrPRak/kS4xI3AVXy8F7pipuDXmDsrO8Lg+yQjBLjw0=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0/go.mod h1:3y6kQCWztq6hyW8Z9YxQDDm0Je9AJoFar2G0yDcmhRk=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8=
|
||||
go.opentelemetry.io/otel/log v0.16.0 h1:DeuBPqCi6pQwtCK0pO4fvMB5eBq6sNxEnuTs88pjsN4=
|
||||
go.opentelemetry.io/otel/log v0.16.0/go.mod h1:rWsmqNVTLIA8UnwYVOItjyEZDbKIkMxdQunsIhpUMes=
|
||||
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.16.0 h1:e/b4bdlQwC5fnGtG3dlXUrNOnP7c8YLVSpSfEBIkTnI=
|
||||
go.opentelemetry.io/otel/sdk/log v0.16.0/go.mod h1:JKfP3T6ycy7QEuv3Hj8oKDy7KItrEkus8XJE6EoSzw4=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.16.0 h1:/XVkpZ41rVRTP4DfMgYv1nEtNmf65XPPyAdqV90TMy4=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.16.0/go.mod h1:iOOPgQr5MY9oac/F5W86mXdeyWZGleIx3uXO98X2R6Y=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=
|
||||
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -381,55 +389,89 @@ go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=
|
||||
golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
||||
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
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.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
|
||||
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
|
||||
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
||||
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
||||
golang.org/x/image v0.36.0 h1:Iknbfm1afbgtwPTmHnS2gTM/6PPZfH+z2EFuOkSbqwc=
|
||||
golang.org/x/image v0.36.0/go.mod h1:YsWD2TyyGKiIX1kZlu9QfKIsQ4nAAK9bdgdrIsE7xy4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
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=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
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.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.8.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.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
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=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
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.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
||||
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
|
||||
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -444,18 +486,18 @@ gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
|
||||
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
|
||||
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
|
||||
modernc.org/ccgo/v4 v4.30.2 h1:4yPaaq9dXYXZ2V8s1UgrC3KIj580l2N4ClrLwnbv2so=
|
||||
modernc.org/ccgo/v4 v4.30.2/go.mod h1:yZMnhWEdW0qw3EtCndG1+ldRrVGS+bIwyWmAWzS0XEw=
|
||||
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
|
||||
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
|
||||
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
|
||||
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/libc v1.67.4 h1:zZGmCMUVPORtKv95c2ReQN5VDjvkoRm9GWPTEPuvlWg=
|
||||
modernc.org/libc v1.67.4/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
|
||||
modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ=
|
||||
modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||
@@ -464,8 +506,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.42.2 h1:7hkZUNJvJFN2PgfUdjni9Kbvd4ef4mNLOu0B9FGxM74=
|
||||
modernc.org/sqlite v1.42.2/go.mod h1:+VkC6v3pLOAE0A0uVucQEcbVW0I5nHCeDaBf+DpsQT8=
|
||||
modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=
|
||||
modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
sloggin "github.com/gin-contrib/slog"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/h2c"
|
||||
"golang.org/x/time/rate"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -51,8 +53,6 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
r.Use(otelgin.Middleware(common.Name))
|
||||
}
|
||||
|
||||
rateLimitMiddleware := middleware.NewRateLimitMiddleware().Add(rate.Every(time.Second), 60)
|
||||
|
||||
// Setup global middleware
|
||||
r.Use(middleware.HeadMiddleware())
|
||||
r.Use(middleware.NewCacheControlMiddleware().Add())
|
||||
@@ -60,7 +60,8 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
r.Use(middleware.NewCspMiddleware().Add())
|
||||
r.Use(middleware.NewErrorHandlerMiddleware().Add())
|
||||
|
||||
err := frontend.RegisterFrontend(r)
|
||||
frontendRateLimitMiddleware := middleware.NewRateLimitMiddleware().Add(rate.Every(100*time.Millisecond), 300)
|
||||
err := frontend.RegisterFrontend(r, frontendRateLimitMiddleware)
|
||||
if errors.Is(err, frontend.ErrFrontendNotIncluded) {
|
||||
slog.Warn("Frontend is not included in the build. Skipping frontend registration.")
|
||||
} else if err != nil {
|
||||
@@ -71,8 +72,10 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
authMiddleware := middleware.NewAuthMiddleware(svc.apiKeyService, svc.userService, svc.jwtService)
|
||||
fileSizeLimitMiddleware := middleware.NewFileSizeLimitMiddleware()
|
||||
|
||||
apiRateLimitMiddleware := middleware.NewRateLimitMiddleware().Add(rate.Every(time.Second), 100)
|
||||
|
||||
// Set up API routes
|
||||
apiGroup := r.Group("/api", rateLimitMiddleware)
|
||||
apiGroup := r.Group("/api", apiRateLimitMiddleware)
|
||||
controller.NewApiKeyController(apiGroup, authMiddleware, svc.apiKeyService)
|
||||
controller.NewWebauthnController(apiGroup, authMiddleware, middleware.NewRateLimitMiddleware(), svc.webauthnService, svc.appConfigService)
|
||||
controller.NewOidcController(apiGroup, authMiddleware, fileSizeLimitMiddleware, svc.oidcService, svc.jwtService)
|
||||
@@ -94,18 +97,23 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
}
|
||||
|
||||
// Set up base routes
|
||||
baseGroup := r.Group("/", rateLimitMiddleware)
|
||||
baseGroup := r.Group("/", apiRateLimitMiddleware)
|
||||
controller.NewWellKnownController(baseGroup, svc.jwtService)
|
||||
|
||||
// Set up healthcheck routes
|
||||
// These are not rate-limited
|
||||
controller.NewHealthzController(r)
|
||||
|
||||
var protocols http.Protocols
|
||||
protocols.SetHTTP1(true)
|
||||
protocols.SetUnencryptedHTTP2(true)
|
||||
|
||||
// Set up the server
|
||||
srv := &http.Server{
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
Protocols: &protocols,
|
||||
Handler: h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// HEAD requests don't get matched by Gin routes, so we convert them to GET
|
||||
// middleware.HeadMiddleware will convert them back to HEAD later
|
||||
if req.Method == http.MethodHead {
|
||||
@@ -115,7 +123,7 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
}
|
||||
|
||||
r.ServeHTTP(w, req)
|
||||
}),
|
||||
}), &http2.Server{}),
|
||||
}
|
||||
|
||||
// Set up the listener
|
||||
|
||||
@@ -50,6 +50,7 @@ type EnvConfigSchema struct {
|
||||
InternalAppURL string `env:"INTERNAL_APP_URL"`
|
||||
UiConfigDisabled bool `env:"UI_CONFIG_DISABLED"`
|
||||
DisableRateLimiting bool `env:"DISABLE_RATE_LIMITING"`
|
||||
VersionCheckDisabled bool `env:"VERSION_CHECK_DISABLED"`
|
||||
StaticApiKey string `env:"STATIC_API_KEY" options:"file"`
|
||||
|
||||
FileBackend string `env:"FILE_BACKEND" options:"toLower"`
|
||||
@@ -128,6 +129,10 @@ func parseEnvConfig() error {
|
||||
|
||||
// ValidateEnvConfig checks the EnvConfig for required fields and valid values
|
||||
func ValidateEnvConfig(config *EnvConfigSchema) error {
|
||||
if shouldSkipEnvValidation(os.Args) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := sloggin.ParseLevel(config.LogLevel); err != nil {
|
||||
return errors.New("invalid LOG_LEVEL value. Must be 'debug', 'info', 'warn' or 'error'")
|
||||
}
|
||||
@@ -209,6 +214,17 @@ func ValidateEnvConfig(config *EnvConfigSchema) error {
|
||||
|
||||
}
|
||||
|
||||
func shouldSkipEnvValidation(args []string) bool {
|
||||
for _, arg := range args[1:] {
|
||||
switch arg {
|
||||
case "-h", "--help", "help", "version":
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// prepareEnvConfig processes special options for EnvConfig fields
|
||||
func prepareEnvConfig(config *EnvConfigSchema) error {
|
||||
val := reflect.ValueOf(config).Elem()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -24,7 +25,11 @@ import (
|
||||
// @Description Initializes all OIDC-related API endpoints for authentication and client management
|
||||
// @Tags OIDC
|
||||
func NewOidcController(group *gin.RouterGroup, authMiddleware *middleware.AuthMiddleware, fileSizeLimitMiddleware *middleware.FileSizeLimitMiddleware, oidcService *service.OidcService, jwtService *service.JwtService) {
|
||||
oc := &OidcController{oidcService: oidcService, jwtService: jwtService}
|
||||
oc := &OidcController{
|
||||
oidcService: oidcService,
|
||||
jwtService: jwtService,
|
||||
createTokens: oidcService.CreateTokens,
|
||||
}
|
||||
|
||||
group.POST("/oidc/authorize", authMiddleware.WithAdminNotRequired().Add(), oc.authorizeHandler)
|
||||
group.POST("/oidc/authorization-required", authMiddleware.WithAdminNotRequired().Add(), oc.authorizationConfirmationRequiredHandler)
|
||||
@@ -47,7 +52,7 @@ func NewOidcController(group *gin.RouterGroup, authMiddleware *middleware.AuthMi
|
||||
group.POST("/oidc/clients/:id/secret", authMiddleware.Add(), oc.createClientSecretHandler)
|
||||
|
||||
group.GET("/oidc/clients/:id/logo", oc.getClientLogoHandler)
|
||||
group.DELETE("/oidc/clients/:id/logo", oc.deleteClientLogoHandler)
|
||||
group.DELETE("/oidc/clients/:id/logo", authMiddleware.Add(), oc.deleteClientLogoHandler)
|
||||
group.POST("/oidc/clients/:id/logo", authMiddleware.Add(), fileSizeLimitMiddleware.Add(2<<20), oc.updateClientLogoHandler)
|
||||
|
||||
group.GET("/oidc/clients/:id/preview/:userId", authMiddleware.Add(), oc.getClientPreviewHandler)
|
||||
@@ -68,8 +73,9 @@ func NewOidcController(group *gin.RouterGroup, authMiddleware *middleware.AuthMi
|
||||
}
|
||||
|
||||
type OidcController struct {
|
||||
oidcService *service.OidcService
|
||||
jwtService *service.JwtService
|
||||
oidcService *service.OidcService
|
||||
jwtService *service.JwtService
|
||||
createTokens func(context.Context, dto.OidcCreateTokensDto) (service.CreatedTokens, error)
|
||||
}
|
||||
|
||||
// authorizeHandler godoc
|
||||
@@ -144,8 +150,13 @@ func (oc *OidcController) authorizationConfirmationRequiredHandler(c *gin.Contex
|
||||
// @Success 200 {object} dto.OidcTokenResponseDto "Token response with access_token and optional id_token and refresh_token"
|
||||
// @Router /api/oidc/token [post]
|
||||
func (oc *OidcController) createTokensHandler(c *gin.Context) {
|
||||
// Per RFC-6749, parameters passed to the /token endpoint MUST be passed in the body of the request
|
||||
// Gin's "ShouldBind" by default reads from the query string too, so we need to reset all query string args before invoking ShouldBind
|
||||
c.Request.URL.RawQuery = ""
|
||||
|
||||
var input dto.OidcCreateTokensDto
|
||||
if err := c.ShouldBind(&input); err != nil {
|
||||
err := c.ShouldBind(&input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
}
|
||||
@@ -164,10 +175,10 @@ func (oc *OidcController) createTokensHandler(c *gin.Context) {
|
||||
|
||||
// Client id and secret can also be passed over the Authorization header
|
||||
if input.ClientID == "" && input.ClientSecret == "" {
|
||||
input.ClientID, input.ClientSecret, _ = c.Request.BasicAuth()
|
||||
input.ClientID, input.ClientSecret, _ = utils.OAuthClientBasicAuth(c.Request)
|
||||
}
|
||||
|
||||
tokens, err := oc.oidcService.CreateTokens(c.Request.Context(), input)
|
||||
tokens, err := oc.createTokens(c.Request.Context(), input)
|
||||
|
||||
switch {
|
||||
case errors.Is(err, &common.OidcAuthorizationPendingError{}):
|
||||
@@ -322,7 +333,7 @@ func (oc *OidcController) introspectTokenHandler(c *gin.Context) {
|
||||
creds service.ClientAuthCredentials
|
||||
ok bool
|
||||
)
|
||||
creds.ClientID, creds.ClientSecret, ok = c.Request.BasicAuth()
|
||||
creds.ClientID, creds.ClientSecret, ok = utils.OAuthClientBasicAuth(c.Request)
|
||||
if !ok {
|
||||
// If there's no basic auth, check if we have a bearer token
|
||||
bearer, ok := utils.BearerAuth(c.Request)
|
||||
@@ -659,7 +670,7 @@ func (oc *OidcController) deviceAuthorizationHandler(c *gin.Context) {
|
||||
|
||||
// Client id and secret can also be passed over the Authorization header
|
||||
if input.ClientID == "" && input.ClientSecret == "" {
|
||||
input.ClientID, input.ClientSecret, _ = c.Request.BasicAuth()
|
||||
input.ClientID, input.ClientSecret, _ = utils.OAuthClientBasicAuth(c.Request)
|
||||
}
|
||||
|
||||
response, err := oc.oidcService.CreateDeviceAuthorization(c.Request.Context(), input)
|
||||
|
||||
227
backend/internal/controller/oidc_controller_test.go
Normal file
227
backend/internal/controller/oidc_controller_test.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
|
||||
func TestCreateTokensHandler(t *testing.T) {
|
||||
createTestContext := func(t *testing.T, rawURL string, form url.Values, authHeader string, noCT bool) (*gin.Context, *httptest.ResponseRecorder) {
|
||||
t.Helper()
|
||||
|
||||
mode := gin.Mode()
|
||||
gin.SetMode(gin.TestMode)
|
||||
t.Cleanup(func() { gin.SetMode(mode) })
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(recorder)
|
||||
|
||||
req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, rawURL, strings.NewReader(form.Encode()))
|
||||
require.NoError(t, err)
|
||||
|
||||
if !noCT {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
if authHeader != "" {
|
||||
req.Header.Set("Authorization", authHeader)
|
||||
}
|
||||
|
||||
c.Request = req
|
||||
return c, recorder
|
||||
}
|
||||
|
||||
t.Run("Ignores Query String Parameters For Binding", func(t *testing.T) {
|
||||
oc := &OidcController{}
|
||||
|
||||
c, _ := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token?grant_type=refresh_token&refresh_token=query-value",
|
||||
url.Values{},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Len(t, c.Errors, 1)
|
||||
assert.Contains(t, c.Errors[0].Err.Error(), "GrantType")
|
||||
})
|
||||
|
||||
t.Run("Missing Authorization Code", func(t *testing.T) {
|
||||
oc := &OidcController{}
|
||||
|
||||
c, _ := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeAuthorizationCode},
|
||||
},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Len(t, c.Errors, 1)
|
||||
var missingCodeErr *common.OidcMissingAuthorizationCodeError
|
||||
require.ErrorAs(t, c.Errors[0].Err, &missingCodeErr)
|
||||
})
|
||||
|
||||
t.Run("Missing Refresh Token", func(t *testing.T) {
|
||||
oc := &OidcController{}
|
||||
|
||||
c, _ := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeRefreshToken},
|
||||
},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Len(t, c.Errors, 1)
|
||||
var missingRefreshErr *common.OidcMissingRefreshTokenError
|
||||
require.ErrorAs(t, c.Errors[0].Err, &missingRefreshErr)
|
||||
})
|
||||
|
||||
t.Run("Uses Basic Auth Credentials When Body Credentials Missing", func(t *testing.T) {
|
||||
var capturedInput dto.OidcCreateTokensDto
|
||||
oc := &OidcController{
|
||||
createTokens: func(_ context.Context, input dto.OidcCreateTokensDto) (service.CreatedTokens, error) {
|
||||
capturedInput = input
|
||||
return service.CreatedTokens{
|
||||
AccessToken: "access-token",
|
||||
IdToken: "id-token",
|
||||
RefreshToken: "refresh-token",
|
||||
ExpiresIn: 2 * time.Minute,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
basicAuth := "Basic " + base64.StdEncoding.EncodeToString([]byte("client-id:client-secret"))
|
||||
c, recorder := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeRefreshToken},
|
||||
"refresh_token": {"input-refresh-token"},
|
||||
},
|
||||
basicAuth,
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Empty(t, c.Errors)
|
||||
assert.Equal(t, "client-id", capturedInput.ClientID)
|
||||
assert.Equal(t, "client-secret", capturedInput.ClientSecret)
|
||||
assert.Equal(t, "input-refresh-token", capturedInput.RefreshToken)
|
||||
|
||||
require.Equal(t, http.StatusOK, recorder.Code)
|
||||
var response dto.OidcTokenResponseDto
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &response))
|
||||
assert.Equal(t, "access-token", response.AccessToken)
|
||||
assert.Equal(t, "Bearer", response.TokenType)
|
||||
assert.Equal(t, "id-token", response.IdToken)
|
||||
assert.Equal(t, "refresh-token", response.RefreshToken)
|
||||
assert.Equal(t, 120, response.ExpiresIn)
|
||||
})
|
||||
|
||||
t.Run("Maps Authorization Pending Error", func(t *testing.T) {
|
||||
oc := &OidcController{
|
||||
createTokens: func(context.Context, dto.OidcCreateTokensDto) (service.CreatedTokens, error) {
|
||||
return service.CreatedTokens{}, &common.OidcAuthorizationPendingError{}
|
||||
},
|
||||
}
|
||||
|
||||
c, recorder := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeRefreshToken},
|
||||
"refresh_token": {"input-refresh-token"},
|
||||
},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Empty(t, c.Errors)
|
||||
require.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
var response map[string]string
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &response))
|
||||
assert.Equal(t, "authorization_pending", response["error"])
|
||||
})
|
||||
|
||||
t.Run("Maps Slow Down Error", func(t *testing.T) {
|
||||
oc := &OidcController{
|
||||
createTokens: func(context.Context, dto.OidcCreateTokensDto) (service.CreatedTokens, error) {
|
||||
return service.CreatedTokens{}, &common.OidcSlowDownError{}
|
||||
},
|
||||
}
|
||||
|
||||
c, recorder := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeRefreshToken},
|
||||
"refresh_token": {"input-refresh-token"},
|
||||
},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Empty(t, c.Errors)
|
||||
require.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
var response map[string]string
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &response))
|
||||
assert.Equal(t, "slow_down", response["error"])
|
||||
})
|
||||
|
||||
t.Run("Returns Generic Service Error In Context", func(t *testing.T) {
|
||||
expectedErr := errors.New("boom")
|
||||
oc := &OidcController{
|
||||
createTokens: func(context.Context, dto.OidcCreateTokensDto) (service.CreatedTokens, error) {
|
||||
return service.CreatedTokens{}, expectedErr
|
||||
},
|
||||
}
|
||||
|
||||
c, _ := createTestContext(
|
||||
t,
|
||||
"http://example.com/oidc/token",
|
||||
url.Values{
|
||||
"grant_type": {service.GrantTypeRefreshToken},
|
||||
"refresh_token": {"input-refresh-token"},
|
||||
},
|
||||
"",
|
||||
false,
|
||||
)
|
||||
|
||||
oc.createTokensHandler(c)
|
||||
|
||||
require.Len(t, c.Errors, 1)
|
||||
assert.ErrorIs(t, c.Errors[0].Err, expectedErr)
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
@@ -67,19 +65,6 @@ func ValidateClientID(clientID string) bool {
|
||||
|
||||
// ValidateCallbackURL validates callback URLs with support for wildcards
|
||||
func ValidateCallbackURL(raw string) bool {
|
||||
// Don't validate if it contains a wildcard
|
||||
if strings.Contains(raw, "*") {
|
||||
return true
|
||||
}
|
||||
|
||||
u, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !u.IsAbs() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
err := utils.ValidateCallbackURLPattern(raw)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"errors"
|
||||
@@ -22,6 +23,8 @@ import (
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
)
|
||||
|
||||
const maxTotalSize = 300 * 1024 * 1024 // 300 MB limit for total decompressed size
|
||||
|
||||
type GeoLiteService struct {
|
||||
httpClient *http.Client
|
||||
disableUpdater bool
|
||||
@@ -151,7 +154,24 @@ func (s *GeoLiteService) isDatabaseUpToDate() bool {
|
||||
|
||||
// extractDatabase extracts the database file from the tar.gz archive directly to the target location.
|
||||
func (s *GeoLiteService) extractDatabase(reader io.Reader) error {
|
||||
gzr, err := gzip.NewReader(reader)
|
||||
// Check for gzip magic number
|
||||
buf := make([]byte, 2)
|
||||
_, err := io.ReadFull(reader, buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read magic number: %w", err)
|
||||
}
|
||||
|
||||
// Check if the file starts with the gzip magic number
|
||||
// Gosec returns false positive for "G602: slice index out of range"
|
||||
//nolint:gosec
|
||||
isGzip := buf[0] == 0x1f && buf[1] == 0x8b
|
||||
|
||||
if !isGzip {
|
||||
// If not gzip, assume it's a regular database file
|
||||
return s.writeDatabaseFile(io.MultiReader(bytes.NewReader(buf), reader))
|
||||
}
|
||||
|
||||
gzr, err := gzip.NewReader(io.MultiReader(bytes.NewReader(buf), reader))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create gzip reader: %w", err)
|
||||
}
|
||||
@@ -160,7 +180,6 @@ func (s *GeoLiteService) extractDatabase(reader io.Reader) error {
|
||||
tarReader := tar.NewReader(gzr)
|
||||
|
||||
var totalSize int64
|
||||
const maxTotalSize = 300 * 1024 * 1024 // 300 MB limit for total decompressed size
|
||||
|
||||
// Iterate over the files in the tar archive
|
||||
for {
|
||||
@@ -222,3 +241,47 @@ func (s *GeoLiteService) extractDatabase(reader io.Reader) error {
|
||||
|
||||
return errors.New("GeoLite2-City.mmdb not found in archive")
|
||||
}
|
||||
|
||||
func (s *GeoLiteService) writeDatabaseFile(reader io.Reader) error {
|
||||
baseDir := filepath.Dir(common.EnvConfig.GeoLiteDBPath)
|
||||
tmpFile, err := os.CreateTemp(baseDir, "geolite.*.mmdb.tmp")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temporary database file: %w", err)
|
||||
}
|
||||
defer tmpFile.Close()
|
||||
|
||||
// Limit the amount we read to maxTotalSize.
|
||||
// We read one extra byte to detect if the source is larger than the limit.
|
||||
limitReader := io.LimitReader(reader, maxTotalSize+1)
|
||||
|
||||
// Write the file contents directly to the temporary file
|
||||
written, err := io.Copy(tmpFile, limitReader)
|
||||
if err != nil {
|
||||
os.Remove(tmpFile.Name())
|
||||
return fmt.Errorf("failed to write database file: %w", err)
|
||||
}
|
||||
|
||||
if written > maxTotalSize {
|
||||
os.Remove(tmpFile.Name())
|
||||
return errors.New("total database size exceeds maximum allowed limit")
|
||||
}
|
||||
|
||||
// Validate the downloaded database file
|
||||
if db, err := maxminddb.Open(tmpFile.Name()); err == nil {
|
||||
db.Close()
|
||||
} else {
|
||||
os.Remove(tmpFile.Name())
|
||||
return fmt.Errorf("failed to open downloaded database file: %w", err)
|
||||
}
|
||||
|
||||
// Ensure atomic replacement of the old database file
|
||||
s.mutex.Lock()
|
||||
err = os.Rename(tmpFile.Name(), common.EnvConfig.GeoLiteDBPath)
|
||||
s.mutex.Unlock()
|
||||
|
||||
if err != nil {
|
||||
os.Remove(tmpFile.Name())
|
||||
return fmt.Errorf("failed to replace database file: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
)
|
||||
|
||||
@@ -31,6 +32,10 @@ func NewVersionService(httpClient *http.Client) *VersionService {
|
||||
}
|
||||
|
||||
func (s *VersionService) GetLatestVersion(ctx context.Context) (string, error) {
|
||||
if common.EnvConfig.VersionCheckDisabled {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
version, err := s.cache.GetOrFetch(ctx, func(ctx context.Context) (string, error) {
|
||||
reqCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/url"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dunglas/go-urlpattern"
|
||||
)
|
||||
|
||||
// GetCallbackURLFromList returns the first callback URL that matches the input callback URL
|
||||
// ValidateCallbackURLPattern checks if the given callback URL pattern
|
||||
// is valid according to the rules defined in this package.
|
||||
func ValidateCallbackURLPattern(pattern string) error {
|
||||
if pattern == "*" {
|
||||
return nil
|
||||
}
|
||||
|
||||
pattern, _, _ = strings.Cut(pattern, "#")
|
||||
pattern = normalizeToURLPatternStandard(pattern)
|
||||
|
||||
_, err := urlpattern.New(pattern, "", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCallbackURLFromList returns the first callback URL that matches the input callback URL.
|
||||
func GetCallbackURLFromList(urls []string, inputCallbackURL string) (callbackURL string, err error) {
|
||||
// Special case for Loopback Interface Redirection. Quoting from RFC 8252 section 7.3:
|
||||
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
||||
@@ -24,7 +42,12 @@ func GetCallbackURLFromList(urls []string, inputCallbackURL string) (callbackURL
|
||||
host := u.Hostname()
|
||||
ip := net.ParseIP(host)
|
||||
if host == "localhost" || (ip != nil && ip.IsLoopback()) {
|
||||
u.Host = host
|
||||
// For IPv6 loopback hosts, brackets are required when serializing without a port.
|
||||
if strings.Contains(host, ":") {
|
||||
u.Host = "[" + host + "]"
|
||||
} else {
|
||||
u.Host = host
|
||||
}
|
||||
loopbackCallbackURLWithoutPort = u.String()
|
||||
}
|
||||
}
|
||||
@@ -64,143 +87,135 @@ func matchCallbackURL(pattern string, inputCallbackURL string) (matches bool, er
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Strip fragment part
|
||||
// Strip fragment part.
|
||||
// The endpoint URI MUST NOT include a fragment component.
|
||||
// https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2
|
||||
pattern, _, _ = strings.Cut(pattern, "#")
|
||||
inputCallbackURL, _, _ = strings.Cut(inputCallbackURL, "#")
|
||||
|
||||
// Store and strip query part
|
||||
var patternQuery url.Values
|
||||
if i := strings.Index(pattern, "?"); i >= 0 {
|
||||
patternQuery, err = url.ParseQuery(pattern[i+1:])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pattern = pattern[:i]
|
||||
}
|
||||
var inputQuery url.Values
|
||||
if i := strings.Index(inputCallbackURL, "?"); i >= 0 {
|
||||
inputQuery, err = url.ParseQuery(inputCallbackURL[i+1:])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
inputCallbackURL = inputCallbackURL[:i]
|
||||
}
|
||||
|
||||
// Split both pattern and input parts
|
||||
patternParts, patternPath := splitParts(pattern)
|
||||
inputParts, inputPath := splitParts(inputCallbackURL)
|
||||
|
||||
// Verify everything except the path and query parameters
|
||||
if len(patternParts) != len(inputParts) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for i, patternPart := range patternParts {
|
||||
matched, err := path.Match(patternPart, inputParts[i])
|
||||
if err != nil || !matched {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
// Verify path with wildcard support
|
||||
matched, err := matchPath(patternPath, inputPath)
|
||||
if err != nil || !matched {
|
||||
pattern, patternQuery, err := extractQueryParams(pattern)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Verify query parameters
|
||||
if len(patternQuery) != len(inputQuery) {
|
||||
inputCallbackURL, inputQuery, err := extractQueryParams(inputCallbackURL)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
pattern = normalizeToURLPatternStandard(pattern)
|
||||
|
||||
// Validate query params
|
||||
v := validateQueryParams(patternQuery, inputQuery)
|
||||
if !v {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for patternKey, patternValues := range patternQuery {
|
||||
inputValues, exists := inputQuery[patternKey]
|
||||
if !exists {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(patternValues) != len(inputValues) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for i := range patternValues {
|
||||
matched, err := path.Match(patternValues[i], inputValues[i])
|
||||
if err != nil || !matched {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
// Validate the rest of the URL using urlpattern
|
||||
p, err := urlpattern.New(pattern, "", nil)
|
||||
if err != nil {
|
||||
//nolint:nilerr
|
||||
slog.Warn("invalid callback URL pattern, skipping", "pattern", pattern, "error", err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return p.Test(inputCallbackURL, ""), nil
|
||||
}
|
||||
|
||||
// matchPath matches the input path against the pattern with wildcard support
|
||||
// Supported wildcards:
|
||||
//
|
||||
// '*' matches any sequence of characters except '/'
|
||||
// '**' matches any sequence of characters including '/'
|
||||
func matchPath(pattern string, input string) (matches bool, err error) {
|
||||
var regexPattern strings.Builder
|
||||
regexPattern.WriteString("^")
|
||||
// normalizeToURLPatternStandard converts patterns with single asterisk wildcards and globstar wildcards
|
||||
// into a format that can be parsed by the urlpattern package, which uses :param for single segment wildcards
|
||||
// and ** for multi-segment wildcards.
|
||||
func normalizeToURLPatternStandard(pattern string) string {
|
||||
patternBase, patternPath := extractPath(pattern)
|
||||
|
||||
runes := []rune(pattern)
|
||||
n := len(runes)
|
||||
|
||||
for i := 0; i < n; {
|
||||
switch runes[i] {
|
||||
case '*':
|
||||
// Check if it's a ** (globstar)
|
||||
if i+1 < n && runes[i+1] == '*' {
|
||||
// globstar = .* (match slashes too)
|
||||
regexPattern.WriteString(".*")
|
||||
i += 2
|
||||
// Replace single asterisk wildcards with :p{index} and keep globstar wildcards as **.
|
||||
var result strings.Builder
|
||||
for i := 0; i < len(patternPath); i++ {
|
||||
if patternPath[i] == '*' {
|
||||
// Check if it's a globstar (**)
|
||||
if i+1 < len(patternPath) && patternPath[i+1] == '*' {
|
||||
result.WriteString("**")
|
||||
i++ // skip next *
|
||||
} else {
|
||||
// single * = [^/]* (no slash)
|
||||
regexPattern.WriteString(`[^/]*`)
|
||||
i++
|
||||
result.WriteString(":p")
|
||||
result.WriteString(strconv.Itoa(i))
|
||||
}
|
||||
default:
|
||||
regexPattern.WriteString(regexp.QuoteMeta(string(runes[i])))
|
||||
i++
|
||||
} else {
|
||||
result.WriteByte(patternPath[i])
|
||||
}
|
||||
}
|
||||
patternPath = result.String()
|
||||
|
||||
regexPattern.WriteString("$")
|
||||
// Replace globstar wildcards (**) with a single *
|
||||
re := regexp.MustCompile(`\*{2}`)
|
||||
patternPath = re.ReplaceAllStringFunc(patternPath, func(_ string) string {
|
||||
return "*"
|
||||
})
|
||||
|
||||
matched, err := regexp.MatchString(regexPattern.String(), input)
|
||||
return matched, err
|
||||
return patternBase + patternPath
|
||||
}
|
||||
|
||||
// splitParts splits the URL into parts by special characters and returns the path separately
|
||||
func splitParts(s string) (parts []string, path string) {
|
||||
split := func(r rune) bool {
|
||||
return r == ':' || r == '/' || r == '[' || r == ']' || r == '@' || r == '.'
|
||||
}
|
||||
|
||||
func extractPath(url string) (base string, path string) {
|
||||
pathStart := -1
|
||||
|
||||
// Look for scheme:// first
|
||||
if i := strings.Index(s, "://"); i >= 0 {
|
||||
if i := strings.Index(url, "://"); i >= 0 {
|
||||
// Look for the next slash after scheme://
|
||||
rest := s[i+3:]
|
||||
rest := url[i+3:]
|
||||
if j := strings.IndexRune(rest, '/'); j >= 0 {
|
||||
pathStart = i + 3 + j
|
||||
}
|
||||
} else {
|
||||
// Otherwise, first slash is path start
|
||||
pathStart = strings.IndexRune(s, '/')
|
||||
pathStart = strings.IndexRune(url, '/')
|
||||
}
|
||||
|
||||
if pathStart >= 0 {
|
||||
path = s[pathStart:]
|
||||
base := s[:pathStart]
|
||||
parts = strings.FieldsFunc(base, split)
|
||||
path = url[pathStart:]
|
||||
base = url[:pathStart]
|
||||
} else {
|
||||
parts = strings.FieldsFunc(s, split)
|
||||
path = ""
|
||||
base = url
|
||||
}
|
||||
|
||||
return parts, path
|
||||
return base, path
|
||||
}
|
||||
|
||||
func extractQueryParams(rawUrl string) (base string, query url.Values, err error) {
|
||||
if i := strings.Index(rawUrl, "?"); i >= 0 {
|
||||
query, err = url.ParseQuery(rawUrl[i+1:])
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
rawUrl = rawUrl[:i]
|
||||
}
|
||||
|
||||
return rawUrl, query, nil
|
||||
}
|
||||
|
||||
func validateQueryParams(patternQuery, inputQuery url.Values) bool {
|
||||
if len(patternQuery) != len(inputQuery) {
|
||||
return false
|
||||
}
|
||||
|
||||
for patternKey, patternValues := range patternQuery {
|
||||
inputValues, exists := inputQuery[patternKey]
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(patternValues) != len(inputValues) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range patternValues {
|
||||
matched, err := path.Match(patternValues[i], inputValues[i])
|
||||
if err != nil || !matched {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -7,6 +7,77 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestValidateCallbackURLPattern(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pattern string
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
name: "exact URL",
|
||||
pattern: "https://example.com/callback",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "wildcard scheme",
|
||||
pattern: "*://example.com/callback",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "wildcard port",
|
||||
pattern: "https://example.com:*/callback",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "partial wildcard port",
|
||||
pattern: "https://example.com:80*/callback",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "wildcard userinfo",
|
||||
pattern: "https://user:*@example.com/callback",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "glob wildcard",
|
||||
pattern: "*",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "relative URL",
|
||||
pattern: "/callback",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
name: "missing scheme separator",
|
||||
pattern: "https//example.com/callback",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
name: "malformed wildcard host glob",
|
||||
pattern: "https://exa[mple.com/callback",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
name: "malformed authority",
|
||||
pattern: "https://[::1/callback",
|
||||
shouldError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateCallbackURLPattern(tt.pattern)
|
||||
if tt.shouldError {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchCallbackURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -187,12 +258,6 @@ func TestMatchCallbackURL(t *testing.T) {
|
||||
"https://example.com/callback",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unexpected credentials",
|
||||
"https://example.com/callback",
|
||||
"https://user:pass@example.com/callback",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"wildcard password",
|
||||
"https://user:*@example.com/callback",
|
||||
@@ -347,7 +412,7 @@ func TestMatchCallbackURL(t *testing.T) {
|
||||
"backslash instead of forward slash",
|
||||
"https://example.com/callback",
|
||||
"https://example.com\\callback",
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"double slash in hostname (protocol smuggling)",
|
||||
@@ -546,246 +611,3 @@ func TestGetCallbackURLFromList_MultiplePatterns(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pattern string
|
||||
input string
|
||||
shouldMatch bool
|
||||
}{
|
||||
// Exact matches
|
||||
{
|
||||
name: "exact match",
|
||||
pattern: "/callback",
|
||||
input: "/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "exact mismatch",
|
||||
pattern: "/callback",
|
||||
input: "/other",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
name: "empty paths",
|
||||
pattern: "",
|
||||
input: "",
|
||||
shouldMatch: true,
|
||||
},
|
||||
|
||||
// Single wildcard (*)
|
||||
{
|
||||
name: "single wildcard matches segment",
|
||||
pattern: "/api/*/callback",
|
||||
input: "/api/v1/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "single wildcard doesn't match multiple segments",
|
||||
pattern: "/api/*/callback",
|
||||
input: "/api/v1/v2/callback",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
name: "single wildcard at end",
|
||||
pattern: "/callback/*",
|
||||
input: "/callback/test",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "single wildcard at start",
|
||||
pattern: "/*/callback",
|
||||
input: "/api/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "multiple single wildcards",
|
||||
pattern: "/*/test/*",
|
||||
input: "/api/test/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "partial wildcard prefix",
|
||||
pattern: "/test*",
|
||||
input: "/testing",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "partial wildcard suffix",
|
||||
pattern: "/*-callback",
|
||||
input: "/oauth-callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "partial wildcard middle",
|
||||
pattern: "/api-*-v1",
|
||||
input: "/api-internal-v1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
|
||||
// Double wildcard (**)
|
||||
{
|
||||
name: "double wildcard matches multiple segments",
|
||||
pattern: "/api/**/callback",
|
||||
input: "/api/v1/v2/v3/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "double wildcard matches single segment",
|
||||
pattern: "/api/**/callback",
|
||||
input: "/api/v1/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "double wildcard doesn't match when pattern has extra slashes",
|
||||
pattern: "/api/**/callback",
|
||||
input: "/api/callback",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
name: "double wildcard at end",
|
||||
pattern: "/api/**",
|
||||
input: "/api/v1/v2/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "double wildcard in middle",
|
||||
pattern: "/api/**/v2/**/callback",
|
||||
input: "/api/v1/v2/v3/v4/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
|
||||
// Complex patterns
|
||||
{
|
||||
name: "mix of single and double wildcards",
|
||||
pattern: "/*/api/**/callback",
|
||||
input: "/app/api/v1/v2/callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "wildcard with special characters",
|
||||
pattern: "/callback-*",
|
||||
input: "/callback-123",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "path with query-like string (no special handling)",
|
||||
pattern: "/callback?code=*",
|
||||
input: "/callback?code=abc",
|
||||
shouldMatch: true,
|
||||
},
|
||||
|
||||
// Edge cases
|
||||
{
|
||||
name: "single wildcard matches empty segment",
|
||||
pattern: "/api/*/callback",
|
||||
input: "/api//callback",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
name: "pattern longer than input",
|
||||
pattern: "/api/v1/callback",
|
||||
input: "/api",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
name: "input longer than pattern",
|
||||
pattern: "/api",
|
||||
input: "/api/v1/callback",
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
matches, err := matchPath(tt.pattern, tt.input)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.shouldMatch, matches)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitParts(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expectedParts []string
|
||||
expectedPath string
|
||||
}{
|
||||
{
|
||||
name: "simple https URL",
|
||||
input: "https://example.com/callback",
|
||||
expectedParts: []string{"https", "example", "com"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "URL with port",
|
||||
input: "https://example.com:8080/callback",
|
||||
expectedParts: []string{"https", "example", "com", "8080"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "URL with subdomain",
|
||||
input: "https://api.example.com/callback",
|
||||
expectedParts: []string{"https", "api", "example", "com"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "URL with credentials",
|
||||
input: "https://user:pass@example.com/callback",
|
||||
expectedParts: []string{"https", "user", "pass", "example", "com"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "URL without path",
|
||||
input: "https://example.com",
|
||||
expectedParts: []string{"https", "example", "com"},
|
||||
expectedPath: "",
|
||||
},
|
||||
{
|
||||
name: "URL with deep path",
|
||||
input: "https://example.com/api/v1/callback",
|
||||
expectedParts: []string{"https", "example", "com"},
|
||||
expectedPath: "/api/v1/callback",
|
||||
},
|
||||
{
|
||||
name: "URL with path and query",
|
||||
input: "https://example.com/callback?code=123",
|
||||
expectedParts: []string{"https", "example", "com"},
|
||||
expectedPath: "/callback?code=123",
|
||||
},
|
||||
{
|
||||
name: "URL with trailing slash",
|
||||
input: "https://example.com/",
|
||||
expectedParts: []string{"https", "example", "com"},
|
||||
expectedPath: "/",
|
||||
},
|
||||
{
|
||||
name: "URL with multiple subdomains",
|
||||
input: "https://api.v1.staging.example.com/callback",
|
||||
expectedParts: []string{"https", "api", "v1", "staging", "example", "com"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "URL with port and credentials",
|
||||
input: "https://user:pass@example.com:8080/callback",
|
||||
expectedParts: []string{"https", "user", "pass", "example", "com", "8080"},
|
||||
expectedPath: "/callback",
|
||||
},
|
||||
{
|
||||
name: "scheme with authority separator but no slash",
|
||||
input: "http://example.com",
|
||||
expectedParts: []string{"http", "example", "com"},
|
||||
expectedPath: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parts, path := splitParts(tt.input)
|
||||
assert.Equal(t, tt.expectedParts, parts, "parts mismatch")
|
||||
assert.Equal(t, tt.expectedPath, path, "path mismatch")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -21,6 +22,27 @@ func BearerAuth(r *http.Request) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// OAuthClientBasicAuth returns the OAuth client ID and secret provided in the request's
|
||||
// Authorization header, if present. See RFC 6749, Section 2.3.
|
||||
func OAuthClientBasicAuth(r *http.Request) (clientID, clientSecret string, ok bool) {
|
||||
clientID, clientSecret, ok = r.BasicAuth()
|
||||
if !ok {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
clientID, err := url.QueryUnescape(clientID)
|
||||
if err != nil {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
clientSecret, err = url.QueryUnescape(clientSecret)
|
||||
if err != nil {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
return clientID, clientSecret, true
|
||||
}
|
||||
|
||||
// SetCacheControlHeader sets the Cache-Control header for the response.
|
||||
func SetCacheControlHeader(ctx *gin.Context, maxAge, staleWhileRevalidate time.Duration) {
|
||||
_, ok := ctx.GetQuery("skipCache")
|
||||
|
||||
@@ -63,3 +63,62 @@ func TestBearerAuth(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOAuthClientBasicAuth(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
authHeader string
|
||||
expectedClientID string
|
||||
expectedClientSecret string
|
||||
expectedOk bool
|
||||
}{
|
||||
{
|
||||
name: "Valid client ID and secret in header (example from RFC 6749)",
|
||||
authHeader: "Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3",
|
||||
expectedClientID: "s6BhdRkqt3",
|
||||
expectedClientSecret: "7Fjfp0ZBr1KtDRbnfVdmIw",
|
||||
expectedOk: true,
|
||||
},
|
||||
{
|
||||
name: "Valid client ID and secret in header (escaped values)",
|
||||
authHeader: "Basic ZTUwOTcyYmQtNmUzMi00OTU3LWJhZmMtMzU0MTU3ZjI1NDViOislMjUlMjYlMkIlQzIlQTMlRTIlODIlQUM=",
|
||||
expectedClientID: "e50972bd-6e32-4957-bafc-354157f2545b",
|
||||
// This is the example string from RFC 6749, Appendix B.
|
||||
expectedClientSecret: " %&+£€",
|
||||
expectedOk: true,
|
||||
},
|
||||
{
|
||||
name: "Empty auth header",
|
||||
authHeader: "",
|
||||
expectedClientID: "",
|
||||
expectedClientSecret: "",
|
||||
expectedOk: false,
|
||||
},
|
||||
{
|
||||
name: "Basic prefix only",
|
||||
authHeader: "Basic ",
|
||||
expectedClientID: "",
|
||||
expectedClientSecret: "",
|
||||
expectedOk: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://example.com", nil)
|
||||
require.NoError(t, err, "Failed to create request")
|
||||
|
||||
if tt.authHeader != "" {
|
||||
req.Header.Set("Authorization", tt.authHeader)
|
||||
}
|
||||
|
||||
clientId, clientSecret, ok := OAuthClientBasicAuth(req)
|
||||
|
||||
assert.Equal(t, tt.expectedOk, ok)
|
||||
|
||||
if tt.expectedOk {
|
||||
assert.Equal(t, tt.expectedClientID, clientId)
|
||||
assert.Equal(t, tt.expectedClientSecret, clientSecret)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -356,8 +356,8 @@
|
||||
"login_code_email_success": "Der Login-Code wurde an den Benutzer gesendet.",
|
||||
"send_email": "E-Mail senden",
|
||||
"show_code": "Code anzeigen",
|
||||
"callback_url_description": "Die URL(s) von deinem Kunden. Wenn du das Feld leer lässt, werden sie automatisch hinzugefügt. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Platzhalter</link> werden unterstützt.",
|
||||
"logout_callback_url_description": "Von deinem Kunden angegebene URL(s) zum Abmelden. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Platzhalter</link> werden unterstützt.",
|
||||
"callback_url_description": "Die URL(s) von deinem Client. Wenn du das Feld leer lässt, werden sie automatisch hinzugefügt. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Platzhalter</link> werden unterstützt.",
|
||||
"logout_callback_url_description": "Von deinem Client angegebene URL(s) zum Abmelden. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Platzhalter</link> werden unterstützt.",
|
||||
"api_key_expiration": "API-Schlüssel-Ablauf",
|
||||
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "Sende eine E-Mail an den Benutzer, wenn sein API-Schlüssel ablaufen wird.",
|
||||
"authorize_device": "Gerät autorisieren",
|
||||
@@ -397,21 +397,21 @@
|
||||
"color_value": "Farbwert",
|
||||
"apply": "Übernehmen",
|
||||
"signup_token": "Anmeldungstoken",
|
||||
"create_a_signup_token_to_allow_new_user_registration": "Erstell ein Anmeldetoken, damit sich neue Benutzer registrieren können.",
|
||||
"create_a_signup_token_to_allow_new_user_registration": "Erstell einen Registrierungstoken, damit sich neue Benutzer registrieren können.",
|
||||
"usage_limit": "Nutzungsbeschränkung",
|
||||
"number_of_times_token_can_be_used": "Wie oft der Anmeldetoken benutzt werden kann.",
|
||||
"number_of_times_token_can_be_used": "Wie oft der Registrierungstoken benutzt werden kann.",
|
||||
"expires": "Läuft ab",
|
||||
"signup": "Anmelden",
|
||||
"signup": "Registrieren",
|
||||
"user_creation": "Benutzererstellung",
|
||||
"configure_user_creation": "Verwalte die Einstellungen für die Benutzererstellung, einschließlich der Anmeldemethoden und Standardberechtigungen für neue Benutzer.",
|
||||
"user_creation_groups_description": "Weise diese Gruppen neuen Benutzern bei der Anmeldung automatisch zu.",
|
||||
"user_creation_claims_description": "Weise diese benutzerdefinierten Ansprüche neuen Benutzern bei der Anmeldung automatisch zu.",
|
||||
"configure_user_creation": "Verwalte die Einstellungen für die Benutzererstellung, einschließlich der Registrierungsmethoden und Standardberechtigungen für neue Benutzer.",
|
||||
"user_creation_groups_description": "Weise diese Gruppen neuen Benutzern bei der Registrierung automatisch zu.",
|
||||
"user_creation_claims_description": "Weise diese benutzerdefinierten Ansprüche neuen Benutzern bei der Registrierung automatisch zu.",
|
||||
"user_creation_updated_successfully": "Einstellungen für die Benutzererstellung erfolgreich aktualisiert.",
|
||||
"signup_disabled_description": "Benutzeranmeldungen sind komplett deaktiviert. Nur Admins können neue Benutzerkonten erstellen.",
|
||||
"signup_requires_valid_token": "Zum Erstellen eines Kontos brauchst du einen gültigen Anmeldetoken.",
|
||||
"signup_requires_valid_token": "Zum Erstellen eines Kontos brauchst du einen gültigen Registrierungstoken.",
|
||||
"validating_signup_token": "Anmeldungstoken bestätigen",
|
||||
"go_to_login": "Zum Login gehen",
|
||||
"signup_to_appname": "Melde dich bei „ {appName}“ an",
|
||||
"signup_to_appname": "Registriere dich bei „ {appName}“",
|
||||
"create_your_account_to_get_started": "Erstell dein Konto, um loszulegen.",
|
||||
"initial_account_creation_description": "Erstell dein Konto, um loszulegen. Du kannst später einen Passkey einrichten.",
|
||||
"setup_your_passkey": "Passkey einrichten",
|
||||
@@ -419,12 +419,12 @@
|
||||
"skip_for_now": "Jetzt überspringen",
|
||||
"account_created": "Konto erstellt",
|
||||
"enable_user_signups": "Benutzeranmeldungen aktivieren",
|
||||
"enable_user_signups_description": "Entscheide, wie sich Leute für neue Konten in Pocket ID anmelden können.",
|
||||
"enable_user_signups_description": "Entscheide, wie sich Leute für neue Konten in Pocket ID registrieren können.",
|
||||
"user_signups_are_disabled": "Benutzeranmeldungen sind im Moment deaktiviert.",
|
||||
"create_signup_token": "Anmeldungstoken erstellen",
|
||||
"view_active_signup_tokens": "Aktive Anmeldetoken anzeigen",
|
||||
"view_active_signup_tokens": "Aktive Registrierungstoken anzeigen",
|
||||
"manage_signup_tokens": "Anmeldungstoken verwalten",
|
||||
"view_and_manage_active_signup_tokens": "Aktive Anmeldetoken anzeigen und verwalten.",
|
||||
"view_and_manage_active_signup_tokens": "Aktive Registrierungstoken anzeigen und verwalten.",
|
||||
"signup_token_deleted_successfully": "Anmeldungstoken erfolgreich gelöscht.",
|
||||
"expired": "Abgelaufen",
|
||||
"used_up": "Aufgebraucht",
|
||||
@@ -434,9 +434,9 @@
|
||||
"token": "Token",
|
||||
"loading": "Laden",
|
||||
"delete_signup_token": "Anmeldungstoken löschen",
|
||||
"are_you_sure_you_want_to_delete_this_signup_token": "Willst du diesen Anmeldetoken wirklich löschen? Das kannst du nicht rückgängig machen.",
|
||||
"signup_with_token": "Mit Token anmelden",
|
||||
"signup_with_token_description": "Benutzer können sich nur mit einem gültigen Anmeldetoken anmelden, das von einem Administrator erstellt wurde.",
|
||||
"are_you_sure_you_want_to_delete_this_signup_token": "Willst du diesen Registrierungstoken wirklich löschen? Das kannst du nicht rückgängig machen.",
|
||||
"signup_with_token": "Mit Token registrieren",
|
||||
"signup_with_token_description": "Benutzer können sich nur mit einem gültigen Registrierungstoken anmelden, das von einem Administrator erstellt wurde.",
|
||||
"signup_open": "Anmeldung offen",
|
||||
"signup_open_description": "Jeder kann ohne Einschränkungen ein neues Konto erstellen.",
|
||||
"of": "von",
|
||||
@@ -477,7 +477,7 @@
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"system": "System",
|
||||
"signup_token_user_groups_description": "Weise diese Gruppen automatisch den Leuten zu, die sich mit diesem Token anmelden.",
|
||||
"signup_token_user_groups_description": "Weise diese Gruppen automatisch den Leuten zu, die sich mit diesem Token registrieren.",
|
||||
"allowed_oidc_clients": "Zugelassene OIDC-Clients",
|
||||
"allowed_oidc_clients_description": "Wähle die OIDC-Clients aus, bei denen sich Mitglieder dieser Benutzergruppe anmelden dürfen.",
|
||||
"unrestrict_oidc_client": "Uneingeschränkt {clientName}",
|
||||
@@ -513,7 +513,7 @@
|
||||
"email_verification_warning": "Bestätige deine E-Mail-Adresse",
|
||||
"email_verification_warning_description": "Deine E-Mail-Adresse ist noch nicht bestätigt. Bitte bestätige sie so schnell wie möglich.",
|
||||
"email_verification": "E-Mail-Bestätigung",
|
||||
"email_verification_description": "Schick den Nutzern eine Bestätigungs-E-Mail, wenn sie sich anmelden oder ihre E-Mail-Adresse ändern.",
|
||||
"email_verification_description": "Schick den Nutzern eine Bestätigungs-E-Mail, wenn sie sich registrieren oder ihre E-Mail-Adresse ändern.",
|
||||
"email_verification_success_title": "E-Mail erfolgreich bestätigt",
|
||||
"email_verification_success_description": "Deine E-Mail-Adresse wurde erfolgreich bestätigt.",
|
||||
"email_verification_error_title": "E-Mail-Verifizierung ist schiefgegangen",
|
||||
|
||||
525
frontend/messages/et.json
Normal file
525
frontend/messages/et.json
Normal file
@@ -0,0 +1,525 @@
|
||||
{
|
||||
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||
"my_account": "My Account",
|
||||
"logout": "Logout",
|
||||
"confirm": "Confirm",
|
||||
"docs": "Docs",
|
||||
"key": "Key",
|
||||
"value": "Value",
|
||||
"remove_custom_claim": "Remove custom claim",
|
||||
"add_custom_claim": "Add custom claim",
|
||||
"add_another": "Add another",
|
||||
"select_a_date": "Select a date",
|
||||
"select_file": "Select File",
|
||||
"profile_picture": "Profile Picture",
|
||||
"profile_picture_is_managed_by_ldap_server": "The profile picture is managed by the LDAP server and cannot be changed here.",
|
||||
"click_profile_picture_to_upload_custom": "Click on the profile picture to upload a custom one from your files.",
|
||||
"image_should_be_in_format": "The image should be in PNG, JPEG or WEBP format.",
|
||||
"items_per_page": "Items per page",
|
||||
"no_items_found": "No items found",
|
||||
"select_items": "Select items...",
|
||||
"search": "Search...",
|
||||
"expand_card": "Expand card",
|
||||
"copied": "Copied",
|
||||
"click_to_copy": "Click to copy",
|
||||
"something_went_wrong": "Something went wrong",
|
||||
"go_back_to_home": "Go back to home",
|
||||
"alternative_sign_in_methods": "Alternative Sign In Methods",
|
||||
"login_background": "Login background",
|
||||
"logo": "Logo",
|
||||
"login_code": "Login Code",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Create a login code that the user can use to sign in without a passkey once.",
|
||||
"one_hour": "1 hour",
|
||||
"twelve_hours": "12 hours",
|
||||
"one_day": "1 day",
|
||||
"one_week": "1 week",
|
||||
"one_month": "1 month",
|
||||
"expiration": "Expiration",
|
||||
"generate_code": "Generate Code",
|
||||
"name": "Name",
|
||||
"browser_unsupported": "Browser unsupported",
|
||||
"this_browser_does_not_support_passkeys": "This browser doesn't support passkeys. Please use an alternative sign in method.",
|
||||
"an_unknown_error_occurred": "An unknown error occurred",
|
||||
"authentication_process_was_aborted": "The authentication process was aborted",
|
||||
"error_occurred_with_authenticator": "An error occurred with the authenticator",
|
||||
"authenticator_does_not_support_discoverable_credentials": "The authenticator does not support discoverable credentials",
|
||||
"authenticator_does_not_support_resident_keys": "The authenticator does not support resident keys",
|
||||
"passkey_was_previously_registered": "This passkey was previously registered",
|
||||
"authenticator_does_not_support_any_of_the_requested_algorithms": "The authenticator does not support any of the requested algorithms",
|
||||
"webauthn_error_invalid_rp_id": "The configured relying party ID is invalid.",
|
||||
"webauthn_error_invalid_domain": "The configured domain is invalid.",
|
||||
"contact_administrator_to_fix": "Contact your administrator to fix this issue.",
|
||||
"webauthn_operation_not_allowed_or_timed_out": "The operation was not allowed or timed out",
|
||||
"webauthn_not_supported_by_browser": "Passkeys are not supported by this browser. Please use an alternative sign in method.",
|
||||
"critical_error_occurred_contact_administrator": "A critical error occurred. Please contact your administrator.",
|
||||
"sign_in_to": "Sign in to {name}",
|
||||
"client_not_found": "Client not found",
|
||||
"client_wants_to_access_the_following_information": "<b>{client}</b> wants to access the following information:",
|
||||
"do_you_want_to_sign_in_to_client_with_your_app_name_account": "Do you want to sign in to <b>{client}</b> with your {appName} account?",
|
||||
"email": "Email",
|
||||
"view_your_email_address": "View your email address",
|
||||
"profile": "Profile",
|
||||
"view_your_profile_information": "View your profile information",
|
||||
"groups": "Groups",
|
||||
"view_the_groups_you_are_a_member_of": "View the groups you are a member of",
|
||||
"cancel": "Cancel",
|
||||
"sign_in": "Sign in",
|
||||
"try_again": "Try again",
|
||||
"client_logo": "Client Logo",
|
||||
"sign_out": "Sign out",
|
||||
"do_you_want_to_sign_out_of_pocketid_with_the_account": "Do you want to sign out of {appName} with the account <b>{username}</b>?",
|
||||
"sign_in_to_appname": "Sign in to {appName}",
|
||||
"please_try_to_sign_in_again": "Please try to sign in again.",
|
||||
"authenticate_with_passkey_to_access_account": "Authenticate yourself with your passkey to access your account.",
|
||||
"authenticate": "Authenticate",
|
||||
"please_try_again": "Please try again.",
|
||||
"continue": "Continue",
|
||||
"alternative_sign_in": "Alternative Sign In",
|
||||
"if_you_do_not_have_access_to_your_passkey_you_can_sign_in_using_one_of_the_following_methods": "If you don't have access to your passkey, you can sign in using one of the following methods.",
|
||||
"use_your_passkey_instead": "Use your passkey instead?",
|
||||
"email_login": "Email Login",
|
||||
"enter_a_login_code_to_sign_in": "Enter a login code to sign in.",
|
||||
"sign_in_with_login_code": "Sign in with login code",
|
||||
"request_a_login_code_via_email": "Request a login code via email.",
|
||||
"go_back": "Go back",
|
||||
"an_email_has_been_sent_to_the_provided_email_if_it_exists_in_the_system": "An email has been sent to the provided email, if it exists in the system.",
|
||||
"enter_code": "Enter code",
|
||||
"enter_your_email_address_to_receive_an_email_with_a_login_code": "Enter your email address to receive an email with a login code.",
|
||||
"your_email": "Your email",
|
||||
"submit": "Submit",
|
||||
"enter_the_code_you_received_to_sign_in": "Enter the code you received to sign in.",
|
||||
"code": "Code",
|
||||
"invalid_redirect_url": "Invalid redirect URL",
|
||||
"audit_log": "Audit Log",
|
||||
"users": "Users",
|
||||
"user_groups": "User Groups",
|
||||
"oidc_clients": "OIDC Clients",
|
||||
"api_keys": "API Keys",
|
||||
"application_configuration": "Application Configuration",
|
||||
"settings": "Settings",
|
||||
"update_pocket_id": "Update Pocket ID",
|
||||
"powered_by": "Powered by",
|
||||
"see_your_recent_account_activities": "See your account activities within the configured retention period.",
|
||||
"time": "Time",
|
||||
"event": "Event",
|
||||
"approximate_location": "Approximate Location",
|
||||
"ip_address": "IP Address",
|
||||
"device": "Device",
|
||||
"client": "Client",
|
||||
"unknown": "Unknown",
|
||||
"account_details_updated_successfully": "Account details updated successfully",
|
||||
"profile_picture_updated_successfully": "Profile picture updated successfully. It may take a few minutes to update.",
|
||||
"account_settings": "Account Settings",
|
||||
"passkey_missing": "Passkey missing",
|
||||
"please_provide_a_passkey_to_prevent_losing_access_to_your_account": "Please add a passkey to prevent losing access to your account.",
|
||||
"single_passkey_configured": "Single Passkey Configured",
|
||||
"it_is_recommended_to_add_more_than_one_passkey": "It is recommended to add more than one passkey to avoid losing access to your account.",
|
||||
"account_details": "Account Details",
|
||||
"passkeys": "Passkeys",
|
||||
"manage_your_passkeys_that_you_can_use_to_authenticate_yourself": "Manage your passkeys that you can use to authenticate yourself.",
|
||||
"add_passkey": "Add Passkey",
|
||||
"create_a_one_time_login_code_to_sign_in_from_a_different_device_without_a_passkey": "Create a one-time login code to sign in from a different device without a passkey.",
|
||||
"create": "Create",
|
||||
"first_name": "First name",
|
||||
"last_name": "Last name",
|
||||
"username": "Username",
|
||||
"save": "Save",
|
||||
"username_can_only_contain": "Username can only contain lowercase letters, numbers, underscores, dots, hyphens, and '@' symbols",
|
||||
"username_must_start_with": "Username must start with an alphanumeric character",
|
||||
"username_must_end_with": "Username must end with an alphanumeric character",
|
||||
"sign_in_using_the_following_code_the_code_will_expire_in_minutes": "Sign in using the following code. The code will expire in 15 minutes.",
|
||||
"or_visit": "or visit",
|
||||
"added_on": "Added on",
|
||||
"rename": "Rename",
|
||||
"delete": "Delete",
|
||||
"are_you_sure_you_want_to_delete_this_passkey": "Are you sure you want to delete this passkey?",
|
||||
"passkey_deleted_successfully": "Passkey deleted successfully",
|
||||
"delete_passkey_name": "Delete {passkeyName}",
|
||||
"passkey_name_updated_successfully": "Passkey name updated successfully",
|
||||
"name_passkey": "Name Passkey",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Name your passkey to easily identify it later.",
|
||||
"create_api_key": "Create API Key",
|
||||
"add_a_new_api_key_for_programmatic_access": "Add a new API key for programmatic access to the <link href='https://pocket-id.org/docs/api'>Pocket ID API</link>.",
|
||||
"add_api_key": "Add API Key",
|
||||
"manage_api_keys": "Manage API Keys",
|
||||
"api_key_created": "API Key Created",
|
||||
"for_security_reasons_this_key_will_only_be_shown_once": "For security reasons, this key will only be shown once. Please store it securely.",
|
||||
"description": "Description",
|
||||
"api_key": "API Key",
|
||||
"close": "Close",
|
||||
"name_to_identify_this_api_key": "Name to identify this API key.",
|
||||
"expires_at": "Expires At",
|
||||
"when_this_api_key_will_expire": "When this API key will expire.",
|
||||
"optional_description_to_help_identify_this_keys_purpose": "Optional description to help identify this key's purpose.",
|
||||
"expiration_date_must_be_in_the_future": "Expiration date must be in the future",
|
||||
"revoke_api_key": "Revoke API Key",
|
||||
"never": "Never",
|
||||
"revoke": "Revoke",
|
||||
"api_key_revoked_successfully": "API key revoked successfully",
|
||||
"are_you_sure_you_want_to_revoke_the_api_key_apikeyname": "Are you sure you want to revoke the API key \"{apiKeyName}\"? This will break any integrations using this key.",
|
||||
"last_used": "Last Used",
|
||||
"actions": "Actions",
|
||||
"images_updated_successfully": "Images updated successfully. It may take a few minutes to update.",
|
||||
"general": "General",
|
||||
"configure_smtp_to_send_emails": "Enable email notifications to alert users when a login is detected from a new device or location.",
|
||||
"ldap": "LDAP",
|
||||
"configure_ldap_settings_to_sync_users_and_groups_from_an_ldap_server": "Configure LDAP settings to sync users and groups from an LDAP server.",
|
||||
"images": "Images",
|
||||
"update": "Update",
|
||||
"email_configuration_updated_successfully": "Email configuration updated successfully",
|
||||
"save_changes_question": "Save changes?",
|
||||
"you_have_to_save_the_changes_before_sending_a_test_email_do_you_want_to_save_now": "You have to save the changes before sending a test email. Do you want to save now?",
|
||||
"save_and_send": "Save and send",
|
||||
"test_email_sent_successfully": "Test email sent successfully to your email address.",
|
||||
"failed_to_send_test_email": "Failed to send test email. Check the server logs for more information.",
|
||||
"smtp_configuration": "SMTP Configuration",
|
||||
"smtp_host": "SMTP Host",
|
||||
"smtp_port": "SMTP Port",
|
||||
"smtp_user": "SMTP User",
|
||||
"smtp_password": "SMTP Password",
|
||||
"smtp_from": "SMTP From",
|
||||
"smtp_tls_option": "SMTP TLS Option",
|
||||
"email_tls_option": "Email TLS Option",
|
||||
"skip_certificate_verification": "Skip Certificate Verification",
|
||||
"this_can_be_useful_for_selfsigned_certificates": "This can be useful for self-signed certificates.",
|
||||
"enabled_emails": "Enabled Emails",
|
||||
"email_login_notification": "Email Login Notification",
|
||||
"send_an_email_to_the_user_when_they_log_in_from_a_new_device": "Send an email to the user when they log in from a new device.",
|
||||
"emai_login_code_requested_by_user": "Email Login Code Requested by User",
|
||||
"allow_users_to_sign_in_with_a_login_code_sent_to_their_email": "Allows users to bypass passkeys by requesting a login code sent to their email. This significantly reduces security as anyone with access to the user's email can gain entry.",
|
||||
"email_login_code_from_admin": "Email Login Code from Admin",
|
||||
"allows_an_admin_to_send_a_login_code_to_the_user": "Allows an admin to send a login code to the user via email.",
|
||||
"send_test_email": "Send test email",
|
||||
"application_configuration_updated_successfully": "Application configuration updated successfully",
|
||||
"application_name": "Application Name",
|
||||
"session_duration": "Session Duration",
|
||||
"the_duration_of_a_session_in_minutes_before_the_user_has_to_sign_in_again": "The duration of a session in minutes before the user has to sign in again.",
|
||||
"enable_self_account_editing": "Enable Self-Account Editing",
|
||||
"whether_the_users_should_be_able_to_edit_their_own_account_details": "Whether the users should be able to edit their own account details.",
|
||||
"ldap_configuration_updated_successfully": "LDAP configuration updated successfully",
|
||||
"ldap_disabled_successfully": "LDAP disabled successfully",
|
||||
"ldap_sync_finished": "LDAP sync finished",
|
||||
"client_configuration": "Client Configuration",
|
||||
"ldap_url": "LDAP URL",
|
||||
"ldap_bind_dn": "LDAP Bind DN",
|
||||
"ldap_bind_password": "LDAP Bind Password",
|
||||
"ldap_base_dn": "LDAP Base DN",
|
||||
"user_search_filter": "User Search Filter",
|
||||
"the_search_filter_to_use_to_search_or_sync_users": "The Search filter to use to search/sync users.",
|
||||
"groups_search_filter": "Groups Search Filter",
|
||||
"the_search_filter_to_use_to_search_or_sync_groups": "The Search filter to use to search/sync groups.",
|
||||
"attribute_mapping": "Attribute Mapping",
|
||||
"user_unique_identifier_attribute": "User Unique Identifier Attribute",
|
||||
"the_value_of_this_attribute_should_never_change": "The value of this attribute should never change.",
|
||||
"username_attribute": "Username Attribute",
|
||||
"user_mail_attribute": "User Mail Attribute",
|
||||
"user_first_name_attribute": "User First Name Attribute",
|
||||
"user_last_name_attribute": "User Last Name Attribute",
|
||||
"user_profile_picture_attribute": "User Profile Picture Attribute",
|
||||
"the_value_of_this_attribute_can_either_be_a_url_binary_or_base64_encoded_image": "The value of this attribute can either be a URL, a binary or a base64 encoded image.",
|
||||
"group_members_attribute": "Group Members Attribute",
|
||||
"the_attribute_to_use_for_querying_members_of_a_group": "The attribute to use for querying members of a group.",
|
||||
"group_unique_identifier_attribute": "Group Unique Identifier Attribute",
|
||||
"group_rdn_attribute": "Group RDN Attribute (in DN)",
|
||||
"admin_group_name": "Admin Group Name",
|
||||
"members_of_this_group_will_have_admin_privileges_in_pocketid": "Members of this group will have Admin Privileges in Pocket ID.",
|
||||
"disable": "Disable",
|
||||
"sync_now": "Sync now",
|
||||
"enable": "Enable",
|
||||
"user_created_successfully": "User created successfully",
|
||||
"create_user": "Create User",
|
||||
"add_a_new_user_to_appname": "Add a new user to {appName}",
|
||||
"add_user": "Add User",
|
||||
"manage_users": "Manage Users",
|
||||
"admin_privileges": "Admin Privileges",
|
||||
"admins_have_full_access_to_the_admin_panel": "Admins have full access to the admin panel.",
|
||||
"delete_firstname_lastname": "Delete {firstName} {lastName}",
|
||||
"are_you_sure_you_want_to_delete_this_user": "Are you sure you want to delete this user?",
|
||||
"user_deleted_successfully": "User deleted successfully",
|
||||
"role": "Role",
|
||||
"source": "Source",
|
||||
"admin": "Admin",
|
||||
"user": "User",
|
||||
"local": "Local",
|
||||
"toggle_menu": "Toggle menu",
|
||||
"edit": "Edit",
|
||||
"user_groups_updated_successfully": "User groups updated successfully",
|
||||
"user_updated_successfully": "User updated successfully",
|
||||
"custom_claims_updated_successfully": "Custom claims updated successfully",
|
||||
"back": "Back",
|
||||
"user_details_firstname_lastname": "User Details {firstName} {lastName}",
|
||||
"manage_which_groups_this_user_belongs_to": "Manage which groups this user belongs to.",
|
||||
"custom_claims": "Custom Claims",
|
||||
"custom_claims_are_key_value_pairs_that_can_be_used_to_store_additional_information_about_a_user": "Custom claims are key-value pairs that can be used to store additional information about a user. These claims will be included in the ID token if the scope 'profile' is requested.",
|
||||
"user_group_created_successfully": "User group created successfully",
|
||||
"create_user_group": "Create User Group",
|
||||
"create_a_new_group_that_can_be_assigned_to_users": "Create a new group that can be assigned to users.",
|
||||
"add_group": "Add Group",
|
||||
"manage_user_groups": "Manage User Groups",
|
||||
"friendly_name": "Friendly Name",
|
||||
"name_that_will_be_displayed_in_the_ui": "Name that will be displayed in the UI",
|
||||
"name_that_will_be_in_the_groups_claim": "Name that will be in the \"groups\" claim",
|
||||
"delete_name": "Delete {name}",
|
||||
"are_you_sure_you_want_to_delete_this_user_group": "Are you sure you want to delete this user group?",
|
||||
"user_group_deleted_successfully": "User group deleted successfully",
|
||||
"user_count": "User Count",
|
||||
"user_group_updated_successfully": "User group updated successfully",
|
||||
"users_updated_successfully": "Users updated successfully",
|
||||
"user_group_details_name": "User Group Details {name}",
|
||||
"assign_users_to_this_group": "Assign users to this group.",
|
||||
"custom_claims_are_key_value_pairs_that_can_be_used_to_store_additional_information_about_a_user_prioritized": "Custom claims are key-value pairs that can be used to store additional information about a user. These claims will be included in the ID token if the scope 'profile' is requested. Custom claims defined on the user will be prioritized if there are conflicts.",
|
||||
"oidc_client_created_successfully": "OIDC client created successfully",
|
||||
"create_oidc_client": "Create OIDC Client",
|
||||
"add_a_new_oidc_client_to_appname": "Add a new OIDC client to {appName}.",
|
||||
"add_oidc_client": "Add OIDC Client",
|
||||
"manage_oidc_clients": "Manage OIDC Clients",
|
||||
"one_time_link": "One Time Link",
|
||||
"use_this_link_to_sign_in_once": "Use this link to sign in once. This is needed for users who haven't added a passkey yet or have lost it.",
|
||||
"add": "Add",
|
||||
"callback_urls": "Callback URLs",
|
||||
"logout_callback_urls": "Logout Callback URLs",
|
||||
"public_client": "Public Client",
|
||||
"public_clients_description": "Public clients do not have a client secret. They are designed for mobile, web, and native applications where secrets cannot be securely stored.",
|
||||
"pkce": "PKCE",
|
||||
"public_key_code_exchange_is_a_security_feature_to_prevent_csrf_and_authorization_code_interception_attacks": "Public Key Code Exchange is a security feature to prevent CSRF and authorization code interception attacks.",
|
||||
"requires_reauthentication": "Requires Re-Authentication",
|
||||
"requires_users_to_authenticate_again_on_each_authorization": "Requires users to authenticate again on each authorization, even if already signed in",
|
||||
"name_logo": "{name} logo",
|
||||
"change_logo": "Change Logo",
|
||||
"upload_logo": "Upload Logo",
|
||||
"remove_logo": "Remove Logo",
|
||||
"are_you_sure_you_want_to_delete_this_oidc_client": "Are you sure you want to delete this OIDC client?",
|
||||
"oidc_client_deleted_successfully": "OIDC client deleted successfully",
|
||||
"authorization_url": "Authorization URL",
|
||||
"oidc_discovery_url": "OIDC Discovery URL",
|
||||
"token_url": "Token URL",
|
||||
"userinfo_url": "Userinfo URL",
|
||||
"logout_url": "Logout URL",
|
||||
"certificate_url": "Certificate URL",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"oidc_client_updated_successfully": "OIDC client updated successfully",
|
||||
"create_new_client_secret": "Create new client secret",
|
||||
"are_you_sure_you_want_to_create_a_new_client_secret": "Are you sure you want to create a new client secret? The old one will be invalidated.",
|
||||
"generate": "Generate",
|
||||
"new_client_secret_created_successfully": "New client secret created successfully",
|
||||
"oidc_client_name": "OIDC Client {name}",
|
||||
"client_id": "Client ID",
|
||||
"client_secret": "Client secret",
|
||||
"show_more_details": "Show more details",
|
||||
"allowed_user_groups": "Allowed User Groups",
|
||||
"allowed_user_groups_description": "Select the user groups whose members are allowed to sign in to this client.",
|
||||
"allowed_user_groups_status_unrestricted_description": "No user group restrictions are applied. Any user can sign in to this client.",
|
||||
"unrestrict": "Unrestrict",
|
||||
"restrict": "Restrict",
|
||||
"user_groups_restriction_updated_successfully": "User groups restriction updated successfully",
|
||||
"allowed_user_groups_updated_successfully": "Allowed user groups updated successfully",
|
||||
"favicon": "Favicon",
|
||||
"light_mode_logo": "Light Mode Logo",
|
||||
"dark_mode_logo": "Dark Mode Logo",
|
||||
"email_logo": "Email Logo",
|
||||
"background_image": "Background Image",
|
||||
"language": "Language",
|
||||
"reset_profile_picture_question": "Reset profile picture?",
|
||||
"this_will_remove_the_uploaded_image_and_reset_the_profile_picture_to_default": "This will remove the uploaded image and reset the profile picture to default. Do you want to continue?",
|
||||
"reset": "Reset",
|
||||
"reset_to_default": "Reset to default",
|
||||
"profile_picture_has_been_reset": "Profile picture has been reset. It may take a few minutes to update.",
|
||||
"select_the_language_you_want_to_use": "Select the language you want to use. Please note that some text may be automatically translated and could be inaccurate.",
|
||||
"contribute_to_translation": "If you find an issue you're welcome to contribute to the translation on <link href='https://crowdin.com/project/pocket-id'>Crowdin</link>.",
|
||||
"personal": "Personal",
|
||||
"global": "Global",
|
||||
"all_users": "All Users",
|
||||
"all_events": "All Events",
|
||||
"all_clients": "All Clients",
|
||||
"all_locations": "All Locations",
|
||||
"global_audit_log": "Global Audit Log",
|
||||
"see_all_recent_account_activities": "View the account activities of all users during the set retention period.",
|
||||
"token_sign_in": "Token Sign In",
|
||||
"client_authorization": "Client Authorization",
|
||||
"new_client_authorization": "New Client Authorization",
|
||||
"device_code_authorization": "Device Code Authorization",
|
||||
"new_device_code_authorization": "New Device Code Authorization",
|
||||
"passkey_added": "Passkey Added",
|
||||
"passkey_removed": "Passkey Removed",
|
||||
"disable_animations": "Disable Animations",
|
||||
"turn_off_ui_animations": "Turn off animations throughout the UI.",
|
||||
"user_disabled": "Account Disabled",
|
||||
"disabled_users_cannot_log_in_or_use_services": "Disabled users cannot log in or use services.",
|
||||
"user_disabled_successfully": "User has been disabled successfully.",
|
||||
"user_enabled_successfully": "User has been enabled successfully.",
|
||||
"status": "Status",
|
||||
"disable_firstname_lastname": "Disable {firstName} {lastName}",
|
||||
"are_you_sure_you_want_to_disable_this_user": "Are you sure you want to disable this user? They will not be able to log in or access any services.",
|
||||
"ldap_soft_delete_users": "Keep disabled users from LDAP.",
|
||||
"ldap_soft_delete_users_description": "When enabled, users removed from LDAP will be disabled rather than deleted from the system.",
|
||||
"login_code_email_success": "The login code has been sent to the user.",
|
||||
"send_email": "Send Email",
|
||||
"show_code": "Show Code",
|
||||
"callback_url_description": "URL(s) provided by your client. Will be automatically added if left blank. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Wildcards</link> are supported.",
|
||||
"logout_callback_url_description": "URL(s) provided by your client for logout. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Wildcards</link> are supported.",
|
||||
"api_key_expiration": "API Key Expiration",
|
||||
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "Send an email to the user when their API key is about to expire.",
|
||||
"authorize_device": "Authorize Device",
|
||||
"the_device_has_been_authorized": "The device has been authorized.",
|
||||
"enter_code_displayed_in_previous_step": "Enter the code that was displayed in the previous step.",
|
||||
"authorize": "Authorize",
|
||||
"federated_client_credentials": "Federated Client Credentials",
|
||||
"federated_client_credentials_description": "Using federated client credentials, you can authenticate OIDC clients using JWT tokens issued by third-party authorities.",
|
||||
"add_federated_client_credential": "Add Federated Client Credential",
|
||||
"add_another_federated_client_credential": "Add another federated client credential",
|
||||
"oidc_allowed_group_count": "Allowed Group Count",
|
||||
"unrestricted": "Unrestricted",
|
||||
"show_advanced_options": "Show Advanced Options",
|
||||
"hide_advanced_options": "Hide Advanced Options",
|
||||
"oidc_data_preview": "OIDC Data Preview",
|
||||
"preview_the_oidc_data_that_would_be_sent_for_different_users": "Preview the OIDC data that would be sent for different users",
|
||||
"id_token": "ID Token",
|
||||
"access_token": "Access Token",
|
||||
"userinfo": "Userinfo",
|
||||
"id_token_payload": "ID Token Payload",
|
||||
"access_token_payload": "Access Token Payload",
|
||||
"userinfo_endpoint_response": "Userinfo Endpoint Response",
|
||||
"copy": "Copy",
|
||||
"no_preview_data_available": "No preview data available",
|
||||
"copy_all": "Copy All",
|
||||
"preview": "Preview",
|
||||
"preview_for_user": "Preview for {name}",
|
||||
"preview_the_oidc_data_that_would_be_sent_for_this_user": "Preview the OIDC data that would be sent for this user",
|
||||
"show": "Show",
|
||||
"select_an_option": "Select an option",
|
||||
"select_user": "Select User",
|
||||
"error": "Error",
|
||||
"select_an_accent_color_to_customize_the_appearance_of_pocket_id": "Select an accent color to customize the appearance of Pocket ID.",
|
||||
"accent_color": "Accent Color",
|
||||
"custom_accent_color": "Custom Accent Color",
|
||||
"custom_accent_color_description": "Enter a custom color using valid CSS color formats (e.g., hex, rgb, hsl).",
|
||||
"color_value": "Color Value",
|
||||
"apply": "Apply",
|
||||
"signup_token": "Signup Token",
|
||||
"create_a_signup_token_to_allow_new_user_registration": "Create a signup token to allow new user registration.",
|
||||
"usage_limit": "Usage Limit",
|
||||
"number_of_times_token_can_be_used": "Number of times the signup token can be used.",
|
||||
"expires": "Expires",
|
||||
"signup": "Sign Up",
|
||||
"user_creation": "User Creation",
|
||||
"configure_user_creation": "Manage user creation settings, including signup methods and default permissions for new users.",
|
||||
"user_creation_groups_description": "Assign these groups automatically to new users upon signup.",
|
||||
"user_creation_claims_description": "Assign these custom claims automatically to new users upon signup.",
|
||||
"user_creation_updated_successfully": "User creation settings updated successfully.",
|
||||
"signup_disabled_description": "User signups are completely disabled. Only administrators can create new user accounts.",
|
||||
"signup_requires_valid_token": "A valid signup token is required to create an account",
|
||||
"validating_signup_token": "Validating signup token",
|
||||
"go_to_login": "Go to login",
|
||||
"signup_to_appname": "Sign Up to {appName}",
|
||||
"create_your_account_to_get_started": "Create your account to get started.",
|
||||
"initial_account_creation_description": "Please create your account to get started. You will be able to set up a passkey later.",
|
||||
"setup_your_passkey": "Set up your passkey",
|
||||
"create_a_passkey_to_securely_access_your_account": "Create a passkey to securely access your account. This will be your primary way to sign in.",
|
||||
"skip_for_now": "Skip for now",
|
||||
"account_created": "Account Created",
|
||||
"enable_user_signups": "Enable User Signups",
|
||||
"enable_user_signups_description": "Decide how users can sign up for new accounts in Pocket ID.",
|
||||
"user_signups_are_disabled": "User signups are currently disabled",
|
||||
"create_signup_token": "Create Signup Token",
|
||||
"view_active_signup_tokens": "View Active Signup Tokens",
|
||||
"manage_signup_tokens": "Manage Signup Tokens",
|
||||
"view_and_manage_active_signup_tokens": "View and manage active signup tokens.",
|
||||
"signup_token_deleted_successfully": "Signup token deleted successfully.",
|
||||
"expired": "Expired",
|
||||
"used_up": "Used Up",
|
||||
"active": "Active",
|
||||
"usage": "Usage",
|
||||
"created": "Created",
|
||||
"token": "Token",
|
||||
"loading": "Loading",
|
||||
"delete_signup_token": "Delete Signup Token",
|
||||
"are_you_sure_you_want_to_delete_this_signup_token": "Are you sure you want to delete this signup token? This action cannot be undone.",
|
||||
"signup_with_token": "Signup with token",
|
||||
"signup_with_token_description": "Users can only sign up using a valid signup token created by an administrator.",
|
||||
"signup_open": "Open Signup",
|
||||
"signup_open_description": "Anyone can create a new account without restrictions.",
|
||||
"of": "of",
|
||||
"skip_passkey_setup": "Skip Passkey Setup",
|
||||
"skip_passkey_setup_description": "It's highly recommended to set up a passkey because without one, you will be locked out of your account as soon as the session expires.",
|
||||
"my_apps": "My Apps",
|
||||
"no_apps_available": "No apps available",
|
||||
"contact_your_administrator_for_app_access": "Contact your administrator to get access to applications.",
|
||||
"launch": "Launch",
|
||||
"client_launch_url": "Client Launch URL",
|
||||
"client_launch_url_description": "The URL that will be opened when a user launches the app from the My Apps page.",
|
||||
"client_name_description": "The name of the client that shows in the Pocket ID UI.",
|
||||
"revoke_access": "Revoke Access",
|
||||
"revoke_access_description": "Revoke access to <b>{clientName}</b>. <b>{clientName}</b> will no longer be able to access your account information.",
|
||||
"revoke_access_successful": "The access to {clientName} has been successfully revoked.",
|
||||
"last_signed_in_ago": "Last signed in {time} ago",
|
||||
"invalid_client_id": "Client ID can only contain letters, numbers, underscores, and hyphens",
|
||||
"custom_client_id_description": "Set a custom client ID if this is required by your application. Otherwise, leave it blank to generate a random one.",
|
||||
"generated": "Generated",
|
||||
"administration": "Administration",
|
||||
"group_rdn_attribute_description": "The attribute used in the groups distinguished name (DN).",
|
||||
"display_name_attribute": "Display Name Attribute",
|
||||
"display_name": "Display Name",
|
||||
"configure_application_images": "Configure Application Images",
|
||||
"ui_config_disabled_info_title": "UI Configuration Disabled",
|
||||
"ui_config_disabled_info_description": "The UI configuration is disabled because the application configuration settings are managed through environment variables. Some settings may not be editable.",
|
||||
"logo_from_url_description": "Paste a direct image URL (svg, png, webp). Find icons at <link href=\"https://selfh.st/icons\">Selfh.st Icons</link> or <link href=\"https://dashboardicons.com\">Dashboard Icons</link>.",
|
||||
"invalid_url": "Invalid URL",
|
||||
"require_user_email": "Require Email Address",
|
||||
"require_user_email_description": "Requires users to have an email address. If disabled, the users without an email address won't be able to use features that require an email address.",
|
||||
"view": "View",
|
||||
"toggle_columns": "Toggle columns",
|
||||
"locale": "Locale",
|
||||
"ldap_id": "LDAP ID",
|
||||
"reauthentication": "Re-authentication",
|
||||
"clear_filters": "Clear Filters",
|
||||
"default_profile_picture": "Default Profile Picture",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System",
|
||||
"signup_token_user_groups_description": "Automatically assign these groups to users who sign up using this token.",
|
||||
"allowed_oidc_clients": "Allowed OIDC Clients",
|
||||
"allowed_oidc_clients_description": "Select the OIDC clients that members of this user group are allowed to sign in to.",
|
||||
"unrestrict_oidc_client": "Unrestrict {clientName}",
|
||||
"confirm_unrestrict_oidc_client_description": "Are you sure you want to unrestrict the OIDC client <b>{clientName}</b>? This will remove all group assignments for this client and any user will be able to sign in.",
|
||||
"allowed_oidc_clients_updated_successfully": "Allowed OIDC clients updated successfully",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"restricted": "Restricted",
|
||||
"scim_provisioning": "SCIM Provisioning",
|
||||
"scim_provisioning_description": "SCIM provisioning allows you to automatically provision and deprovision users and groups from your OIDC client. Learn more in the <link href='https://pocket-id.org/docs/configuration/scim'>docs</link>.",
|
||||
"scim_endpoint": "SCIM Endpoint",
|
||||
"scim_token": "SCIM Token",
|
||||
"last_successful_sync_at": "Last successful sync: {time}",
|
||||
"scim_configuration_updated_successfully": "SCIM configuration updated successfully.",
|
||||
"scim_enabled_successfully": "SCIM enabled successfully.",
|
||||
"scim_disabled_successfully": "SCIM disabled successfully.",
|
||||
"disable_scim_provisioning": "Disable SCIM Provisioning",
|
||||
"disable_scim_provisioning_confirm_description": "Are you sure you want to disable SCIM provisioning for <b>{clientName}</b>? This will stop all automatic user and group provisioning and deprovisioning.",
|
||||
"scim_sync_failed": "SCIM sync failed. Check the server logs for more information.",
|
||||
"scim_sync_successful": "The SCIM sync has been completed successfully.",
|
||||
"save_and_sync": "Save and Sync",
|
||||
"scim_save_changes_description": "You have to save the changes before starting a SCIM sync. Do you want to save now?",
|
||||
"scopes": "Scopes",
|
||||
"issuer_url": "Issuer URL",
|
||||
"smtp_field_required_when_other_provided": "Required when any SMTP setting is provided",
|
||||
"smtp_field_required_when_email_enabled": "Required when email notifications are enabled",
|
||||
"renew": "Renew",
|
||||
"renew_api_key": "Renew API Key",
|
||||
"renew_api_key_description": "Renewing the API key will generate a new key. Make sure to update any integrations using this key.",
|
||||
"api_key_renewed": "API key renewed",
|
||||
"app_config_home_page": "Home Page",
|
||||
"app_config_home_page_description": "The page users are redirected to after signing in.",
|
||||
"email_verification_warning": "Verify your email address",
|
||||
"email_verification_warning_description": "Your email address is not verified yet. Please verify it as soon as possible.",
|
||||
"email_verification": "Email Verification",
|
||||
"email_verification_description": "Send a verification email to users when they sign up or change their email address.",
|
||||
"email_verification_success_title": "Email Verified Successfully",
|
||||
"email_verification_success_description": "Your email address has been verified successfully.",
|
||||
"email_verification_error_title": "Email Verification Failed",
|
||||
"mark_as_unverified": "Mark as unverified",
|
||||
"mark_as_verified": "Mark as verified",
|
||||
"email_verification_sent": "Verification email sent successfully.",
|
||||
"emails_verified_by_default": "Emails verified by default",
|
||||
"emails_verified_by_default_description": "When enabled, users' email addresses will be marked as verified by default upon signup or when their email address is changed."
|
||||
}
|
||||
@@ -311,7 +311,7 @@
|
||||
"allowed_user_groups_description": "이 클라이언트에 로그인할 수 있는 사용자 그룹을 선택하십시오.",
|
||||
"allowed_user_groups_status_unrestricted_description": "사용자 그룹 제한이 적용되지 않습니다. 모든 사용자가 이 클라이언트에 로그인할 수 있습니다.",
|
||||
"unrestrict": "제한 해제",
|
||||
"restrict": "제한하다",
|
||||
"restrict": "제한",
|
||||
"user_groups_restriction_updated_successfully": "사용자 그룹 제한이 성공적으로 업데이트되었습니다.",
|
||||
"allowed_user_groups_updated_successfully": "허용된 사용자 그룹이 성공적으로 변경되었습니다",
|
||||
"favicon": "파비콘",
|
||||
@@ -356,8 +356,8 @@
|
||||
"login_code_email_success": "로그인 코드가 사용자에게 전송되었습니다.",
|
||||
"send_email": "이메일 전송",
|
||||
"show_code": "코드 표시",
|
||||
"callback_url_description": "고객이 제공한 URL. 비워두면 자동으로 추가됩니다. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>와일드카드가</link> 지원됩니다.",
|
||||
"logout_callback_url_description": "로그아웃을 위해 클라이언트가 제공하는 URL(들). <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>와일드카드가</link> 지원됩니다.",
|
||||
"callback_url_description": "클라이언트에서 제공된 URL입니다. 비워두면 자동으로 추가됩니다. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>와일드카드</link>가 지원됩니다.",
|
||||
"logout_callback_url_description": "클라이언트에서 제공된 로그아웃 URL입니다. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>와일드카드</link>가 지원됩니다.",
|
||||
"api_key_expiration": "API 키 만료",
|
||||
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "API 키가 만료되기 전에 사용자에게 이메일을 전송합니다.",
|
||||
"authorize_device": "기기 승인",
|
||||
@@ -480,11 +480,11 @@
|
||||
"signup_token_user_groups_description": "이 토큰을 사용하여 가입하는 사용자에게 자동으로 이 그룹들을 할당합니다.",
|
||||
"allowed_oidc_clients": "허용된 OIDC 클라이언트",
|
||||
"allowed_oidc_clients_description": "이 사용자 그룹의 구성원이 로그인할 수 있는 OIDC 클라이언트를 선택하십시오.",
|
||||
"unrestrict_oidc_client": "제한 해제 {clientName}",
|
||||
"unrestrict_oidc_client": "{clientName} 제한 해제",
|
||||
"confirm_unrestrict_oidc_client_description": "OIDC 클라이언트의 제한을 해제하시겠습니까? <b>{clientName}</b>? 이 작업은 해당 클라이언트의 모든 그룹 할당을 제거하며, 모든 사용자가 로그인할 수 있게 됩니다.",
|
||||
"allowed_oidc_clients_updated_successfully": "허용된 OIDC 클라이언트 업데이트 성공",
|
||||
"yes": "네",
|
||||
"no": "아니",
|
||||
"yes": "예",
|
||||
"no": "아니요",
|
||||
"restricted": "제한됨",
|
||||
"scim_provisioning": "SCIM 프로비저닝",
|
||||
"scim_provisioning_description": "SCIM 프로비저닝을 통해 OIDC 클라이언트에서 사용자 및 그룹을 자동으로 프로비저닝 및 디프로비저닝할 수 있습니다. 자세한 내용은 <link href='https://pocket-id.org/docs/configuration/scim'>문서를</link> 참조하세요.",
|
||||
@@ -504,7 +504,7 @@
|
||||
"issuer_url": "발행자 URL",
|
||||
"smtp_field_required_when_other_provided": "어떤 SMTP 설정이라도 제공될 때 필수",
|
||||
"smtp_field_required_when_email_enabled": "이메일 알림이 활성화된 경우 필수",
|
||||
"renew": "갱신하다",
|
||||
"renew": "갱신",
|
||||
"renew_api_key": "API 키 갱신",
|
||||
"renew_api_key_description": "API 키를 갱신하면 새 키가 생성됩니다. 이 키를 사용하는 모든 통합 기능을 반드시 업데이트하십시오.",
|
||||
"api_key_renewed": "API 키 갱신됨",
|
||||
|
||||
525
frontend/messages/no.json
Normal file
525
frontend/messages/no.json
Normal file
@@ -0,0 +1,525 @@
|
||||
{
|
||||
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||
"my_account": "My Account",
|
||||
"logout": "Logg ut",
|
||||
"confirm": "Confirm",
|
||||
"docs": "Docs",
|
||||
"key": "Nøkkel",
|
||||
"value": "Verdi",
|
||||
"remove_custom_claim": "Remove custom claim",
|
||||
"add_custom_claim": "Add custom claim",
|
||||
"add_another": "Add another",
|
||||
"select_a_date": "Velg dato",
|
||||
"select_file": "Velg fil",
|
||||
"profile_picture": "Profilbilde",
|
||||
"profile_picture_is_managed_by_ldap_server": "Profilbildet administreres av LDAP serveren og kan ikke endres her.",
|
||||
"click_profile_picture_to_upload_custom": "Klikk på profilbildet for å laste opp et bilde fra filene dine.",
|
||||
"image_should_be_in_format": "Bildet kan være i PNG, JPEG eller WEBP format.",
|
||||
"items_per_page": "Items per page",
|
||||
"no_items_found": "No items found",
|
||||
"select_items": "Select items...",
|
||||
"search": "Søk...",
|
||||
"expand_card": "Utvid kort",
|
||||
"copied": "Kopiert",
|
||||
"click_to_copy": "Klikk for å kopiere",
|
||||
"something_went_wrong": "Noe gikk galt",
|
||||
"go_back_to_home": "Go back to home",
|
||||
"alternative_sign_in_methods": "Alternative innloggingingsmetoder",
|
||||
"login_background": "Login background",
|
||||
"logo": "Logo",
|
||||
"login_code": "Innloggingskode",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Lag en innloggingskode som brukeren kan bruke for å logge inn uten en passnøkkel.",
|
||||
"one_hour": "1 time",
|
||||
"twelve_hours": "12 timer",
|
||||
"one_day": "1 dag",
|
||||
"one_week": "1 uke",
|
||||
"one_month": "1 måned",
|
||||
"expiration": "Expiration",
|
||||
"generate_code": "Generer kode",
|
||||
"name": "Navn",
|
||||
"browser_unsupported": "Nettleser ikke støttet",
|
||||
"this_browser_does_not_support_passkeys": "Denne nettleseren støtter ikke passnøkler. Vennligst bruk en annen metode for å logge inn.",
|
||||
"an_unknown_error_occurred": "En ukjent feil oppstod",
|
||||
"authentication_process_was_aborted": "Autentiseringsprosessen ble avbrutt",
|
||||
"error_occurred_with_authenticator": "An error occurred with the authenticator",
|
||||
"authenticator_does_not_support_discoverable_credentials": "The authenticator does not support discoverable credentials",
|
||||
"authenticator_does_not_support_resident_keys": "The authenticator does not support resident keys",
|
||||
"passkey_was_previously_registered": "Denne passnøkkelen er allerede registrert",
|
||||
"authenticator_does_not_support_any_of_the_requested_algorithms": "The authenticator does not support any of the requested algorithms",
|
||||
"webauthn_error_invalid_rp_id": "The configured relying party ID is invalid.",
|
||||
"webauthn_error_invalid_domain": "Det konfigurerte domenet er ugyldig.",
|
||||
"contact_administrator_to_fix": "Kontakt administratoren for å fikse feilen.",
|
||||
"webauthn_operation_not_allowed_or_timed_out": "The operation was not allowed or timed out",
|
||||
"webauthn_not_supported_by_browser": "Passkeys are not supported by this browser. Please use an alternative sign in method.",
|
||||
"critical_error_occurred_contact_administrator": "A critical error occurred. Please contact your administrator.",
|
||||
"sign_in_to": "Logg inn til {name}",
|
||||
"client_not_found": "Fant ikke klient",
|
||||
"client_wants_to_access_the_following_information": "<b>{client}</b> ønsker tilgang til følgende informasjon:",
|
||||
"do_you_want_to_sign_in_to_client_with_your_app_name_account": "Do you want to sign in to <b>{client}</b> with your {appName} account?",
|
||||
"email": "E-post",
|
||||
"view_your_email_address": "Vis E-post adressen din",
|
||||
"profile": "Profil",
|
||||
"view_your_profile_information": "Vis brukerinformasjonen din",
|
||||
"groups": "Grupper",
|
||||
"view_the_groups_you_are_a_member_of": "Vis grupper du er medlem i",
|
||||
"cancel": "Avbryt",
|
||||
"sign_in": "Logg inn",
|
||||
"try_again": "Prøv på nytt",
|
||||
"client_logo": "Klient logo",
|
||||
"sign_out": "Logg ut",
|
||||
"do_you_want_to_sign_out_of_pocketid_with_the_account": "Do you want to sign out of {appName} with the account <b>{username}</b>?",
|
||||
"sign_in_to_appname": "Sign in to {appName}",
|
||||
"please_try_to_sign_in_again": "Vennligst prøv å logge inn på nytt.",
|
||||
"authenticate_with_passkey_to_access_account": "Authenticate yourself with your passkey to access your account.",
|
||||
"authenticate": "Autentiser",
|
||||
"please_try_again": "Vennligst prøv på nytt.",
|
||||
"continue": "Fortsett",
|
||||
"alternative_sign_in": "Alternativ innloggingsmetode",
|
||||
"if_you_do_not_have_access_to_your_passkey_you_can_sign_in_using_one_of_the_following_methods": "Om du ikke har tilgang til passnøkkelen din, så kan du bruke en av følgende innloggingsmetoder.",
|
||||
"use_your_passkey_instead": "Bruk passnøkkelen din i stedet for?",
|
||||
"email_login": "E-post innlogging",
|
||||
"enter_a_login_code_to_sign_in": "Enter a login code to sign in.",
|
||||
"sign_in_with_login_code": "Sign in with login code",
|
||||
"request_a_login_code_via_email": "Request a login code via email.",
|
||||
"go_back": "Go back",
|
||||
"an_email_has_been_sent_to_the_provided_email_if_it_exists_in_the_system": "An email has been sent to the provided email, if it exists in the system.",
|
||||
"enter_code": "Enter code",
|
||||
"enter_your_email_address_to_receive_an_email_with_a_login_code": "Enter your email address to receive an email with a login code.",
|
||||
"your_email": "Your email",
|
||||
"submit": "Submit",
|
||||
"enter_the_code_you_received_to_sign_in": "Enter the code you received to sign in.",
|
||||
"code": "Code",
|
||||
"invalid_redirect_url": "Invalid redirect URL",
|
||||
"audit_log": "Audit Log",
|
||||
"users": "Users",
|
||||
"user_groups": "User Groups",
|
||||
"oidc_clients": "OIDC Clients",
|
||||
"api_keys": "API Keys",
|
||||
"application_configuration": "Application Configuration",
|
||||
"settings": "Settings",
|
||||
"update_pocket_id": "Update Pocket ID",
|
||||
"powered_by": "Powered by",
|
||||
"see_your_recent_account_activities": "See your account activities within the configured retention period.",
|
||||
"time": "Time",
|
||||
"event": "Event",
|
||||
"approximate_location": "Approximate Location",
|
||||
"ip_address": "IP adresse",
|
||||
"device": "Enhet",
|
||||
"client": "Klient",
|
||||
"unknown": "Ukjent",
|
||||
"account_details_updated_successfully": "Brukerdetaljer oppdatert",
|
||||
"profile_picture_updated_successfully": "Profilbildet er oppdatert. Det kan ta noen minutter før det vises overalt.",
|
||||
"account_settings": "Kontoinnstillinger",
|
||||
"passkey_missing": "Finner ingen passnøkkel",
|
||||
"please_provide_a_passkey_to_prevent_losing_access_to_your_account": "Please add a passkey to prevent losing access to your account.",
|
||||
"single_passkey_configured": "Revoker API nøkkel",
|
||||
"it_is_recommended_to_add_more_than_one_passkey": "Det er anbefalt å legge til mer enn én passnøkkel for å forhindre at du mister tilgang til kontoen din.",
|
||||
"account_details": "Kontodetaljer",
|
||||
"passkeys": "Passnøkler",
|
||||
"manage_your_passkeys_that_you_can_use_to_authenticate_yourself": "Manage your passkeys that you can use to authenticate yourself.",
|
||||
"add_passkey": "Legg til passnøkkel",
|
||||
"create_a_one_time_login_code_to_sign_in_from_a_different_device_without_a_passkey": "Create a one-time login code to sign in from a different device without a passkey.",
|
||||
"create": "Opprett",
|
||||
"first_name": "Fornavn",
|
||||
"last_name": "Etternavn",
|
||||
"username": "Brukernavn",
|
||||
"save": "Lagre",
|
||||
"username_can_only_contain": "Username can only contain lowercase letters, numbers, underscores, dots, hyphens, and '@' symbols",
|
||||
"username_must_start_with": "Username must start with an alphanumeric character",
|
||||
"username_must_end_with": "Username must end with an alphanumeric character",
|
||||
"sign_in_using_the_following_code_the_code_will_expire_in_minutes": "Sign in using the following code. The code will expire in 15 minutes.",
|
||||
"or_visit": "or visit",
|
||||
"added_on": "Lagt til på",
|
||||
"rename": "Endre navn",
|
||||
"delete": "Slett",
|
||||
"are_you_sure_you_want_to_delete_this_passkey": "Er du sikker på at du vil slette denne passnøkkelen?",
|
||||
"passkey_deleted_successfully": "Passnøkkelen er slettet",
|
||||
"delete_passkey_name": "Slett {passkeyName}",
|
||||
"passkey_name_updated_successfully": "Kallenavnet til passnøkkelen er oppdatert",
|
||||
"name_passkey": "Navngi passnøkkel",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Gi et navn til passnøkkelen så den blir lettere å identifisere senere.",
|
||||
"create_api_key": "Opprett en API nøkkel",
|
||||
"add_a_new_api_key_for_programmatic_access": "Add a new API key for programmatic access to the <link href='https://pocket-id.org/docs/api'>Pocket ID API</link>.",
|
||||
"add_api_key": "Legg til API nøkkel",
|
||||
"manage_api_keys": "Administrer API nøkler",
|
||||
"api_key_created": "API Key Created",
|
||||
"for_security_reasons_this_key_will_only_be_shown_once": "For security reasons, this key will only be shown once. Please store it securely.",
|
||||
"description": "Beskrivelse",
|
||||
"api_key": "API nøkkel",
|
||||
"close": "Lukk",
|
||||
"name_to_identify_this_api_key": "Name to identify this API key.",
|
||||
"expires_at": "Expires At",
|
||||
"when_this_api_key_will_expire": "When this API key will expire.",
|
||||
"optional_description_to_help_identify_this_keys_purpose": "Optional description to help identify this key's purpose.",
|
||||
"expiration_date_must_be_in_the_future": "Expiration date must be in the future",
|
||||
"revoke_api_key": "Revoker API nøkkel",
|
||||
"never": "Never",
|
||||
"revoke": "Revoke",
|
||||
"api_key_revoked_successfully": "API key revoked successfully",
|
||||
"are_you_sure_you_want_to_revoke_the_api_key_apikeyname": "Are you sure you want to revoke the API key \"{apiKeyName}\"? This will break any integrations using this key.",
|
||||
"last_used": "Last Used",
|
||||
"actions": "Actions",
|
||||
"images_updated_successfully": "Images updated successfully. It may take a few minutes to update.",
|
||||
"general": "General",
|
||||
"configure_smtp_to_send_emails": "Enable email notifications to alert users when a login is detected from a new device or location.",
|
||||
"ldap": "LDAP",
|
||||
"configure_ldap_settings_to_sync_users_and_groups_from_an_ldap_server": "Configure LDAP settings to sync users and groups from an LDAP server.",
|
||||
"images": "Images",
|
||||
"update": "Update",
|
||||
"email_configuration_updated_successfully": "Email configuration updated successfully",
|
||||
"save_changes_question": "Save changes?",
|
||||
"you_have_to_save_the_changes_before_sending_a_test_email_do_you_want_to_save_now": "You have to save the changes before sending a test email. Do you want to save now?",
|
||||
"save_and_send": "Save and send",
|
||||
"test_email_sent_successfully": "Test email sent successfully to your email address.",
|
||||
"failed_to_send_test_email": "Failed to send test email. Check the server logs for more information.",
|
||||
"smtp_configuration": "SMTP Configuration",
|
||||
"smtp_host": "SMTP Host",
|
||||
"smtp_port": "SMTP Port",
|
||||
"smtp_user": "SMTP User",
|
||||
"smtp_password": "SMTP Password",
|
||||
"smtp_from": "SMTP From",
|
||||
"smtp_tls_option": "SMTP TLS Option",
|
||||
"email_tls_option": "Email TLS Option",
|
||||
"skip_certificate_verification": "Skip Certificate Verification",
|
||||
"this_can_be_useful_for_selfsigned_certificates": "This can be useful for self-signed certificates.",
|
||||
"enabled_emails": "Enabled Emails",
|
||||
"email_login_notification": "Email Login Notification",
|
||||
"send_an_email_to_the_user_when_they_log_in_from_a_new_device": "Send an email to the user when they log in from a new device.",
|
||||
"emai_login_code_requested_by_user": "Email Login Code Requested by User",
|
||||
"allow_users_to_sign_in_with_a_login_code_sent_to_their_email": "Allows users to bypass passkeys by requesting a login code sent to their email. This significantly reduces security as anyone with access to the user's email can gain entry.",
|
||||
"email_login_code_from_admin": "Email Login Code from Admin",
|
||||
"allows_an_admin_to_send_a_login_code_to_the_user": "Allows an admin to send a login code to the user via email.",
|
||||
"send_test_email": "Send test E-post",
|
||||
"application_configuration_updated_successfully": "Application configuration updated successfully",
|
||||
"application_name": "Applikasjonsnavn",
|
||||
"session_duration": "Varighet på sesjon",
|
||||
"the_duration_of_a_session_in_minutes_before_the_user_has_to_sign_in_again": "Varighet på sesjon i minutter før brukeren må logge inn på nytt.",
|
||||
"enable_self_account_editing": "Enable Self-Account Editing",
|
||||
"whether_the_users_should_be_able_to_edit_their_own_account_details": "Whether the users should be able to edit their own account details.",
|
||||
"ldap_configuration_updated_successfully": "LDAP konfigurasjon oppdatert",
|
||||
"ldap_disabled_successfully": "LDAP er slått av",
|
||||
"ldap_sync_finished": "LDAP synkronisert",
|
||||
"client_configuration": "Klient konfigurasjon",
|
||||
"ldap_url": "LDAP URL",
|
||||
"ldap_bind_dn": "LDAP Bind DN",
|
||||
"ldap_bind_password": "LDAP Bind Password",
|
||||
"ldap_base_dn": "LDAP Base DN",
|
||||
"user_search_filter": "User Search Filter",
|
||||
"the_search_filter_to_use_to_search_or_sync_users": "The Search filter to use to search/sync users.",
|
||||
"groups_search_filter": "Groups Search Filter",
|
||||
"the_search_filter_to_use_to_search_or_sync_groups": "The Search filter to use to search/sync groups.",
|
||||
"attribute_mapping": "Attribute Mapping",
|
||||
"user_unique_identifier_attribute": "User Unique Identifier Attribute",
|
||||
"the_value_of_this_attribute_should_never_change": "The value of this attribute should never change.",
|
||||
"username_attribute": "Username Attribute",
|
||||
"user_mail_attribute": "User Mail Attribute",
|
||||
"user_first_name_attribute": "User First Name Attribute",
|
||||
"user_last_name_attribute": "User Last Name Attribute",
|
||||
"user_profile_picture_attribute": "User Profile Picture Attribute",
|
||||
"the_value_of_this_attribute_can_either_be_a_url_binary_or_base64_encoded_image": "The value of this attribute can either be a URL, a binary or a base64 encoded image.",
|
||||
"group_members_attribute": "Group Members Attribute",
|
||||
"the_attribute_to_use_for_querying_members_of_a_group": "The attribute to use for querying members of a group.",
|
||||
"group_unique_identifier_attribute": "Group Unique Identifier Attribute",
|
||||
"group_rdn_attribute": "Group RDN Attribute (in DN)",
|
||||
"admin_group_name": "Admin Group Name",
|
||||
"members_of_this_group_will_have_admin_privileges_in_pocketid": "Members of this group will have Admin Privileges in Pocket ID.",
|
||||
"disable": "Slå av",
|
||||
"sync_now": "Synkroniser nå",
|
||||
"enable": "Slå på",
|
||||
"user_created_successfully": "Bruker er opprettet",
|
||||
"create_user": "Opprett bruker",
|
||||
"add_a_new_user_to_appname": "Legg til bruker i {appName}",
|
||||
"add_user": "Legg til bruker",
|
||||
"manage_users": "Administrer brukere",
|
||||
"admin_privileges": "Admin Privileges",
|
||||
"admins_have_full_access_to_the_admin_panel": "Administratorene har full tilgang til administratorpanelet.",
|
||||
"delete_firstname_lastname": "Slett {firstName} {lastName}",
|
||||
"are_you_sure_you_want_to_delete_this_user": "Er du sikker på at du vil slette denne brukeren?",
|
||||
"user_deleted_successfully": "Bruker slettet",
|
||||
"role": "Rolle",
|
||||
"source": "Source",
|
||||
"admin": "Admin",
|
||||
"user": "User",
|
||||
"local": "Local",
|
||||
"toggle_menu": "Toggle menu",
|
||||
"edit": "Edit",
|
||||
"user_groups_updated_successfully": "User groups updated successfully",
|
||||
"user_updated_successfully": "User updated successfully",
|
||||
"custom_claims_updated_successfully": "Custom claims updated successfully",
|
||||
"back": "Back",
|
||||
"user_details_firstname_lastname": "User Details {firstName} {lastName}",
|
||||
"manage_which_groups_this_user_belongs_to": "Manage which groups this user belongs to.",
|
||||
"custom_claims": "Custom Claims",
|
||||
"custom_claims_are_key_value_pairs_that_can_be_used_to_store_additional_information_about_a_user": "Custom claims are key-value pairs that can be used to store additional information about a user. These claims will be included in the ID token if the scope 'profile' is requested.",
|
||||
"user_group_created_successfully": "User group created successfully",
|
||||
"create_user_group": "Create User Group",
|
||||
"create_a_new_group_that_can_be_assigned_to_users": "Create a new group that can be assigned to users.",
|
||||
"add_group": "Add Group",
|
||||
"manage_user_groups": "Manage User Groups",
|
||||
"friendly_name": "Friendly Name",
|
||||
"name_that_will_be_displayed_in_the_ui": "Name that will be displayed in the UI",
|
||||
"name_that_will_be_in_the_groups_claim": "Name that will be in the \"groups\" claim",
|
||||
"delete_name": "Slett {name}",
|
||||
"are_you_sure_you_want_to_delete_this_user_group": "Er du sikker på at du vil slette denne brukergruppen?",
|
||||
"user_group_deleted_successfully": "User group deleted successfully",
|
||||
"user_count": "Antall brukere",
|
||||
"user_group_updated_successfully": "User group updated successfully",
|
||||
"users_updated_successfully": "Brukere er oppdatert",
|
||||
"user_group_details_name": "User Group Details {name}",
|
||||
"assign_users_to_this_group": "Legg brukerne til i denne gruppen.",
|
||||
"custom_claims_are_key_value_pairs_that_can_be_used_to_store_additional_information_about_a_user_prioritized": "Custom claims are key-value pairs that can be used to store additional information about a user. These claims will be included in the ID token if the scope 'profile' is requested. Custom claims defined on the user will be prioritized if there are conflicts.",
|
||||
"oidc_client_created_successfully": "OIDC klient er opprettet",
|
||||
"create_oidc_client": "Opprett OIDC klient",
|
||||
"add_a_new_oidc_client_to_appname": "Add a new OIDC client to {appName}.",
|
||||
"add_oidc_client": "Add OIDC Client",
|
||||
"manage_oidc_clients": "Manage OIDC Clients",
|
||||
"one_time_link": "Engangslenke",
|
||||
"use_this_link_to_sign_in_once": "Use this link to sign in once. This is needed for users who haven't added a passkey yet or have lost it.",
|
||||
"add": "Legg til",
|
||||
"callback_urls": "Callback URLs",
|
||||
"logout_callback_urls": "Logout Callback URLs",
|
||||
"public_client": "Public Client",
|
||||
"public_clients_description": "Public clients do not have a client secret. They are designed for mobile, web, and native applications where secrets cannot be securely stored.",
|
||||
"pkce": "PKCE",
|
||||
"public_key_code_exchange_is_a_security_feature_to_prevent_csrf_and_authorization_code_interception_attacks": "Public Key Code Exchange is a security feature to prevent CSRF and authorization code interception attacks.",
|
||||
"requires_reauthentication": "Requires Re-Authentication",
|
||||
"requires_users_to_authenticate_again_on_each_authorization": "Requires users to authenticate again on each authorization, even if already signed in",
|
||||
"name_logo": "{name} logo",
|
||||
"change_logo": "Bytt logo",
|
||||
"upload_logo": "Last opp logo",
|
||||
"remove_logo": "Fjern logo",
|
||||
"are_you_sure_you_want_to_delete_this_oidc_client": "Are you sure you want to delete this OIDC client?",
|
||||
"oidc_client_deleted_successfully": "OIDC client deleted successfully",
|
||||
"authorization_url": "Authorization URL",
|
||||
"oidc_discovery_url": "OIDC Discovery URL",
|
||||
"token_url": "Token URL",
|
||||
"userinfo_url": "Userinfo URL",
|
||||
"logout_url": "Logout URL",
|
||||
"certificate_url": "Certificate URL",
|
||||
"enabled": "Aktivert",
|
||||
"disabled": "Deaktivert",
|
||||
"oidc_client_updated_successfully": "OIDC client updated successfully",
|
||||
"create_new_client_secret": "Create new client secret",
|
||||
"are_you_sure_you_want_to_create_a_new_client_secret": "Are you sure you want to create a new client secret? The old one will be invalidated.",
|
||||
"generate": "Generer",
|
||||
"new_client_secret_created_successfully": "New client secret created successfully",
|
||||
"oidc_client_name": "OIDC klient {name}",
|
||||
"client_id": "Client ID",
|
||||
"client_secret": "Client secret",
|
||||
"show_more_details": "Vis mer",
|
||||
"allowed_user_groups": "Tillatte brukergrupper",
|
||||
"allowed_user_groups_description": "Velg brukergruppene som skal kunne logge inn med denne klienten.",
|
||||
"allowed_user_groups_status_unrestricted_description": "No user group restrictions are applied. Any user can sign in to this client.",
|
||||
"unrestrict": "Unrestrict",
|
||||
"restrict": "Restrict",
|
||||
"user_groups_restriction_updated_successfully": "User groups restriction updated successfully",
|
||||
"allowed_user_groups_updated_successfully": "Allowed user groups updated successfully",
|
||||
"favicon": "Favicon",
|
||||
"light_mode_logo": "Light Mode Logo",
|
||||
"dark_mode_logo": "Dark Mode Logo",
|
||||
"email_logo": "Email Logo",
|
||||
"background_image": "Background Image",
|
||||
"language": "Language",
|
||||
"reset_profile_picture_question": "Reset profile picture?",
|
||||
"this_will_remove_the_uploaded_image_and_reset_the_profile_picture_to_default": "This will remove the uploaded image and reset the profile picture to default. Do you want to continue?",
|
||||
"reset": "Reset",
|
||||
"reset_to_default": "Reset to default",
|
||||
"profile_picture_has_been_reset": "Profile picture has been reset. It may take a few minutes to update.",
|
||||
"select_the_language_you_want_to_use": "Select the language you want to use. Please note that some text may be automatically translated and could be inaccurate.",
|
||||
"contribute_to_translation": "If you find an issue you're welcome to contribute to the translation on <link href='https://crowdin.com/project/pocket-id'>Crowdin</link>.",
|
||||
"personal": "Personal",
|
||||
"global": "Global",
|
||||
"all_users": "All Users",
|
||||
"all_events": "All Events",
|
||||
"all_clients": "All Clients",
|
||||
"all_locations": "All Locations",
|
||||
"global_audit_log": "Global Audit Log",
|
||||
"see_all_recent_account_activities": "View the account activities of all users during the set retention period.",
|
||||
"token_sign_in": "Token Sign In",
|
||||
"client_authorization": "Client Authorization",
|
||||
"new_client_authorization": "New Client Authorization",
|
||||
"device_code_authorization": "Device Code Authorization",
|
||||
"new_device_code_authorization": "New Device Code Authorization",
|
||||
"passkey_added": "Passnøkkel lagt til",
|
||||
"passkey_removed": "Passnøkkel fjernet",
|
||||
"disable_animations": "Deaktiver animasjoner",
|
||||
"turn_off_ui_animations": "Slå av animasjoner i brukergrensesnittet.",
|
||||
"user_disabled": "Konto deaktivert",
|
||||
"disabled_users_cannot_log_in_or_use_services": "Deaktiverte brukere kan ikke logge inn eller bruke tjenester.",
|
||||
"user_disabled_successfully": "Bruker har blitt deaktivert.",
|
||||
"user_enabled_successfully": "Bruker har blitt aktivert.",
|
||||
"status": "Status",
|
||||
"disable_firstname_lastname": "Deaktiver {firstName} {lastName}",
|
||||
"are_you_sure_you_want_to_disable_this_user": "Are you sure you want to disable this user? They will not be able to log in or access any services.",
|
||||
"ldap_soft_delete_users": "Keep disabled users from LDAP.",
|
||||
"ldap_soft_delete_users_description": "When enabled, users removed from LDAP will be disabled rather than deleted from the system.",
|
||||
"login_code_email_success": "The login code has been sent to the user.",
|
||||
"send_email": "Send E-post",
|
||||
"show_code": "Vis kode",
|
||||
"callback_url_description": "URL(s) provided by your client. Will be automatically added if left blank. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Wildcards</link> are supported.",
|
||||
"logout_callback_url_description": "URL(s) provided by your client for logout. <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>Wildcards</link> are supported.",
|
||||
"api_key_expiration": "API Key Expiration",
|
||||
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "Send an email to the user when their API key is about to expire.",
|
||||
"authorize_device": "Authorize Device",
|
||||
"the_device_has_been_authorized": "The device has been authorized.",
|
||||
"enter_code_displayed_in_previous_step": "Enter the code that was displayed in the previous step.",
|
||||
"authorize": "Authorize",
|
||||
"federated_client_credentials": "Federated Client Credentials",
|
||||
"federated_client_credentials_description": "Using federated client credentials, you can authenticate OIDC clients using JWT tokens issued by third-party authorities.",
|
||||
"add_federated_client_credential": "Add Federated Client Credential",
|
||||
"add_another_federated_client_credential": "Add another federated client credential",
|
||||
"oidc_allowed_group_count": "Allowed Group Count",
|
||||
"unrestricted": "Unrestricted",
|
||||
"show_advanced_options": "Show Advanced Options",
|
||||
"hide_advanced_options": "Hide Advanced Options",
|
||||
"oidc_data_preview": "OIDC Data Preview",
|
||||
"preview_the_oidc_data_that_would_be_sent_for_different_users": "Preview the OIDC data that would be sent for different users",
|
||||
"id_token": "ID Token",
|
||||
"access_token": "Access Token",
|
||||
"userinfo": "Brukerinformasjon",
|
||||
"id_token_payload": "ID Token Payload",
|
||||
"access_token_payload": "Access Token Payload",
|
||||
"userinfo_endpoint_response": "Userinfo Endpoint Response",
|
||||
"copy": "Copy",
|
||||
"no_preview_data_available": "No preview data available",
|
||||
"copy_all": "Copy All",
|
||||
"preview": "Preview",
|
||||
"preview_for_user": "Preview for {name}",
|
||||
"preview_the_oidc_data_that_would_be_sent_for_this_user": "Preview the OIDC data that would be sent for this user",
|
||||
"show": "Show",
|
||||
"select_an_option": "Select an option",
|
||||
"select_user": "Select User",
|
||||
"error": "Error",
|
||||
"select_an_accent_color_to_customize_the_appearance_of_pocket_id": "Select an accent color to customize the appearance of Pocket ID.",
|
||||
"accent_color": "Accent Color",
|
||||
"custom_accent_color": "Custom Accent Color",
|
||||
"custom_accent_color_description": "Enter a custom color using valid CSS color formats (e.g., hex, rgb, hsl).",
|
||||
"color_value": "Color Value",
|
||||
"apply": "Apply",
|
||||
"signup_token": "Signup Token",
|
||||
"create_a_signup_token_to_allow_new_user_registration": "Create a signup token to allow new user registration.",
|
||||
"usage_limit": "Bruksgrense",
|
||||
"number_of_times_token_can_be_used": "Number of times the signup token can be used.",
|
||||
"expires": "Expires",
|
||||
"signup": "Registrer",
|
||||
"user_creation": "User Creation",
|
||||
"configure_user_creation": "Manage user creation settings, including signup methods and default permissions for new users.",
|
||||
"user_creation_groups_description": "Assign these groups automatically to new users upon signup.",
|
||||
"user_creation_claims_description": "Assign these custom claims automatically to new users upon signup.",
|
||||
"user_creation_updated_successfully": "User creation settings updated successfully.",
|
||||
"signup_disabled_description": "User signups are completely disabled. Only administrators can create new user accounts.",
|
||||
"signup_requires_valid_token": "A valid signup token is required to create an account",
|
||||
"validating_signup_token": "Validating signup token",
|
||||
"go_to_login": "Gå til innlogging",
|
||||
"signup_to_appname": "Registrer for {appName}",
|
||||
"create_your_account_to_get_started": "Opprett kontoen din for å komme i gang.",
|
||||
"initial_account_creation_description": "Please create your account to get started. You will be able to set up a passkey later.",
|
||||
"setup_your_passkey": "Opprett din passnøkkel",
|
||||
"create_a_passkey_to_securely_access_your_account": "Create a passkey to securely access your account. This will be your primary way to sign in.",
|
||||
"skip_for_now": "Hopp over for denne gang",
|
||||
"account_created": "Konto opprettet",
|
||||
"enable_user_signups": "Enable User Signups",
|
||||
"enable_user_signups_description": "Decide how users can sign up for new accounts in Pocket ID.",
|
||||
"user_signups_are_disabled": "User signups are currently disabled",
|
||||
"create_signup_token": "Create Signup Token",
|
||||
"view_active_signup_tokens": "View Active Signup Tokens",
|
||||
"manage_signup_tokens": "Manage Signup Tokens",
|
||||
"view_and_manage_active_signup_tokens": "View and manage active signup tokens.",
|
||||
"signup_token_deleted_successfully": "Signup token deleted successfully.",
|
||||
"expired": "Expired",
|
||||
"used_up": "Used Up",
|
||||
"active": "Active",
|
||||
"usage": "Usage",
|
||||
"created": "Created",
|
||||
"token": "Token",
|
||||
"loading": "Loading",
|
||||
"delete_signup_token": "Delete Signup Token",
|
||||
"are_you_sure_you_want_to_delete_this_signup_token": "Are you sure you want to delete this signup token? This action cannot be undone.",
|
||||
"signup_with_token": "Signup with token",
|
||||
"signup_with_token_description": "Users can only sign up using a valid signup token created by an administrator.",
|
||||
"signup_open": "Open Signup",
|
||||
"signup_open_description": "Anyone can create a new account without restrictions.",
|
||||
"of": "of",
|
||||
"skip_passkey_setup": "Skip Passkey Setup",
|
||||
"skip_passkey_setup_description": "It's highly recommended to set up a passkey because without one, you will be locked out of your account as soon as the session expires.",
|
||||
"my_apps": "My Apps",
|
||||
"no_apps_available": "No apps available",
|
||||
"contact_your_administrator_for_app_access": "Contact your administrator to get access to applications.",
|
||||
"launch": "Launch",
|
||||
"client_launch_url": "Client Launch URL",
|
||||
"client_launch_url_description": "The URL that will be opened when a user launches the app from the My Apps page.",
|
||||
"client_name_description": "The name of the client that shows in the Pocket ID UI.",
|
||||
"revoke_access": "Revoke Access",
|
||||
"revoke_access_description": "Revoke access to <b>{clientName}</b>. <b>{clientName}</b> will no longer be able to access your account information.",
|
||||
"revoke_access_successful": "The access to {clientName} has been successfully revoked.",
|
||||
"last_signed_in_ago": "Last signed in {time} ago",
|
||||
"invalid_client_id": "Client ID can only contain letters, numbers, underscores, and hyphens",
|
||||
"custom_client_id_description": "Set a custom client ID if this is required by your application. Otherwise, leave it blank to generate a random one.",
|
||||
"generated": "Generated",
|
||||
"administration": "Administration",
|
||||
"group_rdn_attribute_description": "The attribute used in the groups distinguished name (DN).",
|
||||
"display_name_attribute": "Display Name Attribute",
|
||||
"display_name": "Display Name",
|
||||
"configure_application_images": "Configure Application Images",
|
||||
"ui_config_disabled_info_title": "UI Configuration Disabled",
|
||||
"ui_config_disabled_info_description": "The UI configuration is disabled because the application configuration settings are managed through environment variables. Some settings may not be editable.",
|
||||
"logo_from_url_description": "Paste a direct image URL (svg, png, webp). Find icons at <link href=\"https://selfh.st/icons\">Selfh.st Icons</link> or <link href=\"https://dashboardicons.com\">Dashboard Icons</link>.",
|
||||
"invalid_url": "Invalid URL",
|
||||
"require_user_email": "Require Email Address",
|
||||
"require_user_email_description": "Requires users to have an email address. If disabled, the users without an email address won't be able to use features that require an email address.",
|
||||
"view": "View",
|
||||
"toggle_columns": "Toggle columns",
|
||||
"locale": "Locale",
|
||||
"ldap_id": "LDAP ID",
|
||||
"reauthentication": "Re-authentication",
|
||||
"clear_filters": "Clear Filters",
|
||||
"default_profile_picture": "Default Profile Picture",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System",
|
||||
"signup_token_user_groups_description": "Automatically assign these groups to users who sign up using this token.",
|
||||
"allowed_oidc_clients": "Allowed OIDC Clients",
|
||||
"allowed_oidc_clients_description": "Select the OIDC clients that members of this user group are allowed to sign in to.",
|
||||
"unrestrict_oidc_client": "Unrestrict {clientName}",
|
||||
"confirm_unrestrict_oidc_client_description": "Are you sure you want to unrestrict the OIDC client <b>{clientName}</b>? This will remove all group assignments for this client and any user will be able to sign in.",
|
||||
"allowed_oidc_clients_updated_successfully": "Allowed OIDC clients updated successfully",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"restricted": "Restricted",
|
||||
"scim_provisioning": "SCIM Provisioning",
|
||||
"scim_provisioning_description": "SCIM provisioning allows you to automatically provision and deprovision users and groups from your OIDC client. Learn more in the <link href='https://pocket-id.org/docs/configuration/scim'>docs</link>.",
|
||||
"scim_endpoint": "SCIM Endpoint",
|
||||
"scim_token": "SCIM Token",
|
||||
"last_successful_sync_at": "Last successful sync: {time}",
|
||||
"scim_configuration_updated_successfully": "SCIM configuration updated successfully.",
|
||||
"scim_enabled_successfully": "SCIM enabled successfully.",
|
||||
"scim_disabled_successfully": "SCIM disabled successfully.",
|
||||
"disable_scim_provisioning": "Disable SCIM Provisioning",
|
||||
"disable_scim_provisioning_confirm_description": "Are you sure you want to disable SCIM provisioning for <b>{clientName}</b>? This will stop all automatic user and group provisioning and deprovisioning.",
|
||||
"scim_sync_failed": "SCIM sync failed. Check the server logs for more information.",
|
||||
"scim_sync_successful": "The SCIM sync has been completed successfully.",
|
||||
"save_and_sync": "Save and Sync",
|
||||
"scim_save_changes_description": "You have to save the changes before starting a SCIM sync. Do you want to save now?",
|
||||
"scopes": "Scopes",
|
||||
"issuer_url": "Issuer URL",
|
||||
"smtp_field_required_when_other_provided": "Required when any SMTP setting is provided",
|
||||
"smtp_field_required_when_email_enabled": "Required when email notifications are enabled",
|
||||
"renew": "Renew",
|
||||
"renew_api_key": "Renew API Key",
|
||||
"renew_api_key_description": "Renewing the API key will generate a new key. Make sure to update any integrations using this key.",
|
||||
"api_key_renewed": "API key renewed",
|
||||
"app_config_home_page": "Home Page",
|
||||
"app_config_home_page_description": "The page users are redirected to after signing in.",
|
||||
"email_verification_warning": "Verify your email address",
|
||||
"email_verification_warning_description": "Your email address is not verified yet. Please verify it as soon as possible.",
|
||||
"email_verification": "Email Verification",
|
||||
"email_verification_description": "Send a verification email to users when they sign up or change their email address.",
|
||||
"email_verification_success_title": "Email Verified Successfully",
|
||||
"email_verification_success_description": "Your email address has been verified successfully.",
|
||||
"email_verification_error_title": "Email Verification Failed",
|
||||
"mark_as_unverified": "Mark as unverified",
|
||||
"mark_as_verified": "Mark as verified",
|
||||
"email_verification_sent": "Verification email sent successfully.",
|
||||
"emails_verified_by_default": "Emails verified by default",
|
||||
"emails_verified_by_default_description": "When enabled, users' email addresses will be marked as verified by default upon signup or when their email address is changed."
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
"login_background": "Фон страницы входа",
|
||||
"logo": "Логотип",
|
||||
"login_code": "Код входа",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Создайте код входа, с которым пользователь сможет войти без пасскея один раз.",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Создайте код входа, с которым пользователь сможет войти без ключа доступа один раз.",
|
||||
"one_hour": "1 час",
|
||||
"twelve_hours": "12 часов",
|
||||
"one_day": "1 день",
|
||||
@@ -38,19 +38,19 @@
|
||||
"generate_code": "Сгенерировать код",
|
||||
"name": "Имя",
|
||||
"browser_unsupported": "Браузер не поддерживается",
|
||||
"this_browser_does_not_support_passkeys": "Этот браузер не поддерживает пасскеи. Пожалуйста, воспользуйтесь альтернативным способом входа.",
|
||||
"this_browser_does_not_support_passkeys": "Этот браузер не поддерживает ключи доступа. Пожалуйста, воспользуйтесь альтернативным способом входа.",
|
||||
"an_unknown_error_occurred": "Произошла неизвестная ошибка",
|
||||
"authentication_process_was_aborted": "Процесс аутентификации был прерван",
|
||||
"error_occurred_with_authenticator": "Произошла ошибка аутентификатора",
|
||||
"authenticator_does_not_support_discoverable_credentials": "Аутентификатор не поддерживает обнаруживаемые учетные данные",
|
||||
"authenticator_does_not_support_resident_keys": "Аутентификатор не поддерживает резидентные ключи",
|
||||
"passkey_was_previously_registered": "Этот пасскей был ранее зарегистрирован",
|
||||
"passkey_was_previously_registered": "Этот ключ доступа был ранее зарегистрирован",
|
||||
"authenticator_does_not_support_any_of_the_requested_algorithms": "Аутентификатор не поддерживает ни один из запрошенных алгоритмов",
|
||||
"webauthn_error_invalid_rp_id": "Идентификатор настроенной полагающейся стороны неверный.",
|
||||
"webauthn_error_invalid_domain": "Настроенный домен не работает.",
|
||||
"webauthn_error_invalid_rp_id": "Настроенный идентификатор доверяющей стороны является недопустимым.",
|
||||
"webauthn_error_invalid_domain": "Настроенный домен является недопустимым.",
|
||||
"contact_administrator_to_fix": "Обратись к своему администратору, чтобы решить эту проблему.",
|
||||
"webauthn_operation_not_allowed_or_timed_out": "Операция не разрешена или истекло время ожидания",
|
||||
"webauthn_not_supported_by_browser": "Этот браузер не поддерживает пароли. Попробуй войти другим способом.",
|
||||
"webauthn_not_supported_by_browser": "Этот браузер не поддерживает ключи доступа. Попробуйте войти другим способом.",
|
||||
"critical_error_occurred_contact_administrator": "Произошла критическая ошибка. Обратитесь к администратору.",
|
||||
"sign_in_to": "Войти в {name}",
|
||||
"client_not_found": "Клиент не найден",
|
||||
@@ -70,13 +70,13 @@
|
||||
"do_you_want_to_sign_out_of_pocketid_with_the_account": "Вы хотите выйти из {appName} с учетной записью <b>{username}</b>?",
|
||||
"sign_in_to_appname": "Войти в {appName}",
|
||||
"please_try_to_sign_in_again": "Пожалуйста, попробуйте войти снова.",
|
||||
"authenticate_with_passkey_to_access_account": "Авторизуйтесь с использованием пасскея для доступа к вашей учетной записи.",
|
||||
"authenticate_with_passkey_to_access_account": "Авторизуйтесь с помощью ключа доступа для входа в свою учетную запись.",
|
||||
"authenticate": "Авторизоваться",
|
||||
"please_try_again": "Пожалуйста, повторите попытку.",
|
||||
"continue": "Продолжить",
|
||||
"alternative_sign_in": "Альтернативный вход",
|
||||
"if_you_do_not_have_access_to_your_passkey_you_can_sign_in_using_one_of_the_following_methods": "Если у вас нет доступа к вашему пасскею, вы можете войти одним из следующих способов.",
|
||||
"use_your_passkey_instead": "Воспользоваться пасскеем вместо этого?",
|
||||
"if_you_do_not_have_access_to_your_passkey_you_can_sign_in_using_one_of_the_following_methods": "Если вы не можете использовать свой ключ доступа, вы можете войти одним из следующих способов.",
|
||||
"use_your_passkey_instead": "Использовать вместо этого ключ доступа?",
|
||||
"email_login": "Вход через электронную почту",
|
||||
"enter_a_login_code_to_sign_in": "Введите код входа, чтобы войти.",
|
||||
"sign_in_with_login_code": "Войти с помощью кода входа",
|
||||
@@ -99,7 +99,7 @@
|
||||
"settings": "Настройки",
|
||||
"update_pocket_id": "Обновите Pocket ID",
|
||||
"powered_by": "Работает на",
|
||||
"see_your_recent_account_activities": "Проверь, что происходит с твоей учетной записью в течение того времени, которое ты установил.",
|
||||
"see_your_recent_account_activities": "Смотрите действия вашей учетной записи в установленный период хранения.",
|
||||
"time": "Время",
|
||||
"event": "Событие",
|
||||
"approximate_location": "Примерное местоположение",
|
||||
@@ -110,15 +110,15 @@
|
||||
"account_details_updated_successfully": "Данные учетной записи успешно обновлены",
|
||||
"profile_picture_updated_successfully": "Изображение профиля успешно обновлено. Обновление может занять несколько минут.",
|
||||
"account_settings": "Настройки учетной записи",
|
||||
"passkey_missing": "Пасскей отсутствует",
|
||||
"please_provide_a_passkey_to_prevent_losing_access_to_your_account": "Пожалуйста, добавьте пасскей, чтобы избежать утери доступа к вашей учетной записи.",
|
||||
"single_passkey_configured": "Настроен один пасскей",
|
||||
"it_is_recommended_to_add_more_than_one_passkey": "Рекомендуется добавить более одного пасскея во избежание потери доступа к вашей учетной записи.",
|
||||
"passkey_missing": "Ключ доступа отсутствует",
|
||||
"please_provide_a_passkey_to_prevent_losing_access_to_your_account": "Пожалуйста, добавьте ключ доступа, чтобы не потерять доступ к своей учетной записи.",
|
||||
"single_passkey_configured": "Настроен только один ключ доступа",
|
||||
"it_is_recommended_to_add_more_than_one_passkey": "Рекомендуется добавить более одного ключа доступа, чтобы не потерять доступ к вашей учетной записи.",
|
||||
"account_details": "Детали учетной записи",
|
||||
"passkeys": "Пасскеи",
|
||||
"manage_your_passkeys_that_you_can_use_to_authenticate_yourself": "Управляйте пасскеями, которые вы можете использовать для аутентификации себя.",
|
||||
"add_passkey": "Добавить пасскей",
|
||||
"create_a_one_time_login_code_to_sign_in_from_a_different_device_without_a_passkey": "Создайте одноразовый код входа, чтобы войти с другого устройства без пасскея.",
|
||||
"passkeys": "Ключи доступа",
|
||||
"manage_your_passkeys_that_you_can_use_to_authenticate_yourself": "Управляйте своими ключами доступа, которые вы можете использовать для аутентификации.",
|
||||
"add_passkey": "Добавить ключ доступа",
|
||||
"create_a_one_time_login_code_to_sign_in_from_a_different_device_without_a_passkey": "Создайте одноразовый код входа, чтобы войти с другого устройства без ключа доступа.",
|
||||
"create": "Создать",
|
||||
"first_name": "Имя",
|
||||
"last_name": "Фамилия",
|
||||
@@ -132,12 +132,12 @@
|
||||
"added_on": "Добавлен",
|
||||
"rename": "Переименовать",
|
||||
"delete": "Удалить",
|
||||
"are_you_sure_you_want_to_delete_this_passkey": "Вы уверены, что хотите удалить этот пасскей?",
|
||||
"passkey_deleted_successfully": "Пасскей успешно удален",
|
||||
"are_you_sure_you_want_to_delete_this_passkey": "Вы уверены, что хотите удалить этот ключ доступа?",
|
||||
"passkey_deleted_successfully": "Ключ доступа успешно удален",
|
||||
"delete_passkey_name": "Удалить {passkeyName}",
|
||||
"passkey_name_updated_successfully": "Имя пасскея успешно обновлено",
|
||||
"name_passkey": "Имя пасскея",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Назовите ваш пасскей, чтобы легко идентифицировать его позже.",
|
||||
"passkey_name_updated_successfully": "Имя ключа доступа успешно обновлено",
|
||||
"name_passkey": "Имя ключа доступа",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Назовите ваш ключ доступа, чтобы легко идентифицировать его позже.",
|
||||
"create_api_key": "Создать ключ API",
|
||||
"add_a_new_api_key_for_programmatic_access": "Добавить новый ключ API для программного доступа к <link href='https://pocket-id.org/docs/api'>Pocket ID API</link>.",
|
||||
"add_api_key": "Добавить ключ API",
|
||||
@@ -186,7 +186,7 @@
|
||||
"email_login_notification": "Уведомление о логине по электронной почте",
|
||||
"send_an_email_to_the_user_when_they_log_in_from_a_new_device": "Отправлять пользователю письмо при входе с нового устройства.",
|
||||
"emai_login_code_requested_by_user": "Код входа по электронной почте, запрошенный пользователем",
|
||||
"allow_users_to_sign_in_with_a_login_code_sent_to_their_email": "Позволяет пользователям обходить вход через пасскей, запросив код входа, отправляемый на их электронную почту. Это значительно снижает безопасность так как любой человек, имеющий доступ к электронной почте пользователя, может получить доступ.",
|
||||
"allow_users_to_sign_in_with_a_login_code_sent_to_their_email": "Позволяет пользователям обойти ключи доступа, запросив код входа, отправляемый на их электронную почту. Это значительно снижает безопасность так как любой человек, имеющий доступ к электронной почте пользователя, сможет получить доступ.",
|
||||
"email_login_code_from_admin": "Код входа по электронной почте от администратора",
|
||||
"allows_an_admin_to_send_a_login_code_to_the_user": "Позволяет администратору отправлять код входа пользователю по электронной почте.",
|
||||
"send_test_email": "Отправить тестовое письмо",
|
||||
@@ -274,7 +274,7 @@
|
||||
"add_oidc_client": "Добавить OIDC клиент",
|
||||
"manage_oidc_clients": "Управление OIDC клиентами",
|
||||
"one_time_link": "Одноразовая ссылка",
|
||||
"use_this_link_to_sign_in_once": "Используйте эту ссылку, чтобы войти единожды. Это необходимо для пользователей, которые ещё не добавили пасскей или потеряли его.",
|
||||
"use_this_link_to_sign_in_once": "Используйте эту ссылку, чтобы войти один раз. Это необходимо для пользователей, которые ещё не добавили ключ доступа или потеряли его.",
|
||||
"add": "Добавить",
|
||||
"callback_urls": "URL-адреса обратного вызова",
|
||||
"logout_callback_urls": "URL-адреса обратного вызова при выходе",
|
||||
@@ -308,16 +308,16 @@
|
||||
"client_secret": "Секрет клиента",
|
||||
"show_more_details": "Показать больше деталей",
|
||||
"allowed_user_groups": "Разрешенные группы пользователей",
|
||||
"allowed_user_groups_description": "Выбери группы пользователей, члены которых могут входить в этот клиент.",
|
||||
"allowed_user_groups_description": "Выберите группы пользователей, члены которых могут входить в этот клиент.",
|
||||
"allowed_user_groups_status_unrestricted_description": "Никаких ограничений по группам пользователей нет. Любой может зайти в этот клиент.",
|
||||
"unrestrict": "Без ограничений",
|
||||
"unrestrict": "Снять ограничения",
|
||||
"restrict": "Ограничить",
|
||||
"user_groups_restriction_updated_successfully": "Ограничение групп пользователей обновлено успешно",
|
||||
"user_groups_restriction_updated_successfully": "Ограничение группами пользователей обновлено успешно",
|
||||
"allowed_user_groups_updated_successfully": "Разрешенные группы пользователей успешно обновлены",
|
||||
"favicon": "Значок",
|
||||
"light_mode_logo": "Логотип светлого режима",
|
||||
"dark_mode_logo": "Логотип темного режима",
|
||||
"email_logo": "Логотип электронной почты",
|
||||
"email_logo": "Логотип E-Mail",
|
||||
"background_image": "Фоновое изображение",
|
||||
"language": "Язык",
|
||||
"reset_profile_picture_question": "Сбросить изображение профиля?",
|
||||
@@ -334,14 +334,14 @@
|
||||
"all_clients": "Все клиенты",
|
||||
"all_locations": "Все местоположения",
|
||||
"global_audit_log": "Глобальный журнал аудита",
|
||||
"see_all_recent_account_activities": "Просмотри, что делали все пользователи на аккаунтах за период, который ты выбрал.",
|
||||
"see_all_recent_account_activities": "Просмотр активности всех пользователей в установленный период хранения.",
|
||||
"token_sign_in": "Вход с помощью токена",
|
||||
"client_authorization": "Авторизация клиента",
|
||||
"new_client_authorization": "Авторизация нового клиента",
|
||||
"device_code_authorization": "Авторизация через код устройства",
|
||||
"new_device_code_authorization": "Новая авторизация через код устройства",
|
||||
"passkey_added": "Пасскей добавлен",
|
||||
"passkey_removed": "Пасскей удален",
|
||||
"passkey_added": "Добавлен ключ доступа",
|
||||
"passkey_removed": "Удален ключ доступа",
|
||||
"disable_animations": "Отключить анимации",
|
||||
"turn_off_ui_animations": "Отключить все анимации в интерфейсе.",
|
||||
"user_disabled": "Учетная запись отключена",
|
||||
@@ -356,8 +356,8 @@
|
||||
"login_code_email_success": "Код входа был отправлен пользователю.",
|
||||
"send_email": "Отправить письмо",
|
||||
"show_code": "Показать код",
|
||||
"callback_url_description": "URL-адреса, которые дал твой клиент. Если поле оставить пустым, они добавятся автоматически. Поддерживаются <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>подстановочные знаки</link>.",
|
||||
"logout_callback_url_description": "URL-адреса, которые твой клиент дает для выхода из системы. Поддерживаются <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>подстановочные знаки</link>.",
|
||||
"callback_url_description": "URL-адрес(а), предоставленный вашим клиентом. Будет добавлен автоматически, если оставить поле пустым. Поддерживаются <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>шаблоны</link>.",
|
||||
"logout_callback_url_description": "URL-адрес(а) для выхода из системы, указанный(-е) в вашем клиенте. Поддерживаются <link href='https://pocket-id.org/docs/advanced/callback-url-wildcards'>шаблоны</link>.",
|
||||
"api_key_expiration": "Истечение срока действия ключа API",
|
||||
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "Отправлять пользователю письмо, когда срок действия его ключа API истекает.",
|
||||
"authorize_device": "Авторизовать устройство",
|
||||
@@ -413,9 +413,9 @@
|
||||
"go_to_login": "Перейти ко входу",
|
||||
"signup_to_appname": "Зарегистрироваться в {appName}",
|
||||
"create_your_account_to_get_started": "Создайте свою учетную запись, чтобы начать.",
|
||||
"initial_account_creation_description": "Пожалуйста, создайте свою учетную запись, чтобы начать. Вы сможете настроить пасскей позже.",
|
||||
"setup_your_passkey": "Настройте ваш пасскей",
|
||||
"create_a_passkey_to_securely_access_your_account": "Создайте пасскей для безопасного доступа к учетной записи. Это будет ваш основной способ входа.",
|
||||
"initial_account_creation_description": "Пожалуйста, создайте свою учетную запись, чтобы начать. Вы сможете настроить ключ доступа позже.",
|
||||
"setup_your_passkey": "Настройте ваш ключ доступа",
|
||||
"create_a_passkey_to_securely_access_your_account": "Создайте ключ доступа для безопасного доступа к учетной записи. Это будет ваш основной способ входа.",
|
||||
"skip_for_now": "Пока пропустить",
|
||||
"account_created": "Учетная запись создана",
|
||||
"enable_user_signups": "Включить регистрацию пользователей",
|
||||
@@ -440,8 +440,8 @@
|
||||
"signup_open": "Открытая регистрация",
|
||||
"signup_open_description": "Любой может создать новую учетную запись без ограничений.",
|
||||
"of": "из",
|
||||
"skip_passkey_setup": "Пропустить настройку пасскея",
|
||||
"skip_passkey_setup_description": "Настоятельно рекомендуется настроить пасскей, так как без него вы более не сможете войти в учетную запись после истечения сессии.",
|
||||
"skip_passkey_setup": "Пропустить настройку ключа доступа",
|
||||
"skip_passkey_setup_description": "Настоятельно рекомендуется настроить ключ доступа, так как без него вы не сможете войти в свою учетную запись по истечении сессии.",
|
||||
"my_apps": "Мои приложения",
|
||||
"no_apps_available": "Нет доступных приложений",
|
||||
"contact_your_administrator_for_app_access": "Свяжись с администратором, чтобы получить доступ к приложениям.",
|
||||
@@ -477,49 +477,49 @@
|
||||
"light": "Светлая",
|
||||
"dark": "Темная",
|
||||
"system": "Системная",
|
||||
"signup_token_user_groups_description": "Автоматически добавляй эти группы к пользователям, которые регистрируются с помощью этого токена.",
|
||||
"signup_token_user_groups_description": "Автоматически добавляйте эти группы к пользователям, которые регистрируются с помощью этого токена.",
|
||||
"allowed_oidc_clients": "Разрешенные клиенты OIDC",
|
||||
"allowed_oidc_clients_description": "Выбери клиентов OIDC, к которым могут подключаться участники этой группы пользователей.",
|
||||
"allowed_oidc_clients_description": "Выберите клиенты OIDC, в которые участникам этой группы пользователей разрешено входить.",
|
||||
"unrestrict_oidc_client": "Снять ограничения с {clientName}",
|
||||
"confirm_unrestrict_oidc_client_description": "Ты уверен, что хочешь снять ограничения с клиента OIDC <b>{clientName}</b>? Это удалит все групповые назначения для этого клиента, и любой пользователь сможет войти в систему.",
|
||||
"allowed_oidc_clients_updated_successfully": "Разрешенные клиенты OIDC обновились без проблем",
|
||||
"confirm_unrestrict_oidc_client_description": "Ты уверен, что хочешь снять ограничения с клиента OIDC <b>{clientName}</b>? Это удалит все назначенные группы для этого клиента, и любой пользователь сможет войти в систему.",
|
||||
"allowed_oidc_clients_updated_successfully": "Разрешенные OIDC клиенты успешно обновлены",
|
||||
"yes": "Да",
|
||||
"no": "Нет",
|
||||
"restricted": "Ограниченный",
|
||||
"scim_provisioning": "Настройка SCIM",
|
||||
"scim_provisioning_description": "SCIM позволяет автоматически добавлять и удалять пользователей и группы из твоего клиента OIDC. Подробнее читай в <link href='https://pocket-id.org/docs/configuration/scim'>документации</link>.",
|
||||
"scim_provisioning": "SCIM-провижининг",
|
||||
"scim_provisioning_description": "Провижининг по протоколу SCIM позволяет автоматически создавать и удалять пользователей и группы из вашего OIDC-клиента. Узнайте больше в <link href='https://pocket-id.org/docs/configuration/scim'>документации</link>.",
|
||||
"scim_endpoint": "Конечная точка SCIM",
|
||||
"scim_token": "Токен SCIM",
|
||||
"last_successful_sync_at": "Последняя удачная синхронизация: {time}",
|
||||
"scim_configuration_updated_successfully": "Настройки SCIM обновились без проблем.",
|
||||
"scim_enabled_successfully": "SCIM включен, все работает.",
|
||||
"scim_disabled_successfully": "SCIM отключен, все нормально.",
|
||||
"disable_scim_provisioning": "Отключить настройку SCIM",
|
||||
"scim_configuration_updated_successfully": "Конфигурация SCIM успешно обновлена.",
|
||||
"scim_enabled_successfully": "SCIM успешно включен.",
|
||||
"scim_disabled_successfully": "SCIM успешно отключен.",
|
||||
"disable_scim_provisioning": "Отключить SCIM-провижининг",
|
||||
"disable_scim_provisioning_confirm_description": "Ты уверен, что хочешь отключить SCIM-провижининг для <b>{clientName}</b>? Это остановит все автоматические действия по предоставлению и отмене доступа пользователей и групп.",
|
||||
"scim_sync_failed": "Синхронизация SCIM не получилась. Посмотри в журналах сервера, там будет больше инфо.",
|
||||
"scim_sync_successful": "Синхронизация SCIM прошла без проблем.",
|
||||
"scim_sync_failed": "Сбой синхронизации SCIM. Проверьте журналы сервера для получения дополнительной информации.",
|
||||
"scim_sync_successful": "Синхронизация SCIM успешно завершена.",
|
||||
"save_and_sync": "Сохранить и синхронизировать",
|
||||
"scim_save_changes_description": "Перед тем, как начать синхронизацию SCIM, нужно сохранить изменения. Хочешь сохранить сейчас?",
|
||||
"scopes": "Области применения",
|
||||
"issuer_url": "URL эмитента",
|
||||
"smtp_field_required_when_other_provided": "Нужно, если есть какие-то настройки SMTP",
|
||||
"smtp_field_required_when_email_enabled": "Нужно, если включены уведомления по электронной почте",
|
||||
"renew": "Обновлять",
|
||||
"renew_api_key": "Обнови ключ API",
|
||||
"scim_save_changes_description": "Вы должны сохранить изменения перед началом синхронизации SCIM. Сохранить сейчас?",
|
||||
"scopes": "Области доступа",
|
||||
"issuer_url": "URL издателя",
|
||||
"smtp_field_required_when_other_provided": "Требуется при указании любых настроек SMTP",
|
||||
"smtp_field_required_when_email_enabled": "Требуется, если включены уведомления по электронной почте",
|
||||
"renew": "Обновить",
|
||||
"renew_api_key": "Обновить ключ API",
|
||||
"renew_api_key_description": "При обновлении ключа API будет сгенерирован новый ключ. Не забудь обновить все интеграции, которые используют этот ключ.",
|
||||
"api_key_renewed": "Ключ API обновлен",
|
||||
"app_config_home_page": "Главная страница",
|
||||
"app_config_home_page_description": "Страница, куда пользователи попадают после входа в систему.",
|
||||
"email_verification_warning": "Проверь свой адрес электронной почты",
|
||||
"email_verification_warning_description": "Твой адрес электронной почты ещё не подтверждён. Пожалуйста, подтверди его как можно скорее.",
|
||||
"email_verification": "Проверка электронной почты",
|
||||
"email_verification_description": "Отправляй пользователям письмо с подтверждением, когда они регистрируются или меняют свой адрес электронной почты.",
|
||||
"email_verification_success_title": "Электронная почта подтверждена",
|
||||
"email_verification_success_description": "Твой адрес электронной почты подтвержден.",
|
||||
"email_verification_error_title": "Не получилось подтвердить почту",
|
||||
"mark_as_unverified": "Пометить как непроверенное",
|
||||
"mark_as_verified": "Пометить как проверенное",
|
||||
"email_verification_sent": "Письмо с подтверждением отправлено.",
|
||||
"emails_verified_by_default": "Электронные письма проверяются по умолчанию",
|
||||
"emails_verified_by_default_description": "Если эта функция включена, адреса электронной почты пользователей будут по умолчанию отмечаться как подтвержденные при регистрации или при изменении адреса электронной почты."
|
||||
"app_config_home_page_description": "Страница, на которую пользователи перенаправляются после входа.",
|
||||
"email_verification_warning": "Подтвердите ваш адрес электронной почты",
|
||||
"email_verification_warning_description": "Ваш адрес электронной почты ещё не подтверждён. Пожалуйста, подтвердите его как можно скорее.",
|
||||
"email_verification": "Подтверждение электронной почты",
|
||||
"email_verification_description": "Отправлять пользователям письмо с подтверждением при регистрации или изменении их адреса электронной почты.",
|
||||
"email_verification_success_title": "Электронная почта успешно подтверждена",
|
||||
"email_verification_success_description": "Ваш адрес электронной почты успешно подтвержден.",
|
||||
"email_verification_error_title": "Не удалось подтвердить электронную почту",
|
||||
"mark_as_unverified": "Пометить как неподтвержденную",
|
||||
"mark_as_verified": "Пометить как подтвержденную",
|
||||
"email_verification_sent": "Письмо с подтверждением успешно отправлено.",
|
||||
"emails_verified_by_default": "Электронные почты подтверждены по умолчанию",
|
||||
"emails_verified_by_default_description": "Если эта функция включена, адреса электронной почты пользователей будут по умолчанию помечаться как подтверждённые при регистрации или при смене адреса."
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"add_another": "Додати ще",
|
||||
"select_a_date": "Обрати дату",
|
||||
"select_file": "Обрати файл",
|
||||
"profile_picture": "Фотографія профілю",
|
||||
"profile_picture_is_managed_by_ldap_server": "Фотографія профілю управляється сервером LDAP і не може бути змінена тут.",
|
||||
"profile_picture": "Зображення профілю",
|
||||
"profile_picture_is_managed_by_ldap_server": "Зображення профілю керується сервером LDAP і не може бути змінене тут.",
|
||||
"click_profile_picture_to_upload_custom": "Натисніть на зображення профілю, щоб завантажити власне зображення.",
|
||||
"image_should_be_in_format": "Зображення повинно бути у форматі PNG, JPEG або WEBP.",
|
||||
"items_per_page": "Елементів на сторінці",
|
||||
@@ -28,7 +28,7 @@
|
||||
"login_background": "Фон сторінки входу",
|
||||
"logo": "Логотип",
|
||||
"login_code": "Код входу",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Створіть код входу, який користувач може використовувати для входу без ключа доступу одноразово.",
|
||||
"create_a_login_code_to_sign_in_without_a_passkey_once": "Створіть код входу, який користувач може одноразово використати для входу без ключа доступу.",
|
||||
"one_hour": "1 година",
|
||||
"twelve_hours": "12 годин",
|
||||
"one_day": "1 день",
|
||||
@@ -50,10 +50,10 @@
|
||||
"webauthn_error_invalid_domain": "Налаштований домен є недійсним.",
|
||||
"contact_administrator_to_fix": "Зверніться до адміністратора, щоб вирішити цю проблему.",
|
||||
"webauthn_operation_not_allowed_or_timed_out": "Операція не була дозволена або закінчився час очікування",
|
||||
"webauthn_not_supported_by_browser": "Цей браузер не підтримує паролі. Будь ласка, скористайтеся альтернативним методом входу.",
|
||||
"webauthn_not_supported_by_browser": "Цей браузер не підтримує ключі доступу. Будь ласка, скористайтеся альтернативним методом входу.",
|
||||
"critical_error_occurred_contact_administrator": "Виникла критична помилка. Будь ласка, зверніться до адміністратора.",
|
||||
"sign_in_to": "Увійти в {name}",
|
||||
"client_not_found": "Клієнта не знайдено",
|
||||
"client_not_found": "Клієнт не знайдений",
|
||||
"client_wants_to_access_the_following_information": "<b>{client}</b> хоче отримати доступ до наступної інформації:",
|
||||
"do_you_want_to_sign_in_to_client_with_your_app_name_account": "Бажаєте увійти до <b>{client}</b> за допомогою облікового запису {appName}?",
|
||||
"email": "Електронна пошта",
|
||||
@@ -90,7 +90,7 @@
|
||||
"enter_the_code_you_received_to_sign_in": "Введіть отриманий код, щоб увійти.",
|
||||
"code": "Код",
|
||||
"invalid_redirect_url": "Неправильна URL-адреса перенаправлення",
|
||||
"audit_log": "Журнал авдиту",
|
||||
"audit_log": "Журнал аудиту",
|
||||
"users": "Користувачі",
|
||||
"user_groups": "Групи користувачів",
|
||||
"oidc_clients": "Клієнти OIDC",
|
||||
@@ -135,14 +135,14 @@
|
||||
"are_you_sure_you_want_to_delete_this_passkey": "Ви впевнені, що хочете видалити цей ключ доступу?",
|
||||
"passkey_deleted_successfully": "Ключ доступу успішно видалено",
|
||||
"delete_passkey_name": "Видалити {passkeyName}",
|
||||
"passkey_name_updated_successfully": "Назва ключа доступу успішно оновлено",
|
||||
"passkey_name_updated_successfully": "Назву ключа доступу успішно оновлено",
|
||||
"name_passkey": "Назва ключа доступу",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Назвіть свій ключ доступу, щоб легко пізнати його пізніше.",
|
||||
"name_your_passkey_to_easily_identify_it_later": "Назвіть свій ключ доступу, щоб легко розпізнати його пізніше.",
|
||||
"create_api_key": "Створити API-ключ",
|
||||
"add_a_new_api_key_for_programmatic_access": "Додайте новий ключ API для програмного доступу до <link href='https://pocket-id.org/docs/api'>API Pocket ID</link>.",
|
||||
"add_a_new_api_key_for_programmatic_access": "Додайте новий API-ключ для програмного доступу до <link href='https://pocket-id.org/docs/api'>API Pocket ID</link>.",
|
||||
"add_api_key": "Додати API-ключ",
|
||||
"manage_api_keys": "Керувати ключами API",
|
||||
"api_key_created": "Створено API-ключ",
|
||||
"manage_api_keys": "Керувати API-ключами",
|
||||
"api_key_created": "API-ключ створено",
|
||||
"for_security_reasons_this_key_will_only_be_shown_once": "З міркувань безпеки цей ключ буде показано лише один раз. Будь ласка, збережіть його в безпечному місці.",
|
||||
"description": "Опис",
|
||||
"api_key": "API-ключ",
|
||||
@@ -152,11 +152,11 @@
|
||||
"when_this_api_key_will_expire": "Коли спливе термін дії цього API-ключа.",
|
||||
"optional_description_to_help_identify_this_keys_purpose": "Додатковий опис для допомоги в ідентифікації призначення цього ключа (необов’язково).",
|
||||
"expiration_date_must_be_in_the_future": "Дата закінчення терміну дії повинна бути в майбутньому",
|
||||
"revoke_api_key": "Анулювати API-ключ",
|
||||
"revoke_api_key": "Відкликати API-ключ",
|
||||
"never": "Ніколи",
|
||||
"revoke": "Анулювати",
|
||||
"api_key_revoked_successfully": "API-ключ успішно анульовано",
|
||||
"are_you_sure_you_want_to_revoke_the_api_key_apikeyname": "Ви впевнені, що хочете анулювати API-ключ «{apiKeyName}»? Це призведе до зупинки всіх інтеграцій, які використовують цей ключ.",
|
||||
"revoke": "Відкликати",
|
||||
"api_key_revoked_successfully": "API-ключ успішно відкликано",
|
||||
"are_you_sure_you_want_to_revoke_the_api_key_apikeyname": "Ви впевнені, що хочете відкликати API-ключ «{apiKeyName}»? Це призведе до зупинки всіх інтеграцій, які використовують цей ключ.",
|
||||
"last_used": "Останнє використання",
|
||||
"actions": "Дії",
|
||||
"images_updated_successfully": "Зображення успішно оновлено. Оновлення може зайняти кілька хвилин.",
|
||||
@@ -170,7 +170,7 @@
|
||||
"save_changes_question": "Зберегти зміни?",
|
||||
"you_have_to_save_the_changes_before_sending_a_test_email_do_you_want_to_save_now": "Ви повинні зберегти зміни перед надсиланням тестового листа. Зберегти зараз?",
|
||||
"save_and_send": "Зберегти та надіслати",
|
||||
"test_email_sent_successfully": "Тестовий лист успішно відправлено на вашу електронну адресу.",
|
||||
"test_email_sent_successfully": "Тестовий лист успішно надіслано на вашу електронну адресу.",
|
||||
"failed_to_send_test_email": "Не вдалося надіслати тестовий лист. Перевірте журнали сервера для отримання додаткової інформації.",
|
||||
"smtp_configuration": "Налаштування SMTP",
|
||||
"smtp_host": "SMTP хост",
|
||||
@@ -185,17 +185,17 @@
|
||||
"enabled_emails": "Увімкнені електронні листи",
|
||||
"email_login_notification": "Сповіщення електронною поштою про вхід",
|
||||
"send_an_email_to_the_user_when_they_log_in_from_a_new_device": "Надіслати електронний лист користувачеві після входу з нового пристрою.",
|
||||
"emai_login_code_requested_by_user": "Надіслати коду входу, згенерований користувачем, електронною поштою",
|
||||
"emai_login_code_requested_by_user": "Надіслати код входу, згенерований користувачем, електронною поштою",
|
||||
"allow_users_to_sign_in_with_a_login_code_sent_to_their_email": "Дозволяє користувачам обходити ключі доступу шляхом запиту коду для входу, який був відправлений на їх електронну пошту. Це суттєво зменшує безпеку, оскільки будь-хто, хто має доступ до електронної пошти користувача, може отримати доступ.",
|
||||
"email_login_code_from_admin": "Надіслати коду входу, згенерований адміністратором, електронною поштою",
|
||||
"email_login_code_from_admin": "Надіслати код входу, згенерований адміністратором, електронною поштою",
|
||||
"allows_an_admin_to_send_a_login_code_to_the_user": "Дозволяє адміністратору надсилати код для входу користувачеві електронною поштою.",
|
||||
"send_test_email": "Відправити тестового листа",
|
||||
"application_configuration_updated_successfully": "Налаштування додатку успішно оновлено",
|
||||
"application_name": "Назва додатку",
|
||||
"application_configuration_updated_successfully": "Налаштування застосунку успішно оновлено",
|
||||
"application_name": "Назва застосунку",
|
||||
"session_duration": "Тривалість сеансу",
|
||||
"the_duration_of_a_session_in_minutes_before_the_user_has_to_sign_in_again": "Тривалість сесії у хвилинах до повторного входу користувача.",
|
||||
"the_duration_of_a_session_in_minutes_before_the_user_has_to_sign_in_again": "Тривалість сеансу у хвилинах до повторного входу користувача.",
|
||||
"enable_self_account_editing": "Увімкнути редагування власного облікового запису",
|
||||
"whether_the_users_should_be_able_to_edit_their_own_account_details": "Чи повинні користувачі мати можливість редагувати власні дані облікового запису.",
|
||||
"whether_the_users_should_be_able_to_edit_their_own_account_details": "Чи повинні користувачі мати можливість редагувати дані свого облікового запису.",
|
||||
"ldap_configuration_updated_successfully": "Налаштування LDAP успішно оновлено",
|
||||
"ldap_disabled_successfully": "LDAP успішно вимкнено",
|
||||
"ldap_sync_finished": "Синхронізація LDAP завершена",
|
||||
@@ -279,7 +279,7 @@
|
||||
"callback_urls": "URL-адреси зворотного виклику",
|
||||
"logout_callback_urls": "URL-адреси зворотного виклику для виходу",
|
||||
"public_client": "Публічний клієнт",
|
||||
"public_clients_description": "Публічні клієнти не мають секретного ключа. Вони призначені для мобільних, веб та нативних додатків, де секретний ключ не може надійно зберігатись.",
|
||||
"public_clients_description": "Публічні клієнти не мають секретного ключа. Вони призначені для мобільних, веб та нативних застосунків, де секретний ключ не може надійно зберігатись.",
|
||||
"pkce": "PKCE",
|
||||
"public_key_code_exchange_is_a_security_feature_to_prevent_csrf_and_authorization_code_interception_attacks": "Public Key Code Exchange — це функція безпеки, що запобігає атакам типу CSRF та перехопленню коду авторизації.",
|
||||
"requires_reauthentication": "Потрібна повторна автентифікація",
|
||||
@@ -321,10 +321,10 @@
|
||||
"background_image": "Фонове зображення",
|
||||
"language": "Мова",
|
||||
"reset_profile_picture_question": "Скинути зображення профілю?",
|
||||
"this_will_remove_the_uploaded_image_and_reset_the_profile_picture_to_default": "Це видалить завантажене зображення та скине фото профілю на стандартне. Продовжити?",
|
||||
"this_will_remove_the_uploaded_image_and_reset_the_profile_picture_to_default": "Це видалить завантажене зображення та скине зображення профілю на стандартне. Продовжити?",
|
||||
"reset": "Скинути",
|
||||
"reset_to_default": "Відновити налаштування за замовчуванням",
|
||||
"profile_picture_has_been_reset": "Фотографію профілю скинуто. Оновлення може зайняти кілька хвилин.",
|
||||
"profile_picture_has_been_reset": "Зображення профілю скинуто. Оновлення може зайняти кілька хвилин.",
|
||||
"select_the_language_you_want_to_use": "Виберіть мову, яку бажаєте використовувати. Зверніть увагу, що деякий текст може бути автоматично перекладений і може містити неточності.",
|
||||
"contribute_to_translation": "Якщо ви знайдете помилку, ви можете долучитися до перекладу на <link href='https://crowdin.com/project/pocket-id'>Crowdin</link>.",
|
||||
"personal": "Особисте",
|
||||
@@ -333,26 +333,26 @@
|
||||
"all_events": "Усі події",
|
||||
"all_clients": "Усі клієнти",
|
||||
"all_locations": "Усі місця розташування",
|
||||
"global_audit_log": "Глобальний журнал авдиту",
|
||||
"global_audit_log": "Глобальний журнал аудиту",
|
||||
"see_all_recent_account_activities": "Перегляньте активність облікових записів усіх користувачів протягом встановленого періоду зберігання.",
|
||||
"token_sign_in": "Вхід за допомогою токена",
|
||||
"client_authorization": "Авторизація клієнта",
|
||||
"new_client_authorization": "Нова авторизація клієнта",
|
||||
"device_code_authorization": "Авторизація коду пристрою",
|
||||
"new_device_code_authorization": "Авторизація нового коду пристрою",
|
||||
"passkey_added": "Додано пароль",
|
||||
"passkey_added": "Ключ доступу додано",
|
||||
"passkey_removed": "Ключ доступу видалено",
|
||||
"disable_animations": "Вимкнути анімацію",
|
||||
"disable_animations": "Вимкнути анімації",
|
||||
"turn_off_ui_animations": "Вимкнути анімації у всьому інтерфейсі.",
|
||||
"user_disabled": "Обліковий запис вимкнено",
|
||||
"disabled_users_cannot_log_in_or_use_services": "Вимкнені користувачі не можуть увійти в систему або користуватися послугами.",
|
||||
"user_disabled": "Обліковий запис деактивовано",
|
||||
"disabled_users_cannot_log_in_or_use_services": "Деактивовані користувачі не можуть увійти в систему або користуватися сервісами.",
|
||||
"user_disabled_successfully": "Користувача успішно деактивовано.",
|
||||
"user_enabled_successfully": "Користувача успішно активовано.",
|
||||
"status": "Статус",
|
||||
"disable_firstname_lastname": "Деактивувати {firstName} {lastName}",
|
||||
"are_you_sure_you_want_to_disable_this_user": "Ви впевнені, що хочете вимкнути цього користувача? Він не зможе увійти в систему або користуватися будь-якими послугами.",
|
||||
"are_you_sure_you_want_to_disable_this_user": "Ви впевнені, що хочете деактивувати цього користувача? Він не зможе увійти в систему або отримати доступ до будь-яких сервісів.",
|
||||
"ldap_soft_delete_users": "Зберігати вимкнених користувачів із LDAP.",
|
||||
"ldap_soft_delete_users_description": "Якщо увімкнено, користувачів, видалених з LDAP, буде вимкнено, а не видалено з системи.",
|
||||
"ldap_soft_delete_users_description": "Якщо увімкнено, користувачів, видалених з LDAP, буде деактивовано, а не видалено з системи.",
|
||||
"login_code_email_success": "Код для входу було надіслано користувачеві.",
|
||||
"send_email": "Надіслати електронного листа",
|
||||
"show_code": "Показати код",
|
||||
@@ -379,7 +379,7 @@
|
||||
"userinfo": "Userinfo",
|
||||
"id_token_payload": "Вміст ID-токена",
|
||||
"access_token_payload": "Вміст токена доступу",
|
||||
"userinfo_endpoint_response": "Відповідь сервісу Userinfo",
|
||||
"userinfo_endpoint_response": "Відповідь кінцевої точки Userinfo",
|
||||
"copy": "Копіювати",
|
||||
"no_preview_data_available": "Попередній перегляд даних недоступний",
|
||||
"copy_all": "Скопіювати все",
|
||||
@@ -404,8 +404,8 @@
|
||||
"signup": "Зареєструватися",
|
||||
"user_creation": "Створення користувача",
|
||||
"configure_user_creation": "Керуйте налаштуваннями створення користувачів, включаючи методи реєстрації та права доступу за замовчуванням для нових користувачів.",
|
||||
"user_creation_groups_description": "Призначте ці групи автоматично новим користувачам під час реєстрації.",
|
||||
"user_creation_claims_description": "Призначте ці власні вимоги автоматично новим користувачам під час реєстрації.",
|
||||
"user_creation_groups_description": "Призначати ці групи автоматично новим користувачам під час реєстрації.",
|
||||
"user_creation_claims_description": "Призначати ці власні атрибути автоматично новим користувачам під час реєстрації.",
|
||||
"user_creation_updated_successfully": "Налаштування створення користувача успішно оновлено.",
|
||||
"signup_disabled_description": "Реєстрація користувачів повністю вимкнена. Нові облікові записи можуть створювати лише адміністратори.",
|
||||
"signup_requires_valid_token": "Для створення облікового запису потрібен дійсний токен реєстрації",
|
||||
@@ -413,10 +413,10 @@
|
||||
"go_to_login": "Перейти до входу",
|
||||
"signup_to_appname": "Зареєструватися в {appName}",
|
||||
"create_your_account_to_get_started": "Створіть свій обліковий запис, щоб розпочати.",
|
||||
"initial_account_creation_description": "Будь ласка, створіть свій обліковий запис, щоб почати. Ви зможете налаштувати ключ доступу пізніше.",
|
||||
"initial_account_creation_description": "Будь ласка, створіть свій обліковий запис, щоб розпочати. Ви зможете налаштувати ключ доступу пізніше.",
|
||||
"setup_your_passkey": "Налаштуйте свій ключ доступу",
|
||||
"create_a_passkey_to_securely_access_your_account": "Створіть ключ доступу для безпечного входу до свого облікового запису. Це буде ваш основний спосіб увійти.",
|
||||
"skip_for_now": "Пропустити наразі",
|
||||
"skip_for_now": "Поки що пропустити",
|
||||
"account_created": "Обліковий запис створено",
|
||||
"enable_user_signups": "Дозволити реєстрацію користувачів",
|
||||
"enable_user_signups_description": "Визначте, як користувачі можуть реєструвати нові облікові записи в Pocket ID.",
|
||||
@@ -442,29 +442,29 @@
|
||||
"of": "з",
|
||||
"skip_passkey_setup": "Пропустити налаштування ключа доступу",
|
||||
"skip_passkey_setup_description": "Рекомендується налаштувати ключ доступу, оскільки без нього ви не зможете увійти у свій обліковий запис після закінчення сеансу.",
|
||||
"my_apps": "Мої додатки",
|
||||
"no_apps_available": "Немає доступних додатків",
|
||||
"contact_your_administrator_for_app_access": "Зверніться до адміністратора, щоб отримати доступ до додатків.",
|
||||
"launch": "Запуск",
|
||||
"my_apps": "Мої застосунки",
|
||||
"no_apps_available": "Немає доступних застосунків",
|
||||
"contact_your_administrator_for_app_access": "Зверніться до адміністратора, щоб отримати доступ до застосунків.",
|
||||
"launch": "Запустити",
|
||||
"client_launch_url": "URL-адреса для запуску клієнта",
|
||||
"client_launch_url_description": "URL-адреса, яка відкриється, коли користувач запустить програму зі сторінки «Мої програми».",
|
||||
"client_name_description": "Назва клієнта, яке відображається в інтерфейсі Pocket ID.",
|
||||
"revoke_access": "Скасувати доступ",
|
||||
"revoke_access_description": "Скасувати доступ для <b>{clientName}</b>. <b>{clientName}</b> більше не зможе отримати доступ до інформації вашого облікового запису.",
|
||||
"revoke_access_successful": "Доступ для {clientName} було успішно скасовано.",
|
||||
"client_name_description": "Назва клієнта, яка відображається в інтерфейсі Pocket ID.",
|
||||
"revoke_access": "Відкликати доступ",
|
||||
"revoke_access_description": "Відкликати доступ для <b>{clientName}</b>. <b>{clientName}</b> більше не зможе отримати доступ до інформації вашого облікового запису.",
|
||||
"revoke_access_successful": "Доступ для {clientName} був успішно відкликаний.",
|
||||
"last_signed_in_ago": "Останній вхід {time} тому",
|
||||
"invalid_client_id": "Ідентифікатор клієнта може містити тільки літери, цифри, підкреслення та дефіси.",
|
||||
"custom_client_id_description": "Встановіть власний ідентифікатор клієнта, якщо це потрібно для вашої програми. В іншому випадку залиште поле порожнім, щоб створити випадковий ідентифікатор.",
|
||||
"invalid_client_id": "Ідентифікатор клієнта може містити тільки літери, цифри, підкреслення та дефіси",
|
||||
"custom_client_id_description": "Встановіть власний ідентифікатор клієнта, якщо це вимагається вашим застосунком. В іншому випадку залиште поле порожнім, щоб згенерувати випадковий.",
|
||||
"generated": "Створено",
|
||||
"administration": "Адміністрування",
|
||||
"group_rdn_attribute_description": "Атрибут, що використовується в розрізнювальному імені групи (DN).",
|
||||
"display_name_attribute": "Атрибут імені для відображення",
|
||||
"display_name": "Ім'я для відображення",
|
||||
"configure_application_images": "Налаштування зображень додатків",
|
||||
"configure_application_images": "Налаштування зображень застосунку",
|
||||
"ui_config_disabled_info_title": "Конфігурація інтерфейсу користувача вимкнена",
|
||||
"ui_config_disabled_info_description": "Конфігурація інтерфейсу користувача вимкнена, оскільки налаштування конфігурації програми керуються через змінні середовища. Деякі налаштування можуть бути недоступними для редагування.",
|
||||
"logo_from_url_description": "Вставте прямий URL-адресу зображення (svg, png, webp). Знайдіть іконки на <link href=\"https://selfh.st/icons\">Selfh.st Icons</link> або <link href=\"https://dashboardicons.com\">Dashboard Icons</link>.",
|
||||
"invalid_url": "Недійсний URL-адреса",
|
||||
"logo_from_url_description": "Вставте пряму URL-адресу зображення (svg, png, webp). Знайдіть іконки на <link href=\"https://selfh.st/icons\">Selfh.st Icons</link> або <link href=\"https://dashboardicons.com\">Dashboard Icons</link>.",
|
||||
"invalid_url": "Недійсна URL-адреса",
|
||||
"require_user_email": "Потрібна адреса електронної пошти",
|
||||
"require_user_email_description": "Вимагає від користувачів наявність адреси електронної пошти. Якщо ця опція вимкнена, користувачі без адреси електронної пошти не зможуть користуватися функціями, для яких потрібна адреса електронної пошти.",
|
||||
"view": "Перегляд",
|
||||
@@ -474,13 +474,13 @@
|
||||
"reauthentication": "Повторна аутентифікація",
|
||||
"clear_filters": "Очистити фільтри",
|
||||
"default_profile_picture": "Стандартне зображення профілю",
|
||||
"light": "Світло",
|
||||
"dark": "Темний",
|
||||
"system": "Система",
|
||||
"signup_token_user_groups_description": "Автоматично призначайте ці групи користувачам, які реєструються за допомогою цього токена.",
|
||||
"light": "Світла",
|
||||
"dark": "Темна",
|
||||
"system": "Системна",
|
||||
"signup_token_user_groups_description": "Автоматично призначати ці групи користувачам, які реєструються за допомогою цього токена.",
|
||||
"allowed_oidc_clients": "Дозволені клієнти OIDC",
|
||||
"allowed_oidc_clients_description": "Виберіть клієнти OIDC, до яких члени цієї групи користувачів мають право входити.",
|
||||
"unrestrict_oidc_client": "Без обмежень {clientName}",
|
||||
"unrestrict_oidc_client": "Не обмежувати {clientName}",
|
||||
"confirm_unrestrict_oidc_client_description": "Ви впевнені, що хочете зняти обмеження з клієнта OIDC <b>{clientName}</b>? Це призведе до видалення всіх групових призначень для цього клієнта, і будь-який користувач зможе увійти в систему.",
|
||||
"allowed_oidc_clients_updated_successfully": "Дозволені клієнти OIDC успішно оновлені",
|
||||
"yes": "Так",
|
||||
@@ -505,9 +505,9 @@
|
||||
"smtp_field_required_when_other_provided": "Необхідно, якщо вказано будь-яке налаштування SMTP",
|
||||
"smtp_field_required_when_email_enabled": "Необхідно, якщо увімкнено сповіщення електронною поштою",
|
||||
"renew": "Оновити",
|
||||
"renew_api_key": "Оновити ключ API",
|
||||
"renew_api_key": "Оновити API-ключ",
|
||||
"renew_api_key_description": "Оновлення API-ключа призведе до створення нового ключа. Обов'язково оновіть усі інтеграції, що використовують цей ключ.",
|
||||
"api_key_renewed": "Ключ API оновлено",
|
||||
"api_key_renewed": "API-ключ оновлено",
|
||||
"app_config_home_page": "Головна сторінка",
|
||||
"app_config_home_page_description": "Сторінка, на яку перенаправляють користувачів після входу в систему.",
|
||||
"email_verification_warning": "Підтвердьте свою адресу електронної пошти",
|
||||
|
||||
@@ -474,8 +474,8 @@
|
||||
"reauthentication": "重新驗證",
|
||||
"clear_filters": "清除篩選條件",
|
||||
"default_profile_picture": "預設個人資料照片",
|
||||
"light": "光",
|
||||
"dark": "黑暗",
|
||||
"light": "亮色",
|
||||
"dark": "暗色",
|
||||
"system": "系統",
|
||||
"signup_token_user_groups_description": "自動將這些群組指派給使用此代幣註冊的用戶。",
|
||||
"allowed_oidc_clients": "允許的 OIDC 客戶端",
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
{
|
||||
"name": "pocket-id-frontend",
|
||||
"version": "2.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "vite dev --port 3000",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 3000",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"axios": "^1.13.2",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"jose": "^6.1.3",
|
||||
"qrcode": "^1.5.4",
|
||||
"runed": "^0.37.1",
|
||||
"sveltekit-superforms": "^2.29.1",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"zod": "^4.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inlang/paraglide-js": "^2.7.1",
|
||||
"@inlang/plugin-m-function-matcher": "^2.1.0",
|
||||
"@inlang/plugin-message-format": "^4.0.0",
|
||||
"@internationalized/date": "^3.10.1",
|
||||
"@lucide/svelte": "^0.559.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.49.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^24.10.4",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"bits-ui": "^2.14.4",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.13.1",
|
||||
"formsnap": "^2.0.1",
|
||||
"globals": "^16.5.0",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.7.4",
|
||||
"prettier-plugin-svelte": "^3.4.1",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"rollup": "^4.54.0",
|
||||
"svelte": "^5.46.1",
|
||||
"svelte-check": "^4.3.5",
|
||||
"svelte-sonner": "^1.0.7",
|
||||
"tailwind-variants": "^3.2.2",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"tslib": "^2.8.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.51.0",
|
||||
"vite": "^7.3.0"
|
||||
}
|
||||
"name": "pocket-id-frontend",
|
||||
"version": "2.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "vite dev --port 3000",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 3000",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2",
|
||||
"@tailwindcss/vite": "^4.2.0",
|
||||
"axios": "^1.13.5",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"jose": "^6.1.3",
|
||||
"qrcode": "^1.5.4",
|
||||
"runed": "^0.37.1",
|
||||
"sveltekit-superforms": "^2.30.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inlang/paraglide-js": "^2.12.0",
|
||||
"@inlang/plugin-m-function-matcher": "^2.2.1",
|
||||
"@inlang/plugin-message-format": "^4.3.0",
|
||||
"@internationalized/date": "^3.11.0",
|
||||
"@lucide/svelte": "^0.559.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.53.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^24.10.13",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"bits-ui": "^2.16.2",
|
||||
"eslint": "^9.39.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.15.0",
|
||||
"formsnap": "^2.0.1",
|
||||
"globals": "^16.5.0",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.5.0",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"rollup": "^4.59.0",
|
||||
"svelte": "^5.53.2",
|
||||
"svelte-check": "^4.4.3",
|
||||
"svelte-sonner": "^1.0.7",
|
||||
"tailwind-variants": "^3.2.2",
|
||||
"tailwindcss": "^4.2.0",
|
||||
"tslib": "^2.8.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.56.0",
|
||||
"vite": "^7.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
1
frontend/project.inlang/.gitignore
vendored
1
frontend/project.inlang/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
cache
|
||||
@@ -7,12 +7,14 @@
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"et",
|
||||
"fi",
|
||||
"fr",
|
||||
"it",
|
||||
"ja",
|
||||
"ko",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
inputClass?: string;
|
||||
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox' | 'date';
|
||||
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox' | 'date' | 'url';
|
||||
onInput?: (e: FormInputEvent) => void;
|
||||
} = $props();
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
oninput={(e) => (url = e.currentTarget.value)}
|
||||
onfocusout={handleUrlChange}
|
||||
aria-invalid={hasError}
|
||||
type="url"
|
||||
/>
|
||||
{#if hasError}
|
||||
<p class="text-destructive mt-1 text-start text-xs">{m.invalid_url()}</p>
|
||||
|
||||
@@ -27,10 +27,7 @@
|
||||
>
|
||||
<div class="flex h-16 items-center">
|
||||
{#if !isAuthPage}
|
||||
<a
|
||||
href="/"
|
||||
class="flex items-center gap-3 transition-opacity hover:opacity-80"
|
||||
>
|
||||
<a href="/" class="flex items-center gap-3 transition-opacity hover:opacity-80">
|
||||
<Logo class="size-8" />
|
||||
<h1 class="text-lg font-semibold tracking-tight" data-testid="application-name">
|
||||
{$appConfigStore.appName}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Root from "./toggle.svelte";
|
||||
import Root from './toggle.svelte';
|
||||
export {
|
||||
toggleVariants,
|
||||
type ToggleSize,
|
||||
type ToggleVariant,
|
||||
type ToggleVariants,
|
||||
} from "./toggle.svelte";
|
||||
type ToggleVariants
|
||||
} from './toggle.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Toggle,
|
||||
Root as Toggle
|
||||
};
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
<script lang="ts" module>
|
||||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
import { type VariantProps, tv } from 'tailwind-variants';
|
||||
|
||||
export const toggleVariants = tv({
|
||||
base: "hover:bg-muted hover:text-muted-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-transparent",
|
||||
default: 'bg-transparent',
|
||||
outline:
|
||||
"border-input hover:bg-accent hover:text-accent-foreground border bg-transparent shadow-xs",
|
||||
'border-input hover:bg-accent hover:text-accent-foreground border bg-transparent shadow-xs'
|
||||
},
|
||||
size: {
|
||||
default: "h-9 min-w-9 px-2",
|
||||
sm: "h-8 min-w-8 px-1.5",
|
||||
lg: "h-10 min-w-10 px-2.5",
|
||||
},
|
||||
default: 'h-9 min-w-9 px-2',
|
||||
sm: 'h-8 min-w-8 px-1.5',
|
||||
lg: 'h-10 min-w-10 px-2.5'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
variant: 'default',
|
||||
size: 'default'
|
||||
}
|
||||
});
|
||||
|
||||
export type ToggleVariant = VariantProps<typeof toggleVariants>["variant"];
|
||||
export type ToggleSize = VariantProps<typeof toggleVariants>["size"];
|
||||
export type ToggleVariant = VariantProps<typeof toggleVariants>['variant'];
|
||||
export type ToggleSize = VariantProps<typeof toggleVariants>['size'];
|
||||
export type ToggleVariants = VariantProps<typeof toggleVariants>;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { Toggle as TogglePrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/style.js";
|
||||
import { Toggle as TogglePrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils/style.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
pressed = $bindable(false),
|
||||
class: className,
|
||||
size = "default",
|
||||
variant = "default",
|
||||
size = 'default',
|
||||
variant = 'default',
|
||||
...restProps
|
||||
}: TogglePrimitive.RootProps & {
|
||||
variant?: ToggleVariant;
|
||||
|
||||
@@ -20,7 +20,7 @@ export type User = {
|
||||
|
||||
export type UserCreate = Omit<User, 'id' | 'customClaims' | 'ldapId' | 'userGroups'>;
|
||||
|
||||
export type AccountUpdate = Omit<UserCreate, 'isAdmin' | 'disabled' | 'emailVerified'>
|
||||
export type AccountUpdate = Omit<UserCreate, 'isAdmin' | 'disabled' | 'emailVerified'>;
|
||||
|
||||
export type UserSignUp = Omit<
|
||||
UserCreate,
|
||||
|
||||
@@ -10,8 +10,13 @@ export const load: LayoutLoad = async () => {
|
||||
let isUpToDate = true;
|
||||
try {
|
||||
newestVersion = await versionService.getNewestVersion();
|
||||
isUpToDate = newestVersion === currentVersion;
|
||||
} catch {}
|
||||
// If newestVersion is empty, it means the check is disabled or failed.
|
||||
// In this case, we assume the version is up to date.
|
||||
isUpToDate = newestVersion === '' || newestVersion === currentVersion;
|
||||
} catch {
|
||||
// If the request fails, assume up-to-date to avoid showing a warning.
|
||||
isUpToDate = true;
|
||||
}
|
||||
|
||||
const versionInformation: AppVersionInformation = {
|
||||
currentVersion: versionService.getCurrentVersion(),
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
de: 'Deutsch',
|
||||
en: 'English',
|
||||
es: 'Español',
|
||||
et: 'Eesti',
|
||||
fi: 'Suomi',
|
||||
fr: 'Français',
|
||||
it: 'Italiano',
|
||||
ja: '日本語',
|
||||
ko: '한국어',
|
||||
nl: 'Nederlands',
|
||||
no: 'Norsk',
|
||||
pl: 'Polski',
|
||||
'pt-BR': 'Português brasileiro',
|
||||
ru: 'Русский',
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<Input
|
||||
aria-invalid={!!error}
|
||||
data-testid={`callback-url-${i + 1}`}
|
||||
type="url"
|
||||
bind:value={callbackURLs[i]}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
label={m.client_launch_url()}
|
||||
description={m.client_launch_url_description()}
|
||||
class="w-full"
|
||||
type="url"
|
||||
bind:input={$inputs.launchURL}
|
||||
/>
|
||||
<OidcCallbackUrlInput
|
||||
|
||||
1670
pnpm-lock.yaml
generated
1670
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,11 @@ packages:
|
||||
- email-templates
|
||||
|
||||
overrides:
|
||||
cookie@<0.7.0: '>=0.7.0'
|
||||
devalue: ^5.3.2
|
||||
glob@>=11.0.0 <11.1.0: '>=11.1.0'
|
||||
js-yaml@>=4.0.0 <4.1.1: '>=4.1.1'
|
||||
valibot@>=0.31.0 <1.2.0: '>=1.2.0'
|
||||
validator@<13.15.20: '>=13.15.20'
|
||||
cookie@<0.7.0: ">=0.7.0"
|
||||
devalue: ^5.6.2
|
||||
glob@>=11.0.0 <11.1.0: ">=11.1.0"
|
||||
js-yaml@>=4.0.0 <4.1.1: ">=4.1.1"
|
||||
valibot@>=0.31.0 <1.2.0: ">=1.2.0"
|
||||
validator@<13.15.20: ">=13.15.20"
|
||||
"@isaacs/brace-expansion": ">=5.0.1"
|
||||
next: ">=16.1.5"
|
||||
|
||||
Reference in New Issue
Block a user