diff --git a/.gitignore b/.gitignore index 0cd0161e..7efcaced 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,7 @@ /completions/ /.env -authorized_keys - __debug_bin* /smallweb -/www \ No newline at end of file +/www +TODO.md \ No newline at end of file diff --git a/example/.github/copilot-instructions.md b/example/.github/copilot-instructions.md index 999269b0..ba8c09ad 100644 --- a/example/.github/copilot-instructions.md +++ b/example/.github/copilot-instructions.md @@ -183,55 +183,6 @@ for (const row of rows) { db.close(); ``` -## Private Apps - -Apps can be protected behind authentication. To do this, you'll first need to make sure than an oidc provider is configured in the `.smallweb/config.json[c]` file. - -```json -{ - "oidc": { - // use lastlogin.net as the oidc provider if none is specified - "issuer": "https://lastlogin.net" - }, - "authorizedEmails": [ - "pomdtr@example.com" - ] -} -``` - -Then, you can set the `private` property in the `smallweb.json` file to `true`: - -```json -{ - "private": true -} -``` - -Or protect only specific routes: - -```json -{ - "privateRoutes": [ - "/admin/*" - ] -} -``` - -The user email can then be retrieved using the `Remote-Email` header: - -```ts -export default { - fetch(req: Request) { - const email = req.headers.get("Remote-Email"); - if (!email) { - return new Response("Unauthorized", { status: 401 }); - } - - return new Response(`Hello ${email}`); - }, -} -``` - ## Dependencies Smallweb supports importing dependencies from urls, or npm/jsr packages. You can use the `npm:` prefix to import npm packages. diff --git a/example/.smallweb/config.jsonc b/example/.smallweb/config.jsonc index f17b991e..e57e0f56 100644 --- a/example/.smallweb/config.jsonc +++ b/example/.smallweb/config.jsonc @@ -1,10 +1,4 @@ { "$schema": "../../schemas/config.schema.json", - "domain": "smallweb.traefik.me", - "oidc": { - "issuer": "https://lastlogin.net" - }, - "authorizedEmails": [ - "achille.lacoin@gmail.com" - ] + "domain": "smallweb.live" } diff --git a/example/cli/main.ts b/example/cli/main.ts deleted file mode 100644 index ee59ebe7..00000000 --- a/example/cli/main.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { cli } from 'npm:gunshi@0.17.0' - -export default { - async run(args: string[]) { - await cli(args, { - options: { - name: { - type: "string", - default: "world", - } - }, - run: (ctx) => { - console.log(`Hello ${ctx.values.name}!`) - } - }) - } -} diff --git a/example/hello/main.ts b/example/hello/main.ts new file mode 100644 index 00000000..5f285432 --- /dev/null +++ b/example/hello/main.ts @@ -0,0 +1,9 @@ +import { Hono } from "npm:hono@4.11.7" + +const app = new Hono() + +app.post("/hooks/cli", (c) => { + return c.text(`Hello, ${c.req.query("name") || "world"}!`, 400) +}) + +export default app \ No newline at end of file diff --git a/example/ls/smallweb.json b/example/ls/smallweb.json deleted file mode 100644 index 4dbacef8..00000000 --- a/example/ls/smallweb.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "admin": true, - "private": true -} diff --git a/go.mod b/go.mod index e121a022..7a940a92 100644 --- a/go.mod +++ b/go.mod @@ -1,96 +1,88 @@ module github.com/pomdtr/smallweb -go 1.24 +go 1.25.0 require ( github.com/Masterminds/semver v1.5.0 github.com/adrg/xdg v0.5.3 - github.com/cli/go-gh/v2 v2.12.1 + github.com/cli/go-gh/v2 v2.13.0 github.com/gorilla/websocket v1.5.3 github.com/joho/godotenv v1.5.1 github.com/knadh/koanf/providers/env v1.1.0 - github.com/knadh/koanf/providers/file v1.2.0 - github.com/knadh/koanf/v2 v2.2.2 + github.com/knadh/koanf/providers/file v1.2.1 + github.com/knadh/koanf/v2 v2.3.2 github.com/mattn/go-isatty v0.0.20 - github.com/spf13/cobra v1.9.1 + github.com/spf13/cobra v1.10.2 github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33 - golang.org/x/net v0.41.0 // indirect - golang.org/x/term v0.33.0 + golang.org/x/net v0.48.0 // indirect + golang.org/x/term v0.39.0 ) require ( - github.com/abiosoft/ishell/v2 v2.0.2 - github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db - github.com/bmatcuk/doublestar/v4 v4.9.0 - github.com/caddyserver/certmagic v0.23.0 + github.com/caddyserver/certmagic v0.25.1 github.com/charmbracelet/ssh v0.0.0-20250213143314-8712ec3ff3ef github.com/charmbracelet/wish v1.4.7 - github.com/coreos/go-oidc/v3 v3.14.1 - github.com/creack/pty v1.1.24 github.com/fsnotify/fsnotify v1.9.0 - github.com/getsops/sops/v3 v3.10.2 + github.com/getsops/sops/v3 v3.11.0 github.com/knadh/koanf/providers/confmap v1.0.0 github.com/knadh/koanf/providers/posflag v1.0.1 github.com/leaanthony/gosod v1.0.4 - github.com/lmittmann/tint v1.1.2 + github.com/lmittmann/tint v1.1.3 github.com/mhale/smtpd v0.8.3 - github.com/pkg/sftp v1.13.9 + github.com/mnako/letters v0.2.8 github.com/robfig/cron/v3 v3.0.1 - github.com/samber/slog-http v1.7.0 - go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.40.0 - golang.org/x/oauth2 v0.30.0 + github.com/samber/slog-http v1.11.1 + go.uber.org/zap v1.27.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) require ( - cel.dev/expr v0.22.1 // indirect - cloud.google.com/go v0.120.0 // indirect - cloud.google.com/go/auth v0.15.0 // indirect + cel.dev/expr v0.24.0 // indirect + cloud.google.com/go v0.121.6 // indirect + cloud.google.com/go/auth v0.16.5 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.4.2 // indirect - cloud.google.com/go/kms v1.21.1 // indirect - cloud.google.com/go/longrunning v0.6.6 // indirect - cloud.google.com/go/monitoring v1.24.1 // indirect - cloud.google.com/go/storage v1.51.0 // indirect + cloud.google.com/go/compute/metadata v0.8.4 // indirect + cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/kms v1.23.0 // indirect + cloud.google.com/go/longrunning v0.6.7 // indirect + cloud.google.com/go/monitoring v1.24.2 // indirect + cloud.google.com/go/storage v1.57.0 // indirect filippo.io/age v1.2.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect - github.com/ProtonMail/go-crypto v1.2.0 // indirect - github.com/abiosoft/ishell v2.0.0+incompatible // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect - github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect + github.com/aws/aws-sdk-go-v2 v1.39.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/config v1.31.11 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.15 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect - github.com/aws/smithy-go v1.22.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.29.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 // indirect + github.com/aws/smithy-go v1.23.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect - github.com/caddyserver/zerossl v0.1.3 // indirect + github.com/caddyserver/zerossl v0.1.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/bubbletea v1.3.4 // indirect @@ -105,52 +97,50 @@ require ( github.com/charmbracelet/x/term v0.2.1 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect - github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect + github.com/creack/pty v1.1.24 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e // indirect - github.com/go-jose/go-jose/v4 v4.0.5 // indirect + github.com/go-jose/go-jose/v4 v4.1.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.3.0 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.14.1 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.7 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/vault/api v1.16.0 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/hashicorp/vault/api v1.21.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect - github.com/kr/fs v0.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/libdns/libdns v1.0.0-beta.1 // indirect + github.com/libdns/libdns v1.1.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mholt/acmez/v3 v3.1.2 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/mholt/acmez/v3 v3.1.4 // indirect + github.com/miekg/dns v1.1.69 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -163,40 +153,43 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/pflag v1.0.6 // indirect - github.com/urfave/cli v1.22.16 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect + github.com/urfave/cli v1.22.17 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/zeebo/blake3 v0.2.4 // indirect + github.com/zeebo/errs v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/sdk v1.35.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.46.0 // indirect golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect - golang.org/x/mod v0.25.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.34.0 // indirect - google.golang.org/api v0.228.0 // indirect - google.golang.org/genproto v0.0.0-20250324211829-b45e905df463 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect - google.golang.org/grpc v1.71.1 // indirect - google.golang.org/protobuf v1.36.6 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/oauth2 v0.31.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.39.0 // indirect + google.golang.org/api v0.250.0 // indirect + google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/grpc v1.75.1 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index dac7444a..de29eac0 100644 --- a/go.sum +++ b/go.sum @@ -1,62 +1,62 @@ c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= -cel.dev/expr v0.22.1 h1:xoFEsNh972Yzey8N9TCPx2nDvMN7TMhQEzxLuj/iRrI= -cel.dev/expr v0.22.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= +cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI= +cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/iam v1.4.2 h1:4AckGYAYsowXeHzsn/LCKWIwSWLkdb0eGjH8wWkd27Q= -cloud.google.com/go/iam v1.4.2/go.mod h1:REGlrt8vSlh4dfCJfSEcNjLGq75wW75c5aU3FLOYq34= -cloud.google.com/go/kms v1.21.1 h1:r1Auo+jlfJSf8B7mUnVw5K0fI7jWyoUy65bV53VjKyk= -cloud.google.com/go/kms v1.21.1/go.mod h1:s0wCyByc9LjTdCjG88toVs70U9W+cc6RKFc8zAqX7nE= +cloud.google.com/go/compute/metadata v0.8.4 h1:oXMa1VMQBVCyewMIOm3WQsnVd9FbKBtm8reqWRaXnHQ= +cloud.google.com/go/compute/metadata v0.8.4/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.23.0 h1:WaqAZsUptyHwOo9II8rFC1Kd2I+yvNsNP2IJ14H2sUw= +cloud.google.com/go/kms v1.23.0/go.mod h1:rZ5kK0I7Kn9W4erhYVoIRPtpizjunlrfU4fUkumUp8g= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= -cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR65Rbw= -cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= -cloud.google.com/go/monitoring v1.24.1 h1:vKiypZVFD/5a3BbQMvI4gZdl8445ITzXFh257XBgrS0= -cloud.google.com/go/monitoring v1.24.1/go.mod h1:Z05d1/vn9NaujqY2voG6pVQXoJGbp+r3laV+LySt9K0= -cloud.google.com/go/storage v1.51.0 h1:ZVZ11zCiD7b3k+cH5lQs/qcNaoSz3U9I0jgwVzqDlCw= -cloud.google.com/go/storage v1.51.0/go.mod h1:YEJfu/Ki3i5oHC/7jyTgsGZwdQ8P9hqMqvpi5kRKGgc= -cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= -cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +cloud.google.com/go/storage v1.57.0 h1:4g7NB7Ta7KetVbOMpCqy89C+Vg5VE8scqlSHUPm7Rds= +cloud.google.com/go/storage v1.57.0/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg= +cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= +cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o= filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0/go.mod h1:Y2b/1clN4zsAoUd/pgNAQHjLDnTis/6ROkUfyob6psM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0/go.mod h1:jUZ5LYlw40WMd07qxcQJD5M40aUxrfwqQX1g7zxYnrQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -65,68 +65,60 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs= -github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= -github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw= -github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg= -github.com/abiosoft/ishell/v2 v2.0.2 h1:5qVfGiQISaYM8TkbBl7RFO6MddABoXpATrsFbVI+SNo= -github.com/abiosoft/ishell/v2 v2.0.2/go.mod h1:E4oTCXfo6QjoCart0QYa5m9w4S+deXs/P/9jA77A9Bs= -github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8= -github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= -github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14= -github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM= -github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 h1:PcKMOZfp+kNtJTw2HF2op6SjDvwPBYRvz0Y24PQLUR4= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72/go.mod h1:vq7/m7dahFXcdzWVOvvjasDI9RcsD3RsTfHmDundJYg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= +github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1/go.mod h1:ddqbooRZYNoJ2dsTwOty16rM+/Aqmk/GOXrK8cg7V00= +github.com/aws/aws-sdk-go-v2/config v1.31.11 h1:6QOO1mP0MgytbfKsL/r/gE1P6/c/4pPzrrU3hKxa5fs= +github.com/aws/aws-sdk-go-v2/config v1.31.11/go.mod h1:KzpDsPX/dLxaUzoqM3sN2NOhbQIW4HW/0W8rQA1YFEs= +github.com/aws/aws-sdk-go-v2/credentials v1.18.15 h1:Gqy7/05KEfUSulSvwxnB7t8DuZMR3ShzNcwmTD6HOLU= +github.com/aws/aws-sdk-go-v2/credentials v1.18.15/go.mod h1:VWDWSRpYHjcjURRaQ7NUzgeKFN8Iv31+EOMT/W+bFyc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 h1:Z1897HnnfLLgbs3pcUv8xLvtbai9TEfPUZfA0BFw968= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9/go.mod h1:8oVESJIPBYGWdZhaHcIvTm7BnI6hbsR3ggKn0uyRMhk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA= -github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 h1:RivOtUH3eEu6SWnUMFHKAW4MqDOzWn1vGQ3S38Y5QMg= -github.com/aws/aws-sdk-go-v2/service/kms v1.38.3/go.mod h1:cQn6tAF77Di6m4huxovNM7NVAozWTZLsDRp9t8Z/WYk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 h1:tWUG+4wZqdMl/znThEk9tcCy8tTMxq8dW0JTgamohrY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k= -github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 h1:w9LnHqTq8MEdlnyhV4Bwfizd65lfNCNgdlNC6mM5paE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9/go.mod h1:LGEP6EK4nj+bwWNdrvX/FnDTFowdBNwcSPuZu/ouFys= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 h1:by3nYZLR9l8bUH7kgaMU4dJgYFjyRdFEfORlDpPILB4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9/go.mod h1:IWjQYlqw4EX9jw2g3qnEPPWvCE6bS8fKzhMed1OK7c8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 h1:wuZ5uW2uhJR63zwNlqWH2W4aL4ZjeJP3o92/W+odDY4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9/go.mod h1:/G58M2fGszCrOzvJUkDdY8O9kycodunH4VdT5oBAqls= +github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 h1:Br3kil4j7RPW+7LoLVkYt8SuhIWlg6ylmbmzXJ7PgXY= +github.com/aws/aws-sdk-go-v2/service/kms v1.45.6/go.mod h1:FKXkHzw1fJZtg1P1qoAIiwen5thz/cDRTTDCIu8ljxc= +github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3 h1:P18I4ipbk+b/3dZNq5YYh+Hq6XC0vp5RWkLp1tJldDA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3/go.mod h1:Rm3gw2Jov6e6kDuamDvyIlZJDMYk97VeCZ82wz/mVZ0= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.5 h1:WwL5YLHabIBuAlEKRoLgqLz1LxTvCEpwsQr7MiW/vnM= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.5/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmatcuk/doublestar/v4 v4.9.0 h1:DBvuZxjdKkRP/dr4GVV4w2fnmrk5Hxc90T51LZjv0JA= -github.com/bmatcuk/doublestar/v4 v4.9.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= -github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4= -github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= -github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= +github.com/caddyserver/certmagic v0.25.1 h1:4sIKKbOt5pg6+sL7tEwymE1x2bj6CHr80da1CRRIPbY= +github.com/caddyserver/certmagic v0.25.1/go.mod h1:VhyvndxtVton/Fo/wKhRoC46Rbw1fmjvQ3GjHYSQTEY= +github.com/caddyserver/zerossl v0.1.4 h1:CVJOE3MZeFisCERZjkxIcsqIH4fnFdlYWnPYeFtBHRw= +github.com/caddyserver/zerossl v0.1.4/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -157,31 +149,23 @@ github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQ github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cli/go-gh/v2 v2.12.1 h1:SVt1/afj5FRAythyMV3WJKaUfDNsxXTIe7arZbwTWKA= -github.com/cli/go-gh/v2 v2.12.1/go.mod h1:+5aXmEOJsH9fc9mBHfincDwnS02j2AIA/DsTH0Bk5uw= +github.com/cli/go-gh/v2 v2.13.0 h1:jEHZu/VPVoIJkciK3pzZd3rbT8J90swsK5Ui4ewH1ys= +github.com/cli/go-gh/v2 v2.13.0/go.mod h1:Us/NbQ8VNM0fdaILgoXSz6PKkV5PWaEzkJdc9vR2geM= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= -github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= -github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/cli v28.0.4+incompatible h1:pBJSJeNd9QeIWPjRcV91RVJihd/TXB77q1ef64XEu4A= github.com/docker/cli v28.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v28.0.4+incompatible h1:JNNkBctYKurkw6FrHfKqY0nKIDf5nrbxjVBtS+cdcok= @@ -200,39 +184,35 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfU github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= -github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e h1:y/1nzrdF+RPds4lfoEpNhjfmzlgZtPqyO3jMzrqDQws= github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e/go.mod h1:awFzISqLJoZLm+i9QQ4SgMNHDqljH6jWV0B36V5MrUM= -github.com/getsops/sops/v3 v3.10.2 h1:7t7lBXFcXJPsDMrpYoI36r8xIhjWUmEc8Qdjuwyo+WY= -github.com/getsops/sops/v3 v3.10.2/go.mod h1:Dmtg1qKzFsAl+yqvMgjtnLGTC0l7RnSM6DDtFG7TEsk= -github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= -github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/getsops/sops/v3 v3.11.0 h1:HsJhfZDcLMBZSphnTXIcsS9oR5jJgzSivo0j9zf8KVY= +github.com/getsops/sops/v3 v3.11.0/go.mod h1:KiyVXNRMIEPCSAiapB8e8u+AaQGFgLlWo4Sk9PNTso0= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= -github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= -github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +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/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.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +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/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= @@ -245,8 +225,8 @@ 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/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw= @@ -260,8 +240,8 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= @@ -270,32 +250,30 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= -github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= +github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/vault/api v1.21.0 h1:Xej4LJETV/spWRdjreb2vzQhEZt4+B5yxHAObfQVDOs= +github.com/hashicorp/vault/api v1.21.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= github.com/knadh/koanf/providers/env v1.1.0 h1:U2VXPY0f+CsNDkvdsG8GcsnK4ah85WwWyJgef9oQMSc= github.com/knadh/koanf/providers/env v1.1.0/go.mod h1:QhHHHZ87h9JxJAn2czdEl6pdkNnDh/JS1Vtsyt65hTY= -github.com/knadh/koanf/providers/file v1.2.0 h1:hrUJ6Y9YOA49aNu/RSYzOTFlqzXSCpmYIDXI7OJU6+U= -github.com/knadh/koanf/providers/file v1.2.0/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA= +github.com/knadh/koanf/providers/file v1.2.1 h1:bEWbtQwYrA+W2DtdBrQWyXqJaJSG3KrP3AESOJYp9wM= +github.com/knadh/koanf/providers/file v1.2.1/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA= github.com/knadh/koanf/providers/posflag v1.0.1 h1:EnMxHSrPkYCFnKgBUl5KBgrjed8gVFrcXDzaW4l/C6Y= github.com/knadh/koanf/providers/posflag v1.0.1/go.mod h1:3Wn3+YG3f4ljzRyCUgIwH7G0sZ1pMjCOsNBovrbKmAk= -github.com/knadh/koanf/v2 v2.2.2 h1:ghbduIkpFui3L587wavneC9e3WIliCgiCgdxYO/wd7A= -github.com/knadh/koanf/v2 v2.2.2/go.mod h1:abWQc0cBXLSF/PSOMCB/SK+T13NXDsPvOksbpi5e/9Q= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/knadh/koanf/v2 v2.3.2 h1:Ee6tuzQYFwcZXQpc2MiVeC6qHMandf5SMUJJNoFp/c4= +github.com/knadh/koanf/v2 v2.3.2/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -308,18 +286,16 @@ github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFea github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libdns/libdns v1.0.0-beta.1 h1:KIf4wLfsrEpXpZ3vmc/poM8zCATXT2klbdPe6hyOBjQ= -github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= -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/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U= +github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +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/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -329,10 +305,10 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mhale/smtpd v0.8.3 h1:8j8YNXajksoSLZja3HdwvYVZPuJSqAxFsib3adzRRt8= github.com/mhale/smtpd v0.8.3/go.mod h1:MQl+y2hwIEQCXtNhe5+55n0GZOjSmeqORDIXbqUL3x4= -github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= -github.com/mholt/acmez/v3 v3.1.2/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/mholt/acmez/v3 v3.1.4 h1:DyzZe/RnAzT3rpZj/2Ii5xZpiEvvYk3cQEN/RmqxwFQ= +github.com/mholt/acmez/v3 v3.1.4/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= +github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc= +github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -343,6 +319,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mnako/letters v0.2.8 h1:w4H57g8360ShQ9G+ELUtz1apBBwkYazGYRgr70KF/2c= +github.com/mnako/letters v0.2.8/go.mod h1:BFhGZBaawfeHmghK8q5Q71A3G9SqVSVE7pDlSNdjErg= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= @@ -369,15 +347,11 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmd github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= -github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= -github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -390,14 +364,16 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/samber/slog-http v1.7.0 h1:sFrwkdw3Nrtcqq6WLkFL0K0Drlh76TPRvo0d8epF2a4= -github.com/samber/slog-http v1.7.0/go.mod h1:PAcQQrYFo5KM7Qbk50gNNwKEAMGCyfsw6GN5dI0iv9g= +github.com/samber/slog-http v1.11.1 h1:bAQveHQo7nbExU/JtyVDUrqUWEeMJgMxY0UOSn0f+/c= +github.com/samber/slog-http v1.11.1/go.mod h1:PAcQQrYFo5KM7Qbk50gNNwKEAMGCyfsw6GN5dI0iv9g= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -406,13 +382,13 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33 h1:idh63uw+gsG05HwjZsAENCG4KZfyvjK03bpjxa5qRRk= github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33/go.mod h1:EbW0wDK/qEUYI0A5bqq0C2kF8JTQwWONmGDBbzsxxHo= -github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= -github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= +github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ= +github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -421,143 +397,84 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= -go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -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.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= -golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +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-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= -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.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= -golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-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.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -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.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +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-20210809222454-d867a43fc93e/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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= -golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -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.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -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/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= -golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= -golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs= -google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4= -google.golang.org/genproto v0.0.0-20250324211829-b45e905df463 h1:qEFnJI6AnfZk0NNe8YTyXQh5i//Zxi4gBHwRgp76qpw= -google.golang.org/genproto v0.0.0-20250324211829-b45e905df463/go.mod h1:SqIx1NV9hcvqdLHo7uNZDS5lrUJybQ3evo3+z/WBfA0= -google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM= -google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= -google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +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/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +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/api v0.250.0 h1:qvkwrf/raASj82UegU2RSDGWi/89WkLckn4LuO4lVXM= +google.golang.org/api v0.250.0/go.mod h1:Y9Uup8bDLJJtMzJyQnu+rLRJLA0wn+wTtc6vTlOvfXo= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= +google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c h1:AtEkQdl5b6zsybXcbz00j1LwNodDuH6hVifIaNqk7NQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/app/app.go b/internal/app/app.go index 04461c4a..172292d8 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -21,13 +21,9 @@ var ( ) type AppConfig struct { - Entrypoint string `json:"entrypoint,omitempty"` - Root string `json:"root,omitempty"` - Crons []CronJob `json:"crons,omitempty"` - Admin bool `json:"admin"` - Private bool `json:"private"` - PrivateRoutes []string `json:"privateRoutes"` - PublicRoutes []string `json:"publicRoutes"` + Entrypoint string `json:"entrypoint,omitempty"` + Root string `json:"root,omitempty"` + Crons []CronJob `json:"crons,omitempty"` } type DenoConfig struct { @@ -35,9 +31,9 @@ type DenoConfig struct { } type CronJob struct { - Description string `json:"description"` - Schedule string `json:"schedule"` - Args []string `json:"args"` + Description string `json:"description"` + Schedule string `json:"schedule"` + Name string `json:"name"` } type App struct { @@ -52,12 +48,6 @@ type App struct { func (me *App) Dir() string { dir := me.BaseDir - if fi, err := os.Lstat(dir); err == nil && fi.Mode()&os.ModeSymlink != 0 { - if root, err := os.Readlink(dir); err == nil { - dir = filepath.Join(filepath.Dir(dir), root) - } - } - if me.Config.Root != "" { return filepath.Join(dir, me.Config.Root) } @@ -86,14 +76,7 @@ func (me *App) Dir() string { } func (me *App) DataDir() string { - dir := filepath.Join(me.Dir(), "data") - if fi, err := os.Lstat(dir); err == nil && fi.Mode()&os.ModeSymlink != 0 { - if root, err := os.Readlink(dir); err == nil { - dir = filepath.Join(filepath.Dir(dir), root) - } - } - - return dir + return filepath.Join(me.Dir(), "data") } func LookupApps(rootDir string) ([]string, error) { @@ -236,9 +219,6 @@ func (me App) Env() []string { env = append(env, fmt.Sprintf("SMALLWEB_VERSION=%s", build.Version)) env = append(env, fmt.Sprintf("SMALLWEB_DIR=%s", me.RootDir)) env = append(env, fmt.Sprintf("SMALLWEB_DOMAIN=%s", me.RootDomain)) - if me.Config.Admin { - env = append(env, "SMALLWEB_ADMIN=1") - } // open telemetry for _, value := range os.Environ() { diff --git a/internal/cmd/config.go b/internal/cmd/config.go deleted file mode 100644 index 38a437dc..00000000 --- a/internal/cmd/config.go +++ /dev/null @@ -1,98 +0,0 @@ -package cmd - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - - "github.com/mattn/go-isatty" - "github.com/spf13/cobra" - "github.com/tailscale/hujson" -) - -func findConfigPath(root string) string { - for _, filename := range []string{"config.json", "config.jsonc"} { - path := filepath.Join(root, ".smallweb", filename) - if _, err := os.Stat(path); err == nil { - return path - } - } - - return filepath.Join(root, ".smallweb", "config.json") -} - -func NewCmdConfig() *cobra.Command { - var flags struct { - json bool - } - - cmd := &cobra.Command{ - Use: "config", - Short: "Open Smallweb configuration", - RunE: func(cmd *cobra.Command, args []string) error { - configPath := findConfigPath(k.String("dir")) - if flags.json || !isatty.IsTerminal(os.Stdout.Fd()) { - configBytes, err := os.ReadFile(configPath) - if err != nil { - cmd.PrintErrf("failed to read config file: %v\n", err) - return ExitError{1} - } - - jsonBytes, err := hujson.Standardize(configBytes) - if err != nil { - cmd.PrintErrf("failed to standardize config file: %v\n", err) - return ExitError{1} - } - - var config map[string]any - if err := json.Unmarshal(jsonBytes, &config); err != nil { - cmd.PrintErrf("failed to unmarshal config file: %v\n", err) - return ExitError{1} - } - - encoder := json.NewEncoder(os.Stdout) - encoder.SetEscapeHTML(false) - - if isatty.IsTerminal(os.Stdout.Fd()) { - encoder.SetIndent("", " ") - } - - if err := encoder.Encode(config); err != nil { - cmd.PrintErrf("failed to encode config file: %v\n", err) - return ExitError{1} - } - - return nil - } - - editor := "vi" - if editorEnv, ok := os.LookupEnv("EDITOR"); ok { - editor = editorEnv - } - - editCmd := exec.Command("sh", "-c", fmt.Sprintf("%s %s", editor, configPath)) - - editCmd.Stdout = os.Stdout - editCmd.Stderr = os.Stderr - editCmd.Stdin = os.Stdin - - if err := editCmd.Run(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return ExitError{exitErr.ExitCode()} - } - - return ExitError{1} - } - - return nil - }, - } - - cmd.Flags().BoolVar(&flags.json, "json", false, "Output the configuration in JSON format") - - return cmd -} diff --git a/internal/cmd/crons.go b/internal/cmd/crons.go index a17627e0..e3181057 100644 --- a/internal/cmd/crons.go +++ b/internal/cmd/crons.go @@ -1,25 +1,26 @@ package cmd import ( - "context" "encoding/json" + "fmt" "log/slog" + "net/http" + "net/http/httptest" "os" "time" "github.com/cli/go-gh/v2/pkg/tableprinter" "github.com/mattn/go-isatty" "github.com/pomdtr/smallweb/internal/app" - "github.com/pomdtr/smallweb/internal/worker" "github.com/robfig/cron/v3" "github.com/spf13/cobra" "golang.org/x/term" ) type CronItem struct { - App string `json:"app"` - Args []string `json:"args"` - Schedule string `json:"schedule"` + App string `json:"app"` + Name string `json:"name"` + Schedule string `json:"schedule"` } func NewCmdCrons() *cobra.Command { @@ -55,7 +56,7 @@ func NewCmdCrons() *cobra.Command { for _, job := range a.Config.Crons { crons = append(crons, CronItem{ App: appname, - Args: job.Args, + Name: job.Name, Schedule: job.Schedule, }) } @@ -93,11 +94,11 @@ func NewCmdCrons() *cobra.Command { printer = tableprinter.New(cmd.OutOrStdout(), false, 0) } - printer.AddHeader([]string{"Schedule", "App", "Args"}) + printer.AddHeader([]string{"Schedule", "App", "Name"}) for _, item := range crons { printer.AddField(item.Schedule) printer.AddField(item.App) - args, err := json.Marshal(item.Args) + args, err := json.Marshal(item.Name) if err != nil { cmd.PrintErrf("failed to marshal args for app %s: %v\n", item.App, err) return ExitError{1} @@ -124,7 +125,7 @@ func NewCmdCrons() *cobra.Command { return cmd } -func CronRunner(logger *slog.Logger) *cron.Cron { +func CronRunner(logger *slog.Logger, handler http.Handler) *cron.Cron { parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor) c := cron.New(cron.WithParser(parser)) _, _ = c.AddFunc("* * * * *", func() { @@ -153,25 +154,10 @@ func CronRunner(logger *slog.Logger) *cron.Cron { continue } - a, err := app.LoadApp(appname, k.String("dir"), k.String("domain")) - if err != nil { - logger.Error("failed to load app", "app", appname, "error", err) - continue - } - wk := worker.NewWorker(a, nil) - - command, err := wk.Command(context.Background(), job.Args) - if err != nil { - logger.Error("failed to create command", "app", appname, "args", job.Args, "error", err) - continue - } + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, fmt.Sprintf("https://%s.%s/hooks/cron/%s", appname, k.String("domain"), job.Name), nil) - logger.Info("running cron job", "app", appname, "args", job.Args, "schedule", job.Schedule) - go func() { - if err := command.Run(); err != nil { - logger.Error("failed to run command", "app", appname, "args", job.Args, "error", err) - } - }() + go handler.ServeHTTP(w, r) } } }) diff --git a/internal/cmd/git.go b/internal/cmd/git.go deleted file mode 100644 index 08fded05..00000000 --- a/internal/cmd/git.go +++ /dev/null @@ -1,77 +0,0 @@ -package cmd - -import ( - "errors" - "os/exec" - - "github.com/pomdtr/smallweb/internal/app" - "github.com/spf13/cobra" -) - -func NewCmdGitReceivePack() *cobra.Command { - cmd := &cobra.Command{ - Use: "git-receive-pack", - Hidden: true, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - a, err := app.LoadApp(args[0], k.String("dir"), k.String("domain")) - if err != nil { - cmd.PrintErrf("failed to load app %s: %v\n", args[0], err) - return ExitError{1} - } - - gitCmd := exec.Command("git-receive-pack", a.BaseDir) - - gitCmd.Stdin = cmd.InOrStdin() - gitCmd.Stdout = cmd.OutOrStdout() - gitCmd.Stderr = cmd.ErrOrStderr() - - if err := gitCmd.Run(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return ExitError{exitErr.ExitCode()} - } - - return ExitError{1} - } - - return nil - }, - } - - return cmd -} - -func NewCmdGitUploadPack() *cobra.Command { - cmd := &cobra.Command{ - Use: "git-upload-pack", - Args: cobra.ExactArgs(1), - Hidden: true, - RunE: func(cmd *cobra.Command, args []string) error { - a, err := app.LoadApp(args[0], k.String("dir"), k.String("domain")) - if err != nil { - cmd.PrintErrf("failed to load app %s: %v\n", args[0], err) - return ExitError{1} - } - - gitCmd := exec.Command("git-upload-pack", a.BaseDir) - - gitCmd.Stdin = cmd.InOrStdin() - gitCmd.Stdout = cmd.OutOrStdout() - gitCmd.Stderr = cmd.ErrOrStderr() - - if err := gitCmd.Run(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return ExitError{exitErr.ExitCode()} - } - - return ExitError{1} - } - - return nil - }, - } - - return cmd -} diff --git a/internal/cmd/link.go b/internal/cmd/link.go deleted file mode 100644 index c593fc7c..00000000 --- a/internal/cmd/link.go +++ /dev/null @@ -1,73 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/spf13/cobra" -) - -func NewCmdLink() *cobra.Command { - var flags struct { - force bool - } - - cmd := &cobra.Command{ - Use: "link ", - Aliases: []string{"ln"}, - Args: cobra.ExactArgs(2), - Short: "Create symbolic links", - RunE: func(cmd *cobra.Command, args []string) error { - source, err := filepath.Abs(args[0]) - if err != nil { - return fmt.Errorf("failed to get absolute path for source: %w", err) - } - - if _, err := os.Stat(source); err != nil { - return fmt.Errorf("source does not exist: %w", err) - } - - if !strings.HasPrefix(source, k.String("dir")) { - return fmt.Errorf("source must be inside the smallweb directory") - } - - target, err := filepath.Abs(args[1]) - if err != nil { - return fmt.Errorf("failed to get absolute path for target: %w", err) - } - - // if target is inside the smallweb directory, create a relative symlink - if strings.HasPrefix(target, k.String("dir")) { - relative, err := filepath.Rel(filepath.Dir(target), source) - if err != nil { - return fmt.Errorf("failed to get relative path: %w", err) - } - - if flags.force { - if err := os.Remove(target); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to remove existing target: %w", err) - } - } - - if err := os.Symlink(relative, target); err != nil { - return fmt.Errorf("failed to create symbolic link: %w", err) - } - - return nil - } - - // if target is outside the smallweb directory, create an absolute symlink - if err := os.Symlink(source, target); err != nil { - return fmt.Errorf("failed to create symbolic link: %w", err) - } - - return nil - }, - } - - cmd.Flags().BoolVarP(&flags.force, "force", "f", false, "Force overwrite existing symlinks") - - return cmd -} diff --git a/internal/cmd/list.go b/internal/cmd/list.go index da9b6a56..a3873a64 100644 --- a/internal/cmd/list.go +++ b/internal/cmd/list.go @@ -15,8 +15,7 @@ import ( func NewCmdList() *cobra.Command { var flags struct { - json bool - admin bool + json bool } cmd := &cobra.Command{ @@ -41,9 +40,6 @@ func NewCmdList() *cobra.Command { if err != nil { continue } - if cmd.Flags().Changed("admin") && a.Config.Admin != flags.admin { - continue - } apps = append(apps, a) } @@ -80,18 +76,12 @@ func NewCmdList() *cobra.Command { printer = tableprinter.New(cmd.OutOrStdout(), false, 0) } - printer.AddHeader([]string{"Name", "Dir", "Domain", "Admin"}) + printer.AddHeader([]string{"Name", "Dir", "Domain"}) for _, a := range apps { printer.AddField(a.Name) printer.AddField(strings.Replace(a.BaseDir, os.Getenv("HOME"), "~", 1)) printer.AddField(a.Domain) - if a.Config.Admin { - printer.AddField("Yes") - } else { - printer.AddField("No") - } - printer.EndRow() } @@ -100,7 +90,6 @@ func NewCmdList() *cobra.Command { } cmd.Flags().BoolVar(&flags.json, "json", false, "output as json") - cmd.Flags().BoolVar(&flags.admin, "admin", false, "filter by admin") return cmd } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 28874bf1..0d8259e5 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -6,11 +6,8 @@ import ( "os" "os/exec" "path/filepath" - "strconv" "strings" - "github.com/abiosoft/ishell/v2" - "github.com/abiosoft/readline" "github.com/adrg/xdg" "github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/env" @@ -21,7 +18,6 @@ import ( "github.com/pomdtr/smallweb/internal/app" "github.com/pomdtr/smallweb/internal/build" "github.com/pomdtr/smallweb/internal/utils" - "github.com/pomdtr/smallweb/internal/worker" "github.com/spf13/cobra" ) @@ -101,115 +97,7 @@ func NewCmdRoot() *cobra.Command { Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - shell := ishell.NewWithConfig(&readline.Config{ - Prompt: "> ", - ForceUseInteractive: true, - FuncGetWidth: func() int { - return 80 // Default terminal width - }, - Stdin: fakeReadCloser{cmd.InOrStdin()}, - Stdout: cmd.OutOrStdout(), - Stderr: cmd.OutOrStdout(), - }) - - shell.AutoHelp(false) - - appnames, err := app.LookupApps(k.String("dir")) - if err != nil { - return fmt.Errorf("failed to lookup apps: %w", err) - } - - shell.DeleteCmd("exit") - shell.DeleteCmd("help") - shell.DeleteCmd("clear") - - shell.AddCmd(&ishell.Cmd{ - Name: "/help", - Help: "display help", - Func: func(c *ishell.Context) { - c.Println(c.HelpText()) - }, - }) - - shell.AddCmd(&ishell.Cmd{ - Name: "/clear", - Help: "clear the screen", - Func: func(c *ishell.Context) { - err := c.ClearScreen() - if err != nil { - c.Err(err) - } - }, - }) - - shell.AddCmd(&ishell.Cmd{ - Name: "/exit", - Help: "exit the program", - Func: func(c *ishell.Context) { - c.Stop() - }, - }) - - shell.AddCmd(&ishell.Cmd{ - Name: "/list", - Aliases: []string{"/ls"}, - Help: "list available apps", - Func: func(c *ishell.Context) { - if len(appnames) == 0 { - cmd.PrintErrln("No apps found.") - return - } - - for _, appname := range appnames { - cmd.Println(appname) - } - }, - }) - - shell.NotFound(func(c *ishell.Context) { - c.Err(fmt.Errorf("command not found: %s", c.Args[0])) - }) - - for _, appname := range appnames { - shell.AddCmd(&ishell.Cmd{ - Name: appname, - Help: fmt.Sprintf("run %s app", appname), - Func: func(c *ishell.Context) { - a, err := app.LoadApp(appname, k.String("dir"), k.String("domain")) - if err != nil { - c.Err(fmt.Errorf("failed to load app %s: %w", appname, err)) - return - } - - wk := worker.NewWorker(a, nil) - - command, err := wk.Command(cmd.Context(), c.Args) - if err != nil { - c.Err(fmt.Errorf("failed to create command for app %s: %w", appname, err)) - return - } - - c.Print() - - command.Stdout = cmd.OutOrStdout() - command.Stderr = cmd.OutOrStdout() - - command.Run() - }, - }) - - } - - shell.Printf("Smallweb %s\n", build.Version) - shell.Printf("use /help for a list of commands.\n") - shell.Run() - return nil - } - - if env, ok := os.LookupEnv("SMALLWEB_DISABLE_CUSTOM_COMMANDS"); ok { - if disableCustomCommands, _ := strconv.ParseBool(env); disableCustomCommands { - return fmt.Errorf("unknown command \"%s\" for \"smallweb\"", args[0]) - } + return cmd.Help() } for _, pluginDir := range []string{ @@ -264,35 +152,12 @@ func NewCmdRoot() *cobra.Command { rootCmd.PersistentFlags().String("domain", "", "The domain for smallweb") rootCmd.Flags().SetInterspersed(false) - rootCmd.AddCommand(NewCmdRun()) rootCmd.AddCommand(NewCmdDocs()) rootCmd.AddCommand(NewCmdUp()) rootCmd.AddCommand(NewCmdDoctor()) rootCmd.AddCommand(NewCmdList()) rootCmd.AddCommand(NewCmdCrons()) rootCmd.AddCommand(NewCmdInit()) - rootCmd.AddCommand(NewCmdConfig()) - rootCmd.AddCommand(NewCmdLink()) - rootCmd.AddCommand(NewCmdGitReceivePack()) - rootCmd.AddCommand(NewCmdGitUploadPack()) - - if _, ok := os.LookupEnv("SMALLWEB_DISABLE_COMPLETIONS"); ok { - rootCmd.CompletionOptions.DisableDefaultCmd = true - } - - if env, ok := os.LookupEnv("SMALLWEB_DISABLED_COMMANDS"); ok { - disabledCommands := strings.Split(env, ",") - for _, commandName := range disabledCommands { - if commandName == "completion" { - rootCmd.CompletionOptions.DisableDefaultCmd = true - continue // Skip disabling the completion command - } - - if command, ok := GetCommand(rootCmd, commandName); ok { - rootCmd.RemoveCommand(command) - } - } - } return rootCmd } diff --git a/internal/cmd/run.go b/internal/cmd/run.go deleted file mode 100644 index 4cbd7ea4..00000000 --- a/internal/cmd/run.go +++ /dev/null @@ -1,59 +0,0 @@ -package cmd - -import ( - "errors" - "fmt" - "os/exec" - - "github.com/pomdtr/smallweb/internal/app" - "github.com/pomdtr/smallweb/internal/worker" - "github.com/spf13/cobra" -) - -func NewCmdRun() *cobra.Command { - cmd := &cobra.Command{ - Use: "run [args...]", - Short: "Run an app cli", - ValidArgsFunction: completeApp, - Args: cobra.MinimumNArgs(1), - PreRunE: func(cmd *cobra.Command, args []string) error { - if _, err := checkDenoVersion(); err != nil { - return err - } - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - a, err := app.LoadApp(args[0], k.String("dir"), k.String("domain")) - if err != nil { - return fmt.Errorf("failed to load app: %w", err) - } - - wk := worker.NewWorker(a, nil) - command, err := wk.Command(cmd.Context(), args[1:]) - if err != nil { - return fmt.Errorf("failed to create command: %w", err) - } - - cmd.SilenceErrors = true - - command.Stdin = cmd.InOrStdin() - command.Stdout = cmd.OutOrStdout() - command.Stderr = cmd.ErrOrStderr() - if err := command.Run(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return ExitError{exitErr.ExitCode()} - } - - return ExitError{1} - } - - return nil - - }, - } - - cmd.Flags().SetInterspersed(false) - return cmd -} diff --git a/internal/cmd/up.go b/internal/cmd/up.go index 6f2bb930..f41c1567 100644 --- a/internal/cmd/up.go +++ b/internal/cmd/up.go @@ -1,10 +1,9 @@ package cmd import ( + "bytes" "context" - "crypto/rand" "crypto/tls" - "encoding/base64" "encoding/json" "errors" "fmt" @@ -12,25 +11,24 @@ import ( "log/slog" "net" "net/http" + "net/http/httptest" "net/url" "os" - "os/exec" "os/signal" + "path" "path/filepath" - "slices" "strings" "sync" + "github.com/mnako/letters" + _ "embed" - "github.com/bmatcuk/doublestar/v4" "github.com/caddyserver/certmagic" "github.com/charmbracelet/ssh" "gopkg.in/natefinch/lumberjack.v2" "github.com/charmbracelet/wish" - "github.com/coreos/go-oidc/v3/oidc" - "github.com/creack/pty" "github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/file" "github.com/lmittmann/tint" @@ -43,10 +41,7 @@ import ( "github.com/knadh/koanf/v2" "github.com/pomdtr/smallweb/internal/app" - "github.com/pomdtr/smallweb/internal/sftp" "github.com/pomdtr/smallweb/internal/watcher" - gossh "golang.org/x/crypto/ssh" - "golang.org/x/oauth2" "github.com/pomdtr/smallweb/internal/utils" "github.com/pomdtr/smallweb/internal/worker" @@ -129,16 +124,6 @@ func NewCmdUp() *cobra.Command { logger: logger, } - if issuer := k.String("oidc.issuer"); issuer != "" { - issuerUrl, err := url.Parse(issuer) - if err != nil { - sysLogger.Error("failed to parse issuer url", "url", k.String("oidc.issuer")) - return ExitError{1} - } - - handler.oidcIssuerUrl = issuerUrl - } - watcher, err := watcher.NewWatcher(k.String("dir"), func() { fileProvider := file.Provider(utils.FindConfigPath(k.String("dir"))) flagProvider := posflag.Provider(cmd.Root().PersistentFlags(), ".", k) @@ -156,20 +141,6 @@ func NewCmdUp() *cobra.Command { _ = conf.Load(envProvider, nil) _ = conf.Load(flagProvider, nil) - if issuer := conf.String("oidc.issuer"); issuer != "" { - issuerUrl, err := url.Parse(issuer) - if err != nil { - logger.Error("failed to parse issuer url") - return - } - - handler.oidcIssuerUrl = issuerUrl - handler.oidcProvider = nil - } else { - handler.oidcIssuerUrl = nil - handler.oidcProvider = nil - } - k = conf }) if err != nil { @@ -239,7 +210,7 @@ func NewCmdUp() *cobra.Command { if flags.enableCrons { logger.Info("starting cron jobs") - crons := CronRunner(logger.With("logger", "cron")) + crons := CronRunner(logger.With("logger", "cron"), handler) crons.Start() defer crons.Stop() } @@ -253,23 +224,23 @@ func NewCmdUp() *cobra.Command { continue } - appname, domain := parts[0], parts[1] - if domain != k.String("domain") { - logger.Error("invalid domain", "domain", domain) + email, err := letters.ParseEmail(bytes.NewReader(data)) + if err != nil { + logger.Error("failed to parse email", "error", err) continue } - a, err := app.LoadApp(appname, k.String("dir"), k.String("domain")) + body, err := json.Marshal(email) if err != nil { - logger.Error("failed to load app", "error", err) + logger.Error("failed to marshal email", "error", err) continue } - worker := worker.NewWorker(a, nil) - if err := worker.SendEmail(context.Background(), data); err != nil { - logger.Error("failed to send email", "error", err) - continue - } + w := httptest.NewRecorder() + u := fmt.Sprintf("http://%s.%s/hooks/email", parts[0], k.String("domain")) + r := httptest.NewRequest(http.MethodPost, u, bytes.NewReader(body)) + + handler.ServeHTTP(w, r) } return nil @@ -292,9 +263,14 @@ func NewCmdUp() *cobra.Command { return ExitError{1} } - for _, keyType := range []string{"id_rsa", "id_ed25519"} { - if _, err := os.Stat(filepath.Join(homeDir, ".ssh", keyType)); err == nil { - sshPrivateKeyPath = filepath.Join(homeDir, ".ssh", keyType) + for _, keyPath := range []string{ + filepath.Join(homeDir, ".ssh", "smallweb", "id_ed25519"), + filepath.Join(homeDir, ".ssh", "smallweb", "id_rsa"), + filepath.Join(homeDir, ".ssh", "id_ed25519"), + filepath.Join(homeDir, ".ssh", "id_rsa"), + } { + if _, err := os.Stat(keyPath); err == nil { + sshPrivateKeyPath = keyPath break } } @@ -305,168 +281,85 @@ func NewCmdUp() *cobra.Command { return ExitError{1} } - privateKeyBytes, err := os.ReadFile(sshPrivateKeyPath) - if err != nil { - sysLogger.Error("failed to read private key", "error", err) - return ExitError{1} - } - - privateKey, err := gossh.ParseRawPrivateKey(privateKeyBytes) - if err != nil { - sysLogger.Error("failed to parse private key", "error", err) - return ExitError{1} - } - - signer, err := gossh.NewSignerFromKey(privateKey) - if err != nil { - sysLogger.Error("failed to create signer", "error", err) - return ExitError{1} - } - - authorizedKey := string(gossh.MarshalAuthorizedKey(signer.PublicKey())) - sshLogger := logger.With("logger", "ssh") srv, err := wish.NewServer( wish.WithAddress(flags.sshAddr), wish.WithHostKeyPath(sshPrivateKeyPath), wish.WithPublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool { - authorizedKeys := []string{authorizedKey} - authorizedKeys = append(authorizedKeys, k.Strings("authorizedKeys")...) - - if ctx.User() != "_" { - authorizedKeys = append(authorizedKeys, k.Strings(fmt.Sprintf("apps.%s.authorizedKeys", ctx.User()))...) - } - - for _, authorizedKey := range authorizedKeys { - if authorizedKey == "*" { - return true - } - - k, _, _, _, err := gossh.ParseAuthorizedKey([]byte(authorizedKey)) - if err != nil { - continue - } - - if ssh.KeysEqual(k, key) { - return true - } - } - - return false + return true }), - sftp.SSHOption(k.String("dir"), nil), wish.WithMiddleware( func(next ssh.Handler) ssh.Handler { return func(sess ssh.Session) { - var cmd *exec.Cmd - if sess.User() != "_" { - a, err := app.LoadApp(sess.User(), k.String("dir"), k.String("domain")) - if err != nil { - fmt.Fprintf(sess, "failed to load app: %v\n", err) - sess.Exit(1) - return - } - - wk := worker.NewWorker(a, nil) - c, err := wk.Command(sess.Context(), sess.Command()) - if err != nil { - fmt.Fprintf(sess, "failed to get command: %v\n", err) - sess.Exit(1) - return - } - - cmd = c - } else { - execPath, err := os.Executable() - if err != nil { - fmt.Fprintf(sess.Stderr(), "failed to get executable path: %v\n", err) - sess.Exit(1) - return - } - - cmd = exec.Command(execPath, "--dir", k.String("dir"), "--domain", k.String("domain")) - cmd.Args = append(cmd.Args, sess.Command()...) - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "SMALLWEB_DISABLE_CUSTOM_COMMANDS=true") - cmd.Env = append(cmd.Env, "SMALLWEB_DISABLED_COMMANDS=up,config,init,doctor,completion") + if sess.User() != "cli" { + next(sess) + return + } + args := sess.Command() + if len(args) == 0 { + fmt.Fprintln(sess.Stderr(), "No app provided") + sess.Exit(1) + return } - ptyReq, winCh, isPty := sess.Pty() - if isPty { - cmd.Env = append(cmd.Env, "TERM="+ptyReq.Term) - f, err := pty.Start(cmd) - if err != nil { - fmt.Fprintf(sess, "failed to start command: %v\n", err) - sess.Exit(1) - } - - go func() { - for win := range winCh { - pty.Setsize(f, &pty.Winsize{ - Rows: uint16(win.Height), - Cols: uint16(win.Width), - }) + var parts []string + + q := url.Values{} + for i := 1; i < len(args); i++ { + arg := args[i] + + if strings.HasPrefix(arg, "--") { + // Long flag: --key=value or --key + key := strings.TrimPrefix(arg, "--") + if idx := strings.Index(key, "="); idx != -1 { + q.Set(key[:idx], key[idx+1:]) + } else if i+1 < len(args) && !strings.HasPrefix(args[i+1], "-") { + q.Set(key, args[i+1]) + i++ + } else { + q.Set(key, "true") } - }() - - go func() { - io.Copy(sess, f) - }() - - go func() { - io.Copy(f, sess) - }() - - if err := cmd.Wait(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - sess.Exit(exitErr.ExitCode()) - return + } else if strings.HasPrefix(arg, "-") && len(arg) > 1 && arg != "-" { + // Short flags: -abc or -a value + flags := strings.TrimPrefix(arg, "-") + if idx := strings.Index(flags, "="); idx != -1 { + q.Set(flags[:idx], flags[idx+1:]) + } else if len(flags) == 1 && i+1 < len(args) && !strings.HasPrefix(args[i+1], "-") { + q.Set(flags, args[i+1]) + i++ + } else { + for _, f := range flags { + q.Set(string(f), "true") + } } - - fmt.Fprintf(sess, "failed to run command: %v", err) - sess.Exit(1) - return + } else { + // Positional argument + parts = append(parts, url.PathEscape(arg)) } + } - return + w := httptest.NewRecorder() + u := fmt.Sprintf("https://%s.%s/hooks/cli", args[0], k.String("domain")) + if len(parts) > 0 { + u += path.Join(parts...) } - cmd.Stdout = sess - cmd.Stderr = sess.Stderr() - stdin, err := cmd.StdinPipe() - if err != nil { - fmt.Fprintf(sess, "failed to get stdin: %v\n", err) - sess.Exit(1) - return + if query := q.Encode(); query != "" { + u += "?" + query } - go func() { - defer stdin.Close() - io.Copy(stdin, sess) - }() + r := httptest.NewRequest(http.MethodPost, u, io.NopCloser(sess)) - if err := cmd.Run(); err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - sess.Exit(exitErr.ExitCode()) - return - } + handler.ServeHTTP(w, r) - fmt.Fprintf(sess, "failed to run command: %v", err) + resp := w.Result() + io.Copy(sess, resp.Body) + + if resp.StatusCode >= 400 { sess.Exit(1) return } - } - }, - func(next ssh.Handler) ssh.Handler { - return func(sess ssh.Session) { - sshLogger.Info( - "ssh connection", - "user", sess.User(), - "remote addr", sess.RemoteAddr().String(), - "command", sess.Command(), - ) - next(sess) + + sess.Exit(0) } }, ), @@ -537,25 +430,10 @@ func getListener(addr string, config *tls.Config) (net.Listener, error) { } type Handler struct { - watcher *watcher.Watcher - logger *slog.Logger - workerMu sync.Mutex - workers map[string]*worker.Worker - oidcMu sync.Mutex - oidcIssuerUrl *url.URL - oidcProvider *oidc.Provider -} - -type AuthData struct { - State string `json:"state"` - SuccessURL string `json:"success_url"` - CodeVerifier string `json:"code_verifier"` -} - -type IssuerConfig struct { - AuthorizationEndpoint string `json:"authorization_endpoint"` - TokenEndpoint string `json:"token_endpoint"` - JwksUri string `json:"jwks_uri"` + watcher *watcher.Watcher + logger *slog.Logger + workerMu sync.Mutex + workers map[string]*worker.Worker } func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -580,196 +458,6 @@ func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - if me.oidcIssuerUrl != nil && me.oidcIssuerUrl.Host == r.Host { - wk, err := me.GetWorker(appname, k.String("dir"), k.String("domain")) - if err != nil { - if errors.Is(err, app.ErrAppNotFound) { - w.WriteHeader(http.StatusNotFound) - w.Write([]byte(fmt.Sprintf("No app found for host %s", r.Host))) - return - } - - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "failed to get worker: %v", err) - return - } - - wk.ServeHTTP(w, r) - return - } - - if r.URL.Path == "/_smallweb/signin" { - if me.oidcIssuerUrl == nil { - http.Error(w, "oidc issuer url not set", http.StatusInternalServerError) - return - } - - oauth2Config, err := me.Oauth2Config(r) - if err != nil { - http.Error(w, fmt.Sprintf("failed to get oauth2 config: %v", err), http.StatusInternalServerError) - return - } - - var successURL string - if param := r.URL.Query().Get("success_url"); param != "" { - successURL = fmt.Sprintf("%s://%s%s", ExtractScheme(r), r.Host, param) - } else if r.Header.Get("Referer") != "" { - successURL = r.Header.Get("Referer") - } else { - successURL = fmt.Sprintf("%s://%s/", ExtractScheme(r), r.Host) - } - - state := rand.Text() - verifier := oauth2.GenerateVerifier() - authData := AuthData{ - State: state, - SuccessURL: successURL, - CodeVerifier: verifier, - } - - // Marshal the struct to JSON - jsonData, err := json.Marshal(authData) - if err != nil { - http.Error(w, "Server error", http.StatusInternalServerError) - return - } - - encodedData := base64.StdEncoding.EncodeToString(jsonData) - http.SetCookie(w, &http.Cookie{ - Name: "oauth_data", - Value: encodedData, - HttpOnly: true, - Secure: ExtractScheme(r) == "https", - MaxAge: 5 * 60, - SameSite: http.SameSiteLaxMode, - }) - - http.Redirect(w, r, oauth2Config.AuthCodeURL(state, oauth2.S256ChallengeOption(verifier)), http.StatusTemporaryRedirect) - return - } - - if r.URL.Path == "/_smallweb/signout" { - if me.oidcIssuerUrl == nil { - http.Error(w, "oidc issuer url not set", http.StatusInternalServerError) - return - } - - http.SetCookie(w, &http.Cookie{ - Name: "id_token", - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: -1, - }) - - http.SetCookie(w, &http.Cookie{ - Name: "refresh_token", - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: -1, - }) - - var successUrl string - if param := r.URL.Query().Get("success_url"); param != "" { - successUrl = fmt.Sprintf("%s://%s%s", ExtractScheme(r), r.Host, param) - } else if r.Header.Get("Referer") != "" { - successUrl = r.Header.Get("Referer") - } else { - successUrl = fmt.Sprintf("%s://%s/", ExtractScheme(r), r.Host) - } - - http.Redirect(w, r, successUrl, http.StatusTemporaryRedirect) - return - } - - if r.URL.Path == "/_smallweb/oauth/callback" { - if me.oidcIssuerUrl == nil { - http.Error(w, "oidc issuer url not set", http.StatusInternalServerError) - return - } - - oauth2Config, err := me.Oauth2Config(r) - if err != nil { - http.Error(w, fmt.Sprintf("failed to get oauth2 config: %v", err), http.StatusInternalServerError) - return - } - - authCookie, err := r.Cookie("oauth_data") - if err != nil { - http.Error(w, "state cookie not found", http.StatusUnauthorized) - return - } - - http.SetCookie(w, &http.Cookie{ - Name: "oauth_data", - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: -1, - }) - - decodedData, err := base64.StdEncoding.DecodeString(authCookie.Value) - if err != nil { - http.Error(w, "failed to decode state cookie", http.StatusUnauthorized) - return - } - - var authData AuthData - if err := json.Unmarshal(decodedData, &authData); err != nil { - http.Error(w, "failed to unmarshal state cookie", http.StatusUnauthorized) - return - } - - if authData.State != r.URL.Query().Get("state") { - http.Error(w, "invalid state", http.StatusUnauthorized) - return - } - - code := r.URL.Query().Get("code") - if code == "" { - http.Error(w, "oauth code not found", http.StatusUnauthorized) - return - } - - oauth2Token, err := oauth2Config.Exchange(r.Context(), code, oauth2.VerifierOption(authData.CodeVerifier)) - if err != nil { - http.Error(w, fmt.Sprintf("failed to exchange code: %v", err), http.StatusInternalServerError) - return - } - - idToken, ok := oauth2Token.Extra("id_token").(string) - if !ok { - http.Error(w, "id token not found", http.StatusInternalServerError) - return - } - - http.SetCookie(w, &http.Cookie{ - Name: "id_token", - Value: idToken, - SameSite: http.SameSiteLaxMode, - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: 34560000, - }) - - if oauth2Token.RefreshToken != "" { - http.SetCookie(w, &http.Cookie{ - Name: "refresh_token", - Value: oauth2Token.RefreshToken, - SameSite: http.SameSiteLaxMode, - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: 34560000, - }) - } - - http.Redirect(w, r, authData.SuccessURL, http.StatusTemporaryRedirect) - return - } - wk, err := me.GetWorker(appname, k.String("dir"), k.String("domain")) if err != nil { if errors.Is(err, app.ErrAppNotFound) { @@ -783,263 +471,37 @@ func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - claims, err := me.extractClaims(r) - if err != nil && isRoutePrivate(wk.App, r.URL.Path) { - if me.oidcIssuerUrl == nil { - http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) - return - } - - if !errors.Is(err, &oidc.TokenExpiredError{}) { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - var expiredErr *oidc.TokenExpiredError - if errors.As(err, &expiredErr) { - refreshTokenCookie, err := r.Cookie("refresh_token") - if err != nil { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - oauth2Config, err := me.Oauth2Config(r) - if err != nil { - http.Error(w, fmt.Sprintf("failed to get oauth2 config: %v", err), http.StatusInternalServerError) - return - } - - tokenSource := oauth2Config.TokenSource(context.Background(), &oauth2.Token{RefreshToken: refreshTokenCookie.Value}) - oauth2Token, err := tokenSource.Token() - if err != nil { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - rawIdToken, ok := oauth2Token.Extra("id_token").(string) - if !ok { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - provider, ok := me.Provider() - if !ok { - http.Error(w, "oidc provider not found", http.StatusInternalServerError) - return - } - - verifier := provider.Verifier(&oidc.Config{ClientID: r.Host}) - idToken, err := verifier.Verify(r.Context(), rawIdToken) - if err != nil { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - if err := idToken.Claims(&claims); err != nil { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - http.SetCookie(w, &http.Cookie{ - Name: "id_token", - Value: rawIdToken, - SameSite: http.SameSiteLaxMode, - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: 34560000, - }) - - if oauth2Token.RefreshToken != "" { - http.SetCookie(w, &http.Cookie{ - Name: "refresh_token", - Value: oauth2Token.RefreshToken, - SameSite: http.SameSiteLaxMode, - Secure: ExtractScheme(r) == "https", - HttpOnly: true, - Path: "/", - MaxAge: 34560000, - }) - } - } - } - - if isRoutePrivate(wk.App, r.URL.Path) && !isAuthorized(appname, claims.Email, claims.Group) { - if claims.Email == "" { - http.Redirect(w, r, fmt.Sprintf("%s://%s/_smallweb/signin?success_url=%s", ExtractScheme(r), r.Host, r.URL.Path), http.StatusTemporaryRedirect) - return - } - - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - - r.Header.Set("Remote-User", claims.User) - r.Header.Set("Remote-Email", claims.Email) - r.Header.Set("Remote-Group", claims.Group) - r.Header.Set("Remote-Name", claims.Name) - wk.ServeHTTP(w, r) } -func isRoutePrivate(a app.App, route string) bool { - isPrivate := a.Config.Private - - for _, publicRoute := range a.Config.PublicRoutes { - if ok, _ := doublestar.Match(publicRoute, route); ok { - isPrivate = false - } - } - - for _, privateRoute := range a.Config.PrivateRoutes { - if ok, _ := doublestar.Match(privateRoute, route); ok { - isPrivate = true - } - } - - return isPrivate -} - -func isAuthorized(appname string, email string, group string) bool { - var authorizedEmails []string - authorizedEmails = append(authorizedEmails, k.Strings("authorizedEmails")...) - authorizedEmails = append(authorizedEmails, k.Strings(fmt.Sprintf("apps.%s.authorizedEmails", appname))...) - - for _, authorizedEmail := range authorizedEmails { - if match, _ := doublestar.Match(authorizedEmail, email); match { - return true - } - } - - var authorizedGroups []string - authorizedGroups = append(authorizedGroups, k.Strings("authorizedGroups")...) - authorizedGroups = append(authorizedGroups, k.Strings(fmt.Sprintf("apps.%s.authorizedGroups", appname))...) - - for _, authorizedGroup := range authorizedGroups { - if match, _ := doublestar.Match(authorizedGroup, group); match { - return true - } - } - - return false -} - -type Claims struct { - Email string - Group string - User string - Name string -} - -func (me *Handler) extractClaims(r *http.Request) (Claims, error) { - provider, ok := me.Provider() - if !ok { - return Claims{ - Email: r.Header.Get("Remote-Email"), - Group: r.Header.Get("Remote-Group"), - User: r.Header.Get("Remote-User"), - Name: r.Header.Get("Remote-Name"), - }, nil - } - - var rawIdToken string - if auth := r.Header.Get("Authorization"); auth != "" { - parts := strings.Split(strings.TrimSpace(auth), " ") - if len(parts) != 2 { - return Claims{}, fmt.Errorf("invalid authorization header") - } - - if parts[0] != "Bearer" { - return Claims{}, fmt.Errorf("invalid authorization header") - } - - rawIdToken = parts[1] - - } else { - idTokenCookie, err := r.Cookie("id_token") - if err != nil { - return Claims{}, fmt.Errorf("id token not found") +func lookupApp(d string) (app string, redirect bool, found bool) { + domains := k.StringMap("additionalDomains") + if v, ok := domains[d]; ok { + if v == "*" { + return "www", true, true } - rawIdToken = idTokenCookie.Value + return v, false, true } - verifier := provider.Verifier(&oidc.Config{ClientID: fmt.Sprintf("%s://%s", ExtractScheme(r), r.Host)}) - idToken, err := verifier.Verify(r.Context(), rawIdToken) - if err != nil { - return Claims{}, fmt.Errorf("failed to verify id token: %v", err) - } - - var userinfo Claims - if err := idToken.Claims(&userinfo); err != nil { - return Claims{}, fmt.Errorf("failed to extract claims: %v", err) - } - - return userinfo, nil -} - -func lookupApp(domain string) (app string, redirect bool, found bool) { - for _, app := range k.MapKeys("apps") { - if slices.Contains(k.Strings(fmt.Sprintf("apps.%s.additionalDomains", app)), domain) { - return app, false, true - } - } - - if domain == k.String("domain") { + if d == k.String("domain") { return "www", true, true } - if strings.HasSuffix(domain, fmt.Sprintf(".%s", k.String("domain"))) { - return strings.TrimSuffix(domain, fmt.Sprintf(".%s", k.String("domain"))), false, true - } - - for _, additionalDomain := range k.Strings("additionalDomains") { - if domain == additionalDomain { - return "www", true, true - } - - if strings.HasSuffix(domain, fmt.Sprintf(".%s", additionalDomain)) { - return strings.TrimSuffix(domain, fmt.Sprintf(".%s", additionalDomain)), false, true - } - } - - return "", false, false -} - -func (me *Handler) Provider() (*oidc.Provider, bool) { - me.oidcMu.Lock() - defer me.oidcMu.Unlock() - - if me.oidcIssuerUrl == nil { - return nil, false + parts := strings.SplitN(d, ".", 2) + if len(parts) != 2 { + return "", false, false } - if me.oidcProvider == nil { - provider, err := oidc.NewProvider(context.Background(), me.oidcIssuerUrl.String()) - if err != nil { - me.logger.Error("failed to create oidc provider", "error", err) - return nil, false - } - - me.oidcProvider = provider + if v, ok := domains[parts[1]]; ok && v == "*" { + return parts[0], false, true } - return me.oidcProvider, true -} - -func (me *Handler) Oauth2Config(r *http.Request) (*oauth2.Config, error) { - clientID := fmt.Sprintf("%s://%s", ExtractScheme(r), r.Host) - provider, ok := me.Provider() - if !ok { - return nil, fmt.Errorf("oidc provider not set") + if parts[1] == k.String("domain") { + return parts[0], false, true } - return &oauth2.Config{ - ClientID: clientID, - Scopes: []string{"openid", "email", "profile", "groups"}, - RedirectURL: fmt.Sprintf("%s://%s/_smallweb/oauth/callback", ExtractScheme(r), r.Host), - Endpoint: provider.Endpoint(), - }, nil + return "", false, false } func ExtractScheme(r *http.Request) string { diff --git a/internal/sftp/handler.go b/internal/sftp/handler.go deleted file mode 100644 index 7d581a65..00000000 --- a/internal/sftp/handler.go +++ /dev/null @@ -1,257 +0,0 @@ -package sftp - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "time" - - "github.com/charmbracelet/ssh" - "github.com/charmbracelet/wish" - "github.com/pkg/sftp" -) - -// Based on https://github.com/pkg/sftp/blob/master/request-example.go - -type handler struct { - session ssh.Session - root *os.Root -} - -func (h *handler) Filecmd(r *sftp.Request) error { - switch r.Method { - case "Rename": - if _, err := h.root.Stat(strings.TrimPrefix(r.Filepath, "/")); err != nil { - return err - } - - src := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Filepath, "/")) - dst := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Target, "/")) - return os.Rename(src, dst) - case "Link": - if _, err := h.root.Stat(strings.TrimPrefix(r.Filepath, "/")); err != nil { - return err - } - - if _, err := h.root.Stat(strings.TrimPrefix(r.Target, "/")); err == nil { - return fmt.Errorf("target file exists") - } else if !errors.Is(err, os.ErrNotExist) { - return err - } - - src := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Filepath, "/")) - dst := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Target, "/")) - return os.Link(src, dst) - case "Symlink": - if _, err := h.root.Stat(strings.TrimPrefix(r.Filepath, "/")); err != nil { - return fmt.Errorf("file does not exist") - } - - if _, err := h.root.Stat(strings.TrimPrefix(r.Target, "/")); err == nil { - return fmt.Errorf("target file exists") - } else if !errors.Is(err, os.ErrNotExist) { - return err - } - - src := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Filepath, "/")) - dst := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Target, "/")) - return os.Symlink(src, dst) - case "Rmdir": - return h.root.Remove(strings.TrimPrefix(r.Filepath, "/")) - case "Remove": - return h.root.Remove(strings.TrimPrefix(r.Filepath, "/")) - case "Mkdir": - return h.root.Mkdir(strings.TrimPrefix(r.Filepath, "/"), 0777) - case "Setstat": - if _, err := h.root.Stat(strings.TrimPrefix(r.Filepath, "/")); err != nil { - return fmt.Errorf("file does not exist") - } - - fp := filepath.Join(h.root.Name(), strings.TrimPrefix(r.Filepath, "/")) - attrs := r.Attributes() - - if attrs.Size != 0 { - if err := os.Truncate(fp, int64(attrs.Size)); err != nil { - return err - } - } - - if attrs.Mode != 0 { - if err := os.Chmod(fp, os.FileMode(attrs.Mode)); err != nil { - return err - } - } - - if attrs.GID != 0 || attrs.UID != 0 { - if err := os.Chown(fp, int(attrs.UID), int(attrs.GID)); err != nil { - return err - } - } - - if attrs.Atime != 0 && attrs.Mtime != 0 { - atime := time.Unix(int64(attrs.Atime), 0) - mtime := time.Unix(int64(attrs.Mtime), 0) - if err := os.Chtimes(fp, atime, mtime); err != nil { - return err - } - } - - return nil - } - return errors.New("unsupported") -} - -func (h *handler) Filelist(r *sftp.Request) (sftp.ListerAt, error) { - switch r.Method { - case "List": - if r.Filepath == "/" { - entries, err := os.ReadDir(h.root.Name()) - if err != nil { - return nil, err - } - - var fileInfos []os.FileInfo - for _, entry := range entries { - fileInfo, err := entry.Info() - if err != nil { - return nil, err - } - fileInfos = append(fileInfos, fileInfo) - } - - return listerat(fileInfos), nil - } - - f, err := h.root.Open(strings.TrimPrefix(r.Filepath, "/")) - if err != nil { - return nil, err - } - - entries, err := f.ReadDir(0) - if err != nil { - return nil, err - } - - var fileInfos []os.FileInfo - for _, entry := range entries { - fileInfo, err := entry.Info() - if err != nil { - return nil, err - } - fileInfos = append(fileInfos, fileInfo) - } - - return listerat(fileInfos), nil - - case "Stat": - if r.Filepath == "/" { - stat, err := os.Stat(h.root.Name()) - if err != nil { - return nil, err - } - - return listerat([]os.FileInfo{stat}), nil - } - - info, err := h.root.Stat(strings.TrimPrefix(r.Filepath, "/")) - if err != nil { - return nil, err - } - - return listerat([]os.FileInfo{info}), nil - } - - return nil, errors.New("unsupported") -} - -func (h *handler) Filewrite(r *sftp.Request) (io.WriterAt, error) { - f, err := h.root.OpenFile(strings.TrimPrefix(r.Filepath, "/"), flag(r.Pflags()), 0644) - if err != nil { - return nil, err - } - - return f, nil -} - -func flag(pflags sftp.FileOpenFlags) int { - var flag int - if pflags.Creat { - flag |= os.O_CREATE - } - if pflags.Trunc { - flag |= os.O_TRUNC - } - if pflags.Excl { - flag |= os.O_EXCL - } - if pflags.Write { - flag |= os.O_WRONLY - } - if pflags.Read { - flag |= os.O_RDONLY - } - if pflags.Append { - flag |= os.O_APPEND - } - - return flag -} - -func (h *handler) Fileread(r *sftp.Request) (io.ReaderAt, error) { - if r.Filepath == "/" { - return nil, os.ErrInvalid - } - - return h.root.Open(strings.TrimPrefix(r.Filepath, "/")) -} - -type handlererr struct { - Handler *handler -} - -func (f *handlererr) Filecmd(r *sftp.Request) error { - err := f.Handler.Filecmd(r) - if err != nil { - wish.Errorln(f.Handler.session, err) - } - return err -} -func (f *handlererr) Filelist(r *sftp.Request) (sftp.ListerAt, error) { - result, err := f.Handler.Filelist(r) - if err != nil { - wish.Errorln(f.Handler.session, err) - } - return result, err -} -func (f *handlererr) Filewrite(r *sftp.Request) (io.WriterAt, error) { - result, err := f.Handler.Filewrite(r) - if err != nil { - wish.Errorln(f.Handler.session, err) - } - return result, err -} -func (f *handlererr) Fileread(r *sftp.Request) (io.ReaderAt, error) { - result, err := f.Handler.Fileread(r) - if err != nil { - wish.Errorln(f.Handler.session, err) - } - return result, err -} - -type listerat []os.FileInfo - -func (f listerat) ListAt(ls []os.FileInfo, offset int64) (int, error) { - var n int - if offset >= int64(len(f)) { - return 0, io.EOF - } - n = copy(ls, f[offset:]) - if n < len(ls) { - return n, io.EOF - } - return n, nil -} diff --git a/internal/sftp/sftp.go b/internal/sftp/sftp.go deleted file mode 100644 index 64c614fa..00000000 --- a/internal/sftp/sftp.go +++ /dev/null @@ -1,73 +0,0 @@ -package sftp - -import ( - "errors" - "io" - "log/slog" - "os" - - "github.com/charmbracelet/ssh" - "github.com/charmbracelet/wish" - "github.com/pkg/sftp" -) - -func SSHOption(rootPath string, logger *slog.Logger) ssh.Option { - return func(server *ssh.Server) error { - if server.SubsystemHandlers == nil { - server.SubsystemHandlers = map[string]ssh.SubsystemHandler{} - } - - server.SubsystemHandlers["sftp"] = SubsystemHandler(rootPath, logger) - return nil - } -} - -func SubsystemHandler(dir string, logger *slog.Logger) ssh.SubsystemHandler { - return func(session ssh.Session) { - defer func() { - if r := recover(); r != nil { - if logger != nil { - logger.Error("error running sftp middleware", "err", r) - } - wish.Println(session, "error running sftp middleware, check the flags you are using") - } - }() - - if session.User() != "_" { - wish.Errorln(session, "sftp subsystem is only available for the _ user") - return - } - - root, err := os.OpenRoot(dir) - if err != nil { - if logger != nil { - logger.Error("Error opening root", "err", err) - } - - wish.Errorln(session, err) - } - - handler := &handlererr{ - Handler: &handler{ - session: session, - root: root, - }, - } - - handlers := sftp.Handlers{ - FilePut: handler, - FileList: handler, - FileGet: handler, - FileCmd: handler, - } - - requestServer := sftp.NewRequestServer(session, handlers) - - if err := requestServer.Serve(); err != nil && !errors.Is(err, io.EOF) { - if logger != nil { - logger.Error("Error serving sftp subsystem", "err", err) - } - wish.Errorln(session, err) - } - } -} diff --git a/internal/worker/worker.go b/internal/worker/worker.go index 630a020b..9eb8fa24 100644 --- a/internal/worker/worker.go +++ b/internal/worker/worker.go @@ -83,44 +83,17 @@ func (me *Worker) DenoArgs(deno string) ([]string, error) { } npmCache := filepath.Join(xdg.CacheHome, "deno", "npm", "registry.npmjs.org") - if me.App.Config.Admin { - args = append( - args, - fmt.Sprintf("--allow-read=%s,%s,%s", me.App.RootDir, deno, npmCache), - fmt.Sprintf("--allow-write=%s", me.App.RootDir), - ) - - return args, nil - } // if root is not a symlink appDir := me.App.Dir() - if fi, err := os.Lstat(appDir); err == nil && fi.Mode()&os.ModeSymlink == 0 { - args = append( - args, - fmt.Sprintf("--allow-read=%s,%s,%s", appDir, deno, npmCache), - fmt.Sprintf("--allow-write=%s", me.App.DataDir()), - ) - - return args, nil - } - - target, err := os.Readlink(appDir) - if err != nil { - return nil, fmt.Errorf("could not read symlink: %w", err) - } - - if !filepath.IsAbs(target) { - target = filepath.Join(filepath.Dir(appDir), target) - } - args = append( args, - fmt.Sprintf("--allow-read=%s,%s,%s,%s", appDir, target, deno, npmCache), - fmt.Sprintf("--allow-write=%s,%s", me.App.DataDir(), filepath.Join(target, "data")), + fmt.Sprintf("--allow-read=%s,%s,%s", appDir, deno, npmCache), + fmt.Sprintf("--allow-write=%s", me.App.DataDir()), ) return args, nil + } func (me *Worker) Start() error { @@ -344,7 +317,11 @@ func (me *Worker) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - request, err := http.NewRequestWithContext(r.Context(), r.Method, fmt.Sprintf("http://127.0.0.1:%d%s", me.port, r.URL.String()), r.Body) + url := r.URL + url.Host = fmt.Sprintf("127.0.0.1:%d", me.port) + url.Scheme = "http" + + request, err := http.NewRequestWithContext(r.Context(), r.Method, url.String(), r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/schemas/config.schema.json b/schemas/config.schema.json index 3982b9c5..d43804e1 100644 --- a/schemas/config.schema.json +++ b/schemas/config.schema.json @@ -5,108 +5,15 @@ "domain" ], "properties": { - "oidc": { - "type": "object", - "description": "OpenID Connect configuration", - "required": [ - "issuer" - ], - "properties": { - "issuer": { - "description": "OpenID Connect issuer", - "type": "string" - } - } - }, "domain": { - "description": "Domain name", + "description": "Main domain", "type": "string" }, "additionalDomains": { - "description": "Additional wildcard domains", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedEmails": { - "description": "Authorized email addresses", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedGroups": { - "description": "Authorized groups", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedKeys": { - "description": "Authorized SSH keys", - "type": "array", - "items": { - "type": "string" - } - }, - "apps": { + "description": "Additional domains", "type": "object", "additionalProperties": { - "$ref": "#/definitions/appConfig" - } - }, - "repos": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/repoConfig" - } - } - }, - "definitions": { - "appConfig": { - "type": "object", - "properties": { - "additionalDomains": { - "description": "Additional app domains", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedEmails": { - "description": "Authorized email addresses", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedGroups": { - "description": "Authorized groups", - "type": "array", - "items": { - "type": "string" - } - }, - "authorizedKeys": { - "description": "Authorized SSH keys", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "repoConfig": { - "type": "object", - "properties": { - "authorizedKeys": { - "description": "Authorized SSH keys for the repository", - "type": "array", - "items": { - "type": "string" - } - } + "type": "string" } } } diff --git a/schemas/manifest.schema.json b/schemas/manifest.schema.json index b835b541..17e62b99 100644 --- a/schemas/manifest.schema.json +++ b/schemas/manifest.schema.json @@ -10,28 +10,6 @@ "description": "The root directory of the project", "type": "string" }, - "admin": { - "description": "Give app read/write access to the whole smallweb folder", - "type": "boolean" - }, - "private": { - "description": "Protect all routes behind authentication", - "type": "boolean" - }, - "privateRoutes": { - "description": "Make specific routes private", - "type": "array", - "items": { - "type": "string" - } - }, - "publicRoutes": { - "description": "Make specific routes public", - "type": "array", - "items": { - "type": "string" - } - }, "crons": { "description": "Cron jobs", "type": "array", @@ -55,13 +33,6 @@ } } } - }, - "labels": { - "description": "Labels for the project", - "type": "object", - "additionalProperties": { - "type": "string" - } } } }