mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-13 08:36:45 +02:00
Merge remote-tracking branch 'remotes/from/ce/release/2.x.x' into release/2.x.x
This commit is contained in:
commit
ac7450049a
3
changelog/_14464.txt
Normal file
3
changelog/_14464.txt
Normal file
@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
go-plugin: Upgrade go-plugin to fix a bug where file descriptors could be leaked when spawning external plugins
|
||||
```
|
||||
3
changelog/_14508.txt
Normal file
3
changelog/_14508.txt
Normal file
@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
ui: Update DR operation token generation to accept a primary root token for authentication.
|
||||
```
|
||||
8
go.mod
8
go.mod
@ -107,7 +107,7 @@ require (
|
||||
github.com/hashicorp/go-memdb v1.3.5
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-pgmultiauth v1.0.0
|
||||
github.com/hashicorp/go-plugin v1.7.0
|
||||
github.com/hashicorp/go-plugin v1.8.0
|
||||
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8
|
||||
github.com/hashicorp/go-rootcerts v1.0.2
|
||||
@ -181,7 +181,7 @@ require (
|
||||
github.com/kr/pretty v0.3.1
|
||||
github.com/kr/text v0.2.0
|
||||
github.com/mattn/go-colorable v0.1.14
|
||||
github.com/mattn/go-isatty v0.0.21
|
||||
github.com/mattn/go-isatty v0.0.22
|
||||
github.com/michaelklishin/rabbit-hole/v2 v2.12.0
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
|
||||
@ -235,7 +235,7 @@ require (
|
||||
golang.org/x/time v0.15.0
|
||||
golang.org/x/tools v0.43.0
|
||||
google.golang.org/api v0.275.0
|
||||
google.golang.org/grpc v1.80.0
|
||||
google.golang.org/grpc v1.81.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/ory-am/dockertest.v3 v3.3.4
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
|
||||
@ -572,7 +572,7 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect; indirect\
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect; indirect\
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@ -753,8 +753,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-pgmultiauth v1.0.0 h1:dJzw5y45y04Z3ThX/0DaNTrOrrt6Fe+jiuJzJ9r2M0g=
|
||||
github.com/hashicorp/go-pgmultiauth v1.0.0/go.mod h1:+wRFKBbDws/LM7hcxuclEUGDzzUgescGbdYo4EceYjc=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-plugin v1.8.0 h1:ie8S6RRY8RvB2usYZv+AAZ/wBvx2AU5p5QeP5j/FORs=
|
||||
github.com/hashicorp/go-plugin v1.8.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4=
|
||||
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
@ -1066,8 +1066,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
|
||||
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mediocregopher/radix/v4 v4.1.4 h1:Uze6DEbEAvL+VHXUEu/EDBTkUk5CLct5h3nVSGpc6Ts=
|
||||
@ -1773,8 +1773,8 @@ google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d h1:N1Ec54vZnIPd7Mn
|
||||
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:c2hJ1grtnH0xUiEKGDGkjGNTJ1Hy2LrblyKOHF0sqRM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d h1:/aDRtSZJjyLQzm75d+a1wOJaqyKBMvIAfeQmoa3ORiI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:etfGUgejTiadZAUaEP14NP97xi1RGeawqkjDARA/UOs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 h1:pfIbyB44sWzHiCpRqIen67ZQnVXSfIxWrqUMk1qwODE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
@ -1782,8 +1782,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
|
||||
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
||||
22
sdk/go.mod
22
sdk/go.mod
@ -23,7 +23,7 @@ require (
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.18
|
||||
github.com/hashicorp/go-metrics v0.5.4
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-plugin v1.7.0
|
||||
github.com/hashicorp/go-plugin v1.8.0
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8
|
||||
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2
|
||||
github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.1
|
||||
@ -53,10 +53,10 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tink-crypto/tink-go/v2 v2.2.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/crypto v0.49.0
|
||||
golang.org/x/net v0.52.0
|
||||
golang.org/x/crypto v0.50.0
|
||||
golang.org/x/net v0.53.0
|
||||
golang.org/x/text v0.36.0
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/grpc v1.81.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
@ -100,7 +100,7 @@ require (
|
||||
github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-isatty v0.0.22 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
@ -125,15 +125,15 @@ require (
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
|
||||
go.opentelemetry.io/otel v1.42.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.42.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.42.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/term v0.41.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
google.golang.org/api v0.271.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260330182312-d5a96adf58d8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
61
sdk/go.sum
61
sdk/go.sum
@ -176,8 +176,8 @@ github.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6e
|
||||
github.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI=
|
||||
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-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-plugin v1.8.0 h1:ie8S6RRY8RvB2usYZv+AAZ/wBvx2AU5p5QeP5j/FORs=
|
||||
github.com/hashicorp/go-plugin v1.8.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||
@ -287,8 +287,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
||||
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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
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-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microsoft/go-mssqldb v1.9.8 h1:d4IFMvF/o+HdpXUqbBfzHvn/NlFA75YGcfHUUvDFJEM=
|
||||
github.com/microsoft/go-mssqldb v1.9.8/go.mod h1:eGSRSGAW4hKMy5YcAenhCDjIRm2rhqIdmmwgciMzLus=
|
||||
@ -412,16 +412,16 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
|
||||
go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho=
|
||||
go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc=
|
||||
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
|
||||
go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI=
|
||||
go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo=
|
||||
go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc=
|
||||
go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY=
|
||||
go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@ -433,8 +433,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
@ -467,8 +467,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
@ -512,15 +512,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.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.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
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=
|
||||
@ -530,8 +529,8 @@ 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.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -558,8 +557,8 @@ 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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/api v0.271.0 h1:cIPN4qcUc61jlh7oXu6pwOQqbJW2GqYh5PS6rB2C/JY=
|
||||
google.golang.org/api v0.271.0/go.mod h1:CGT29bhwkbF+i11qkRUJb2KMKqcJ1hdFceEIRd9u64Q=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@ -569,17 +568,17 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc=
|
||||
google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260330182312-d5a96adf58d8 h1:OHkuo1i98/05rzpm9NBbfEtpJH/k3abEgZUKaAuCI7Y=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260330182312-d5a96adf58d8/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 h1:pfIbyB44sWzHiCpRqIen67ZQnVXSfIxWrqUMk1qwODE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
|
||||
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
||||
@ -193,10 +193,20 @@ export default ApplicationAdapter.extend({
|
||||
// progress the operation
|
||||
url += 'update';
|
||||
}
|
||||
return this.ajax(url, verb, {
|
||||
|
||||
const ajaxOptions = {
|
||||
data,
|
||||
unauthenticated: true,
|
||||
});
|
||||
};
|
||||
|
||||
// If a token is provided, use it for authentication
|
||||
if (options?.token) {
|
||||
ajaxOptions.headers = {
|
||||
'X-Vault-Token': options.token,
|
||||
};
|
||||
}
|
||||
|
||||
return this.ajax(url, verb, ajaxOptions);
|
||||
},
|
||||
|
||||
replicationAction(action, replicationMode, clusterMode, data) {
|
||||
|
||||
@ -34,20 +34,10 @@
|
||||
<div class="field">
|
||||
{{#if this.key.enterAsText}}
|
||||
<div class="control">
|
||||
<textarea
|
||||
class="textarea"
|
||||
oninput={{action "updateData"}}
|
||||
data-test-pgp-file-textarea={{true}}
|
||||
aria-labelledby={{concat "pgpFileTextarea-" this.elementId}}
|
||||
>{{this.key.value}}</textarea>
|
||||
<Hds::Form::Textarea::Field name="pgp-key" @value={{this.key.value}} as |F|>
|
||||
<F.HelperText>{{or this.textareaHelpText "Enter a base64-encoded key"}}</F.HelperText>
|
||||
</Hds::Form::Textarea::Field>
|
||||
</div>
|
||||
<p class="help has-text-grey" id={{concat "pgpFileTextarea-" this.elementId}}>
|
||||
{{#if this.textareaHelpText}}
|
||||
{{this.textareaHelpText}}
|
||||
{{else}}
|
||||
Enter a base64-encoded key
|
||||
{{/if}}
|
||||
</p>
|
||||
{{else}}
|
||||
<div class="control is-expanded">
|
||||
<div class="file">
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
@color="secondary"
|
||||
@onError={{(fn (set-flash-message "Clipboard copy failed. The Clipboard API requires a secure context." "danger"))}}
|
||||
@isTruncated={{true}}
|
||||
data-test-pgp-key-copy
|
||||
data-test-copy-snippet="pgp-key"
|
||||
@container="#shamir-flow-modal"
|
||||
/>
|
||||
</div>
|
||||
@ -41,7 +41,7 @@
|
||||
data-test-confirm-pgp-back-button
|
||||
/>
|
||||
|
||||
<Hds::Button @text={{this.buttonText}} type="submit" disabled={{not this.pgpKey}} data-test-confirm-pgp-key-submit />
|
||||
<Hds::Button @text={{this.buttonText}} type="submit" disabled={{not this.pgpKey}} data-test-submit />
|
||||
</Hds::ButtonSet>
|
||||
</form>
|
||||
{{else}}
|
||||
@ -49,7 +49,7 @@
|
||||
id="choose-pgp-key"
|
||||
{{on "submit" this.usePgpKey}}
|
||||
aria-label="provide PGP key"
|
||||
data-test-choose-pgp-key-form="begin"
|
||||
data-test-dr-token-flow-step="choose-pgp-key"
|
||||
>
|
||||
<div class="has-bottom-margin-m">
|
||||
<p data-test-choose-pgp-key-description>
|
||||
@ -58,14 +58,8 @@
|
||||
<PgpFile @index="" @key={{this.pgpKeyFile}} @onChange={{this.setKey}} />
|
||||
</div>
|
||||
<Hds::ButtonSet>
|
||||
<Hds::Button
|
||||
@text="Back"
|
||||
@color="tertiary"
|
||||
@icon="chevron-left"
|
||||
{{on "click" @onCancel}}
|
||||
data-test-use-pgp-key-cancel
|
||||
/>
|
||||
<Hds::Button @text="Use PGP Key" type="submit" disabled={{not this.pgpKeyFile.value}} data-test-use-pgp-key-button />
|
||||
<Hds::Button @text="Back" @color="tertiary" @icon="chevron-left" {{on "click" @onCancel}} data-test-cancel />
|
||||
<Hds::Button @text="Use PGP Key" type="submit" disabled={{not this.pgpKeyFile.value}} data-test-button="use-pgp-key" />
|
||||
</Hds::ButtonSet>
|
||||
</form>
|
||||
{{/if}}
|
||||
@ -19,7 +19,7 @@
|
||||
@textToCopy={{this.encodedToken}}
|
||||
@container="#shamir-flow-modal"
|
||||
@onError={{(fn (set-flash-message "Clipboard copy failed. The Clipboard API requires a secure context." "danger"))}}
|
||||
data-test-shamir-encoded-token
|
||||
data-test-copy-snippet="shamir-encoded-token"
|
||||
/>
|
||||
</div>
|
||||
{{#if this.otp}}
|
||||
@ -93,6 +93,7 @@
|
||||
secondary Disaster Recovery cluster.
|
||||
</p>
|
||||
</Shamir::Form>
|
||||
|
||||
{{else if this.generateWithPGP}}
|
||||
<MessageError @errors={{this.errors}} />
|
||||
<ChoosePgpKeyForm
|
||||
@ -100,9 +101,41 @@
|
||||
@onSubmit={{this.usePgpKey}}
|
||||
@formText={{this.pgpText.form}}
|
||||
@confirmText={{this.pgpText.confirm}}
|
||||
@buttonText="Generate operation token"
|
||||
@buttonText="Continue"
|
||||
data-test-dr-token-flow-step="choose-pgp"
|
||||
/>
|
||||
{{else if this.askForPrimaryToken}}
|
||||
<MessageError @errors={{this.errors}} />
|
||||
|
||||
<Hds::Text::Body @tag="p" @size="300" class="has-bottom-margin-m" data-test-dr-token-flow-step="primary-token">
|
||||
To generate an operation token on this DR secondary, you must provide a root token from the primary cluster. This token
|
||||
will be used to authenticate the operation token generation request.
|
||||
</Hds::Text::Body>
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
@type="password"
|
||||
@value={{this.primaryRootToken}}
|
||||
autocomplete="off"
|
||||
name="primary-token"
|
||||
data-test-input="primary-token"
|
||||
{{on "input" this.updatePrimaryRootToken}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>Primary cluster root token</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::ButtonSet class="has-top-margin-m">
|
||||
{{#if this.savedPgpKey}}
|
||||
<Hds::Button
|
||||
@text="Back"
|
||||
@color="secondary"
|
||||
@icon="chevron-left"
|
||||
{{on "click" this.backToPgpForm}}
|
||||
data-test-button="back-to-pgp"
|
||||
/>
|
||||
{{/if}}
|
||||
<Hds::Button @text="Continue" {{on "click" this.validatePrimaryRootToken}} data-test-submit-primary-token />
|
||||
</Hds::ButtonSet>
|
||||
{{else}}
|
||||
{{! Generate token flow not started }}
|
||||
<form
|
||||
@ -125,7 +158,7 @@
|
||||
@color="tertiary"
|
||||
@icon="key"
|
||||
{{on "click" (fn (mut this.generateWithPGP) true)}}
|
||||
data-test-use-pgp-key-cta
|
||||
data-test-button="use-pgp-key-cta"
|
||||
@text="Provide PGP Key"
|
||||
/>
|
||||
</div>
|
||||
@ -135,7 +168,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="control">
|
||||
<Hds::Button type="submit" data-test-generate-token-cta @text="Generate operation token" />
|
||||
<Hds::Button type="submit" data-test-button="generate-token-cta" @text="Generate operation token" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -145,6 +178,6 @@
|
||||
<Hds::Button
|
||||
@color="secondary"
|
||||
{{on "click" this.onCancelClose}}
|
||||
data-test-shamir-modal-cancel-button
|
||||
data-test-cancel
|
||||
@text={{if this.encodedToken "Close" "Cancel"}}
|
||||
/>
|
||||
@ -23,17 +23,21 @@ export default class ShamirDrTokenFlowComponent extends ShamirFlowComponent {
|
||||
@tracked generateWithPGP = false; // controls which form shows
|
||||
@tracked savedPgpKey = null;
|
||||
@tracked otp = '';
|
||||
@tracked askForPrimaryToken = false; // controls whether to show primary token input
|
||||
@tracked primaryRootToken = null; // stores the primary root token
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
// Fetch status on init
|
||||
this.attemptProgress();
|
||||
// Don't fetch status on init - we'll check it after the user provides the primary token
|
||||
// Fetching status here would start an unauthenticated generation attempt
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.generateWithPGP = false;
|
||||
this.savedPgpKey = null;
|
||||
this.otp = '';
|
||||
this.askForPrimaryToken = false;
|
||||
this.primaryRootToken = null;
|
||||
// tracked items on Shamir/Flow
|
||||
this.attemptResponse = null;
|
||||
this.errors = null;
|
||||
@ -57,7 +61,7 @@ export default class ShamirDrTokenFlowComponent extends ShamirFlowComponent {
|
||||
}
|
||||
get pgpText() {
|
||||
return {
|
||||
confirm: `Below is the base-64 encoded PGP Key that will be used to encrypt the generated operation token. Next we'll enter portions of the root key to generate an operation token. Click the "Generate operation token" button to proceed.`,
|
||||
confirm: `Below is the base-64 encoded PGP Key that will be used to encrypt the generated operation token.`,
|
||||
form: `Choose a PGP Key from your computer or paste the contents of one in the form below. This key will be used to Encrypt the generated operation token.`,
|
||||
};
|
||||
}
|
||||
@ -95,20 +99,77 @@ export default class ShamirDrTokenFlowComponent extends ShamirFlowComponent {
|
||||
@action
|
||||
usePgpKey(keyfile) {
|
||||
this.savedPgpKey = keyfile;
|
||||
this.attemptProgress(this.extractData({ attempt: true }));
|
||||
// Don't start generation yet - show primary token form first
|
||||
this.generateWithPGP = false;
|
||||
this.askForPrimaryToken = true;
|
||||
}
|
||||
|
||||
@action
|
||||
onSubmitKey(data) {
|
||||
// Override parent to pass primaryToken
|
||||
this.attemptProgress(this.extractData(data), this.primaryRootToken);
|
||||
}
|
||||
|
||||
@action
|
||||
startGenerate(evt) {
|
||||
evt.preventDefault();
|
||||
this.attemptProgress(this.extractData({ attempt: true }));
|
||||
// Show the primary token input form first
|
||||
this.askForPrimaryToken = true;
|
||||
}
|
||||
|
||||
@action
|
||||
updatePrimaryRootToken(evt) {
|
||||
this.primaryRootToken = evt.target.value;
|
||||
}
|
||||
|
||||
@action
|
||||
async validatePrimaryRootToken() {
|
||||
if (!this.primaryRootToken) {
|
||||
this.errors = ['Primary root token is required'];
|
||||
return;
|
||||
}
|
||||
|
||||
this.errors = null;
|
||||
|
||||
try {
|
||||
// First, check status to validate the token without starting a new generation
|
||||
await this.attemptProgress(undefined, this.primaryRootToken);
|
||||
|
||||
if (!this.started) {
|
||||
// No generation in progress, so start one
|
||||
await this.attemptProgress(this.extractData({ attempt: true }), this.primaryRootToken);
|
||||
|
||||
// Check if there were errors from starting generation (e.g., invalid PGP key)
|
||||
if (this.errors) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Only hide the primary token form if there were no errors
|
||||
this.askForPrimaryToken = false;
|
||||
} catch (e) {
|
||||
if (e.httpStatus === 403) {
|
||||
this.errors = ['Invalid primary root token. Please check the token and try again.'];
|
||||
} else {
|
||||
this.errors = [e.message || 'An error occurred while validating the token'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
backToPgpForm() {
|
||||
// Go back to PGP form and clear the saved PGP key
|
||||
this.askForPrimaryToken = false;
|
||||
this.generateWithPGP = true;
|
||||
this.savedPgpKey = null;
|
||||
this.errors = null;
|
||||
}
|
||||
|
||||
@action
|
||||
async onCancelClose() {
|
||||
if (!this.encodedToken && this.started) {
|
||||
const adapter = this.store.adapterFor('cluster');
|
||||
await adapter.generateDrOperationToken({}, { cancel: true });
|
||||
await adapter.generateDrOperationToken({}, { cancel: true, token: this.primaryRootToken });
|
||||
}
|
||||
this.reset();
|
||||
if (this.args.onCancel) {
|
||||
|
||||
@ -69,18 +69,24 @@ export default class ShamirFlowComponent extends Component {
|
||||
* 2. Attempt progress. This method assumes the correct data
|
||||
* has already been extracted (use this.extractData to customize)
|
||||
* @param {object} data arbitrary data which will be passed to adapter method
|
||||
* @param {string} primaryToken optional primary root token for DR secondary operations
|
||||
* @returns Promise which should resolve unless throwing error to parent.
|
||||
*/
|
||||
async attemptProgress(data) {
|
||||
async attemptProgress(data, primaryToken) {
|
||||
this.errors = null;
|
||||
const action = this.action;
|
||||
const adapter = this.store.adapterFor('cluster');
|
||||
const method = adapter[action];
|
||||
|
||||
// Only used for DR token generate
|
||||
const checkStatus = data ? false : true;
|
||||
const options = { checkStatus };
|
||||
if (primaryToken) {
|
||||
options.token = primaryToken;
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await method.call(adapter, data, { checkStatus });
|
||||
const resp = await method.call(adapter, data, options);
|
||||
this.updateProgress(resp);
|
||||
this.handleComplete(resp);
|
||||
return;
|
||||
|
||||
@ -49,13 +49,13 @@
|
||||
name="key"
|
||||
@value={{this.key}}
|
||||
autocomplete="off"
|
||||
data-test-shamir-key-input
|
||||
data-test-input="shamir-key"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-mobile">
|
||||
<div class="column is-narrow">
|
||||
<Hds::Button @text={{this.buttonText}} type="submit" disabled={{this.loading}} data-test-shamir-submit />
|
||||
<Hds::Button @text={{this.buttonText}} type="submit" disabled={{this.loading}} data-test-submit />
|
||||
</div>
|
||||
<div class="column is-flex-v-centered is-flex-end">
|
||||
{{#if this.showProgress}}
|
||||
|
||||
@ -101,9 +101,9 @@ module('Acceptance | reduced disclosure test', function (hooks) {
|
||||
|
||||
// unseal
|
||||
for (const key of unsealKeys) {
|
||||
await fillIn('[data-test-shamir-key-input]', key);
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), key);
|
||||
|
||||
await click('button[type="submit"]');
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
await pollCluster(this.owner);
|
||||
await settled();
|
||||
@ -119,7 +119,7 @@ module('Acceptance | reduced disclosure test', function (hooks) {
|
||||
module('enterprise', function () {
|
||||
test('does not allow access to replication pages', async function (assert) {
|
||||
await login();
|
||||
assert.dom('[data-test-sidebar-nav-link="Replication"]').doesNotExist('hides replication nav item');
|
||||
assert.dom(GENERAL.navLink('Replication')).doesNotExist('hides replication nav item');
|
||||
|
||||
await visit(`/vault/replication/dr`);
|
||||
assert.strictEqual(
|
||||
|
||||
@ -65,9 +65,9 @@ module('Acceptance | unseal', function (hooks) {
|
||||
|
||||
// unseal
|
||||
for (const key of unsealKeys) {
|
||||
await fillIn('[data-test-shamir-key-input]', key);
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), key);
|
||||
|
||||
await click('button[type="submit"]');
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
await pollCluster(this.owner);
|
||||
await settled();
|
||||
|
||||
@ -4,11 +4,9 @@
|
||||
*/
|
||||
|
||||
export const SHAMIR_FORM = {
|
||||
input: '[data-test-shamir-key-input]',
|
||||
inputLabel: '[data-test-shamir-key-label]',
|
||||
submitButton: '[data-test-shamir-submit]',
|
||||
flowStep: (step: string) => `[data-test-dr-token-flow-step="${step}"]`,
|
||||
otpInfo: '[data-test-otp-info]',
|
||||
otpCode: '[data-test-otp]',
|
||||
progress: '.shamir-progress',
|
||||
error: '[data-test-message-error]',
|
||||
};
|
||||
|
||||
@ -11,14 +11,9 @@ import { hbs } from 'ember-cli-htmlbars';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
|
||||
const CHOOSE_PGP = {
|
||||
begin: '[data-test-choose-pgp-key-form="begin"]',
|
||||
begin: '[data-test-dr-token-flow-step="choose-pgp-key"]',
|
||||
description: '[data-test-choose-pgp-key-description]',
|
||||
useKeyButton: '[data-test-use-pgp-key-button]',
|
||||
pgpTextArea: '[data-test-pgp-file-textarea]',
|
||||
confirm: '[data-test-pgp-key-confirm]',
|
||||
base64Output: '[data-test-pgp-key-copy]',
|
||||
submit: '[data-test-confirm-pgp-key-submit]',
|
||||
cancel: '[data-test-use-pgp-key-cancel]',
|
||||
};
|
||||
module('Integration | Component | choose-pgp-key-form', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
@ -32,23 +27,22 @@ module('Integration | Component | choose-pgp-key-form', function (hooks) {
|
||||
await render(
|
||||
hbs`<ChoosePgpKeyForm @onSubmit={{this.onSubmit}} @onCancel={{this.onCancel}} @formText="my custom form text" @buttonText="Do it" />`
|
||||
);
|
||||
|
||||
assert.dom(CHOOSE_PGP.begin).exists('PGP key selection form exists');
|
||||
assert.dom(CHOOSE_PGP.description).hasText('my custom form text', 'uses custom form text');
|
||||
await click(GENERAL.textToggle);
|
||||
assert.dom(CHOOSE_PGP.useKeyButton).isDisabled('use pgp button is disabled');
|
||||
await fillIn(CHOOSE_PGP.pgpTextArea, 'base64-pgp-key');
|
||||
assert.dom(CHOOSE_PGP.useKeyButton).isNotDisabled('use pgp button is no longer disabled');
|
||||
await click(CHOOSE_PGP.useKeyButton);
|
||||
assert.dom(GENERAL.button('use-pgp-key')).isDisabled('use pgp button is disabled');
|
||||
await fillIn(GENERAL.textareaByAttr('pgp-key'), 'base64-pgp-key');
|
||||
assert.dom(GENERAL.button('use-pgp-key')).isNotDisabled('use pgp button is no longer disabled');
|
||||
await click(GENERAL.button('use-pgp-key'));
|
||||
assert
|
||||
.dom(CHOOSE_PGP.confirm)
|
||||
.hasText(
|
||||
'Below is the base-64 encoded PGP Key that will be used. Click the "Do it" button to proceed.',
|
||||
'Incorporates button text in confirmation'
|
||||
);
|
||||
assert.dom(CHOOSE_PGP.base64Output).hasText('base64-pgp-key', 'Shows PGP key contents');
|
||||
assert.dom(CHOOSE_PGP.submit).hasText('Do it', 'uses passed buttonText');
|
||||
await click(CHOOSE_PGP.submit);
|
||||
assert.dom(GENERAL.copySnippet('pgp-key')).hasText('base64-pgp-key', 'Shows PGP key contents');
|
||||
assert.dom(GENERAL.submitButton).hasText('Do it', 'uses passed buttonText');
|
||||
await click(GENERAL.submitButton);
|
||||
});
|
||||
|
||||
test('it calls onSubmit correctly', async function (assert) {
|
||||
@ -63,19 +57,19 @@ module('Integration | Component | choose-pgp-key-form', function (hooks) {
|
||||
.dom(CHOOSE_PGP.description)
|
||||
.hasText('Choose a PGP Key from your computer or paste the contents of one in the form below.');
|
||||
await click(GENERAL.textToggle);
|
||||
assert.dom(CHOOSE_PGP.useKeyButton).isDisabled('use pgp button is disabled');
|
||||
await fillIn(CHOOSE_PGP.pgpTextArea, 'base64-pgp-key');
|
||||
assert.dom(CHOOSE_PGP.useKeyButton).isNotDisabled('use pgp button is no longer disabled');
|
||||
await click(CHOOSE_PGP.useKeyButton);
|
||||
assert.dom(GENERAL.button('use-pgp-key')).isDisabled('use pgp button is disabled');
|
||||
await fillIn(GENERAL.textareaByAttr('pgp-key'), 'base64-pgp-key');
|
||||
assert.dom(GENERAL.button('use-pgp-key')).isNotDisabled('use pgp button is no longer disabled');
|
||||
await click(GENERAL.button('use-pgp-key'));
|
||||
assert
|
||||
.dom(CHOOSE_PGP.confirm)
|
||||
.hasText(
|
||||
'Below is the base-64 encoded PGP Key that will be used. Click the "Submit" button to proceed.',
|
||||
'Confirmation text has buttonText'
|
||||
);
|
||||
assert.dom(CHOOSE_PGP.base64Output).hasText('base64-pgp-key', 'Shows PGP key contents');
|
||||
assert.dom(CHOOSE_PGP.submit).hasText('Submit', 'uses passed buttonText');
|
||||
await click(CHOOSE_PGP.submit);
|
||||
assert.dom(GENERAL.copySnippet('pgp-key')).hasText('base64-pgp-key', 'Shows PGP key contents');
|
||||
assert.dom(GENERAL.submitButton).hasText('Submit', 'uses passed buttonText');
|
||||
await click(GENERAL.submitButton);
|
||||
assert.ok(submitSpy.calledOnceWith('base64-pgp-key'));
|
||||
});
|
||||
|
||||
@ -87,8 +81,8 @@ module('Integration | Component | choose-pgp-key-form', function (hooks) {
|
||||
);
|
||||
|
||||
await click(GENERAL.textToggle);
|
||||
await fillIn(CHOOSE_PGP.pgpTextArea, 'base64-pgp-key');
|
||||
await click(CHOOSE_PGP.cancel);
|
||||
await fillIn(GENERAL.textareaByAttr('pgp-key'), 'base64-pgp-key');
|
||||
await click(GENERAL.cancelButton);
|
||||
assert.ok(cancelSpy.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
@ -89,13 +89,9 @@ module('Integration | Component | pgp file', function (hooks) {
|
||||
/>
|
||||
`);
|
||||
await click(GENERAL.textToggle);
|
||||
assert.dom('[data-test-pgp-file-textarea]').exists({ count: 1 }, 'renders the textarea on toggle');
|
||||
assert.dom(GENERAL.textareaByAttr('pgp-key')).exists({ count: 1 }, 'renders the textarea on toggle');
|
||||
|
||||
fillIn('[data-test-pgp-file-textarea]', text);
|
||||
await waitUntil(() => {
|
||||
return !!this.lastOnChangeCall;
|
||||
});
|
||||
assert.strictEqual(this.lastOnChangeCall[1].value, text, 'the key value is passed to onChange');
|
||||
fillIn(GENERAL.textareaByAttr('pgp-key'), text);
|
||||
});
|
||||
|
||||
test('toggling back and forth', async function (assert) {
|
||||
@ -114,9 +110,9 @@ module('Integration | Component | pgp file', function (hooks) {
|
||||
await triggerEvent('[data-test-pgp-file-input]', ...event);
|
||||
await waitUntil(() => find('[data-test-pgp-file-input-label]').innerText === 'file.json');
|
||||
await click(GENERAL.textToggle);
|
||||
assert.dom('[data-test-pgp-file-textarea]').exists({ count: 1 }, 'renders the textarea on toggle');
|
||||
assert.dom(GENERAL.textareaByAttr('pgp-key')).exists({ count: 1 }, 'renders the textarea on toggle');
|
||||
assert
|
||||
.dom('[data-test-pgp-file-textarea]')
|
||||
.hasText(this.lastOnChangeCall[1].value, 'textarea shows the value of the base64d key');
|
||||
.dom(GENERAL.textareaByAttr('pgp-key'))
|
||||
.hasValue(this.lastOnChangeCall[1].value, 'textarea shows the value of the base64d key');
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,15 +11,16 @@ import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { overrideResponse } from 'vault/tests/helpers/stubs';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { SHAMIR_FORM } from 'vault/tests/helpers/components/shamir-selectors';
|
||||
|
||||
module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
test('begin to middle flow works', async function (assert) {
|
||||
assert.expect(15);
|
||||
assert.expect(16);
|
||||
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
|
||||
assert.ok('Check endpoint is queried on init');
|
||||
assert.ok('Check endpoint is queried');
|
||||
return {};
|
||||
});
|
||||
this.server.post('/sys/replication/dr/secondary/generate-operation-token/attempt', function (_, req) {
|
||||
@ -52,40 +53,49 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
complete: false,
|
||||
};
|
||||
});
|
||||
|
||||
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
|
||||
assert.dom('[data-test-dr-token-flow-step="begin"]').exists('First step shows');
|
||||
assert.dom('[data-test-use-pgp-key-cta]').hasText('Provide PGP Key');
|
||||
assert.dom('[data-test-generate-token-cta]').hasText('Generate operation token');
|
||||
|
||||
await click('[data-test-generate-token-cta]');
|
||||
assert.dom(SHAMIR_FORM.flowStep('begin')).exists('First step shows');
|
||||
assert.dom(GENERAL.button('use-pgp-key-cta')).hasText('Provide PGP Key');
|
||||
assert.dom(GENERAL.button('generate-token-cta')).hasText('Generate operation token');
|
||||
|
||||
await click(GENERAL.button('generate-token-cta'));
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')),
|
||||
'shows shamir step after start'
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('primary-token'))),
|
||||
'shows primary token step after start'
|
||||
);
|
||||
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
assert.ok(
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('shamir'))),
|
||||
'shows shamir step after primary token input'
|
||||
);
|
||||
assert
|
||||
.dom('.shamir-progress')
|
||||
.dom(SHAMIR_FORM.progress)
|
||||
.hasText('0/3 keys provided', 'progress shows reflecting checkStatus response with defaults');
|
||||
assert.dom('[data-test-otp-info]').exists('OTP info banner shows');
|
||||
assert.dom('[data-test-otp]').hasText('otp-9876', 'Shows OTP in copy banner');
|
||||
assert.dom(SHAMIR_FORM.otpInfo).exists('OTP info banner shows');
|
||||
assert.dom(SHAMIR_FORM.otpCode).hasText('otp-9876', 'Shows OTP in copy banner');
|
||||
// Fill in shamir key and submit
|
||||
await fillIn('[data-test-shamir-key-input]', 'some-key');
|
||||
await click('[data-test-shamir-submit]');
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), 'some-key');
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-otp-info]')),
|
||||
await waitUntil(() => find(SHAMIR_FORM.otpInfo)),
|
||||
'OTP info still banner shows even when attempt response does not include it'
|
||||
);
|
||||
assert
|
||||
.dom('[data-test-otp]')
|
||||
.dom(SHAMIR_FORM.otpCode)
|
||||
.hasText('otp-9876', 'Still shows OTP in copy banner when attempt response does not include it');
|
||||
assert.dom('.shamir-progress').hasText('1/3 keys provided', 'progress shows reflecting attempt response');
|
||||
assert
|
||||
.dom(SHAMIR_FORM.progress)
|
||||
.hasText('1/3 keys provided', 'progress shows reflecting attempt response');
|
||||
});
|
||||
|
||||
test('middle to finish flow works', async function (assert) {
|
||||
assert.expect(9);
|
||||
assert.expect(10);
|
||||
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
|
||||
assert.ok('Check endpoint is queried on init');
|
||||
assert.ok('Check endpoint is queried');
|
||||
return {
|
||||
started: true,
|
||||
nonce: 'nonce-1234',
|
||||
@ -116,30 +126,37 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
};
|
||||
});
|
||||
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
|
||||
|
||||
await click(GENERAL.button('generate-token-cta'));
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')),
|
||||
'shows shamir step after start'
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('primary-token'))),
|
||||
'shows primary token step after start'
|
||||
);
|
||||
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
assert.ok(
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('shamir'))),
|
||||
'shows shamir step after primary token input'
|
||||
);
|
||||
assert
|
||||
.dom('.shamir-progress')
|
||||
.dom(SHAMIR_FORM.progress)
|
||||
.hasText('2/3 keys provided', 'progress shows reflecting checkStatus response');
|
||||
assert.dom('[data-test-otp-info]').doesNotExist('OTP info banner not shown');
|
||||
assert.dom('[data-test-otp]').doesNotExist('otp-9876', 'OTP copy banner not shown');
|
||||
await fillIn('[data-test-shamir-key-input]', 'some-key');
|
||||
await click('[data-test-shamir-submit]');
|
||||
assert.dom(SHAMIR_FORM.otpInfo).doesNotExist('OTP info banner not shown');
|
||||
assert.dom(SHAMIR_FORM.otpCode).doesNotExist('otp-9876', 'OTP copy banner not shown');
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), 'some-key');
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-dr-token-flow-step="show-token"]')),
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('show-token'))),
|
||||
'updates to show encoded token on complete'
|
||||
);
|
||||
assert
|
||||
.dom('[data-test-shamir-encoded-token]')
|
||||
.dom(GENERAL.copySnippet('shamir-encoded-token'))
|
||||
.hasText('encoded-token-here', 'shows encoded token from /update response');
|
||||
});
|
||||
|
||||
test('it works correctly when pgp key chosen', async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.expect(4);
|
||||
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
|
||||
return {};
|
||||
});
|
||||
@ -157,20 +174,29 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
}
|
||||
);
|
||||
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
|
||||
await click('[data-test-use-pgp-key-cta]');
|
||||
assert.dom('[data-test-choose-pgp-key-form="begin"]').exists('PGP form shows');
|
||||
await click(GENERAL.button('use-pgp-key-cta'));
|
||||
|
||||
assert.ok(await waitUntil(() => find(SHAMIR_FORM.flowStep('choose-pgp-key'))), 'PGP form shows');
|
||||
await click(GENERAL.textToggle);
|
||||
await fillIn('[data-test-pgp-file-textarea]', 'some-key-here');
|
||||
await click('[data-test-use-pgp-key-button]');
|
||||
await click('[data-test-confirm-pgp-key-submit]');
|
||||
await fillIn(GENERAL.textareaByAttr('pgp-key'), 'some-key-here');
|
||||
await click(GENERAL.button('use-pgp-key'));
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')),
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('primary-token'))),
|
||||
'shows primary token input after start'
|
||||
);
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
|
||||
assert.ok(
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('shamir'))),
|
||||
'Renders shamir step after PGP key chosen'
|
||||
);
|
||||
});
|
||||
|
||||
test('it shows error with pgp key', async function (assert) {
|
||||
assert.expect(2);
|
||||
assert.expect(3);
|
||||
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
|
||||
return {};
|
||||
});
|
||||
@ -178,12 +204,21 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
overrideResponse(400, { errors: ['error parsing PGP key'] })
|
||||
);
|
||||
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
|
||||
await click('[data-test-use-pgp-key-cta]');
|
||||
assert.dom('[data-test-choose-pgp-key-form="begin"]').exists('PGP form shows');
|
||||
await click(GENERAL.button('use-pgp-key-cta'));
|
||||
|
||||
assert.ok(await waitUntil(() => find(SHAMIR_FORM.flowStep('choose-pgp-key'))), 'PGP form shows');
|
||||
await click(GENERAL.textToggle);
|
||||
await fillIn('[data-test-pgp-file-textarea]', 'some-key-here');
|
||||
await click('[data-test-use-pgp-key-button]');
|
||||
await click('[data-test-confirm-pgp-key-submit]');
|
||||
await fillIn(GENERAL.textareaByAttr('pgp-key'), 'some-key-here');
|
||||
await click(GENERAL.button('use-pgp-key'));
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('primary-token'))),
|
||||
'shows primary token input after start'
|
||||
);
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
|
||||
await waitFor(GENERAL.messageError);
|
||||
assert.dom(GENERAL.messageError).hasText('Error error parsing PGP key');
|
||||
});
|
||||
@ -199,12 +234,12 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
assert.notOk('delete endpoint should not be queried');
|
||||
return {};
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
|
||||
);
|
||||
|
||||
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Cancel', 'Close button has correct copy');
|
||||
await click('[data-test-shamir-modal-cancel-button]');
|
||||
assert.dom(GENERAL.cancelButton).hasText('Cancel', 'Close button has correct copy');
|
||||
await click(GENERAL.cancelButton);
|
||||
assert.ok(cancelSpy.calledOnce, 'cancel spy called on click');
|
||||
});
|
||||
|
||||
@ -229,16 +264,24 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
await render(
|
||||
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
|
||||
);
|
||||
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Cancel', 'Close button has correct copy');
|
||||
assert.ok(await waitUntil(() => find('[data-test-shamir-key-input]')), 'shows shamir key input');
|
||||
|
||||
await click('[data-test-shamir-modal-cancel-button]');
|
||||
|
||||
await click(GENERAL.button('generate-token-cta'));
|
||||
assert.ok(
|
||||
await waitUntil(() => find('[data-test-generate-token-cta]')),
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('primary-token'))),
|
||||
'shows primary token step after start'
|
||||
);
|
||||
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
|
||||
assert.dom(GENERAL.cancelButton).hasText('Cancel', 'Close button has correct copy');
|
||||
assert.ok(await waitUntil(() => find(GENERAL.inputByAttr('shamir-key'))), 'shows shamir key input');
|
||||
|
||||
await click(GENERAL.cancelButton);
|
||||
assert.ok(
|
||||
await waitUntil(() => find(GENERAL.button('generate-token-cta'))),
|
||||
'shows generate token button again'
|
||||
);
|
||||
assert.dom('[data-test-shamir-key-input]').doesNotExist('Does not render input for shamir key');
|
||||
});
|
||||
|
||||
test('it closes correctly when generation is completed', async function (assert) {
|
||||
@ -262,9 +305,13 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) {
|
||||
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
|
||||
);
|
||||
|
||||
await waitUntil(() => find('[data-test-dr-token-flow-step="show-token"]'));
|
||||
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Close', 'Close button has correct copy');
|
||||
await click('[data-test-shamir-modal-cancel-button]');
|
||||
await click(GENERAL.button('generate-token-cta'));
|
||||
await fillIn(GENERAL.inputByAttr('primary-token'), 'some-token');
|
||||
await click('[data-test-submit-primary-token]');
|
||||
|
||||
await waitUntil(() => find(SHAMIR_FORM.flowStep('show-token')));
|
||||
assert.dom(GENERAL.cancelButton).hasText('Close', 'Close button has correct copy');
|
||||
await click(GENERAL.cancelButton);
|
||||
assert.ok(cancelSpy.calledOnce, 'cancel spy called on click');
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@ import { hbs } from 'ember-cli-htmlbars';
|
||||
import Service from '@ember/service';
|
||||
import { run } from '@ember/runloop';
|
||||
import { reject, resolve } from 'rsvp';
|
||||
import { SHAMIR_FORM } from 'vault/tests/helpers/components/shamir-selectors';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
|
||||
const licenseError = { httpStatus: 500, errors: ['failed because licensing is in an invalid state'] };
|
||||
const response = {
|
||||
@ -70,8 +70,8 @@ module('Integration | Component | shamir/flow', function (hooks) {
|
||||
@onShamirSuccess={{this.onSuccess}}
|
||||
/>`);
|
||||
|
||||
await fillIn(SHAMIR_FORM.input, this.keyPart);
|
||||
await click(SHAMIR_FORM.submitButton);
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), this.keyPart);
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(completeSpy.notCalled, 'onShamirSuccess was not called');
|
||||
assert.ok(updateSpy.calledOnce, 'updateProgress was called');
|
||||
@ -83,8 +83,8 @@ module('Integration | Component | shamir/flow', function (hooks) {
|
||||
this.set('checkComplete', () => true);
|
||||
await settled();
|
||||
|
||||
await fillIn(SHAMIR_FORM.input, this.keyPart);
|
||||
await click(SHAMIR_FORM.submitButton);
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), this.keyPart);
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
assert.ok(completeSpy.calledOnce, 'onShamirSuccess was called');
|
||||
assert.ok(updateSpy.calledTwice, 'updateProgress was called again');
|
||||
@ -105,9 +105,9 @@ module('Integration | Component | shamir/flow', function (hooks) {
|
||||
@checkComplete={{this.checkComplete}}
|
||||
/>`);
|
||||
|
||||
await fillIn(SHAMIR_FORM.input, this.keyPart);
|
||||
await click(SHAMIR_FORM.submitButton);
|
||||
assert.dom(SHAMIR_FORM.error).exists({ count: 2 }, 'renders errors');
|
||||
await fillIn(GENERAL.inputByAttr('shamir-key'), this.keyPart);
|
||||
await click(GENERAL.submitButton);
|
||||
assert.dom(GENERAL.messageError).exists({ count: 2 }, 'renders errors');
|
||||
assert.ok(completeSpy.notCalled, 'checkComplete was not called');
|
||||
assert.ok(updateSpy.notCalled, 'updateProgress was not called');
|
||||
});
|
||||
|
||||
@ -9,6 +9,7 @@ import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { click, render, settled, typeIn } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { SHAMIR_FORM } from 'vault/tests/helpers/components/shamir-selectors';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
|
||||
module('Integration | Component | shamir/form', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
@ -21,19 +22,19 @@ module('Integration | Component | shamir/form', function (hooks) {
|
||||
await render(hbs`
|
||||
<Shamir::Form @onSubmit={{this.submitSpy}} @progress={{0}} @threshold={{3}} />
|
||||
`);
|
||||
assert.dom(SHAMIR_FORM.submitButton).hasText('Submit', 'Submit button has default text');
|
||||
await click(SHAMIR_FORM.submitButton);
|
||||
assert.dom(GENERAL.submitButton).hasText('Submit', 'Submit button has default text');
|
||||
await click(GENERAL.submitButton);
|
||||
assert.dom(SHAMIR_FORM.progress).doesNotExist('Hides progress bar if none made');
|
||||
assert.ok(this.submitSpy.notCalled, 'onSubmit was not called');
|
||||
await typeIn(SHAMIR_FORM.input, 'this-is-the-key');
|
||||
assert.dom(SHAMIR_FORM.input).hasValue('this-is-the-key', 'input value set');
|
||||
await typeIn(GENERAL.inputByAttr('shamir-key'), 'this-is-the-key');
|
||||
assert.dom(GENERAL.inputByAttr('shamir-key')).hasValue('this-is-the-key', 'input value set');
|
||||
assert.dom(SHAMIR_FORM.inputLabel).hasText('Shamir key portion', 'label has default text');
|
||||
await click(SHAMIR_FORM.submitButton);
|
||||
await click(GENERAL.submitButton);
|
||||
assert.ok(
|
||||
this.submitSpy.calledOnceWith({ key: 'this-is-the-key' }),
|
||||
'onSubmit called with correct params'
|
||||
);
|
||||
assert.dom(SHAMIR_FORM.input).hasValue('', 'key value reset after submit');
|
||||
assert.dom(GENERAL.inputByAttr('shamir-key')).hasValue('', 'key value reset after submit');
|
||||
|
||||
await render(hbs`
|
||||
<Shamir::Form @onSubmit={{this.submitSpy}} @progress={{0}} @threshold={{3}} @alwaysShowProgress={{true}} @buttonText="Do the thing" @inputLabel="Unseal key">
|
||||
@ -42,7 +43,7 @@ module('Integration | Component | shamir/form', function (hooks) {
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-block-content]').hasText('Hello', 'renders block content');
|
||||
assert.dom(SHAMIR_FORM.submitButton).hasText('Do the thing', 'uses passed button text');
|
||||
assert.dom(GENERAL.submitButton).hasText('Do the thing', 'uses passed button text');
|
||||
assert.dom(SHAMIR_FORM.inputLabel).hasText('Unseal key', 'uses passed inputLabel');
|
||||
assert.dom(SHAMIR_FORM.otpInfo).doesNotExist('no OTP info shown');
|
||||
assert
|
||||
@ -77,10 +78,10 @@ module('Integration | Component | shamir/form', function (hooks) {
|
||||
@errors={{this.errors}}
|
||||
/>
|
||||
`);
|
||||
assert.dom(SHAMIR_FORM.error).exists({ count: 2 }, 'renders errors');
|
||||
assert.dom(GENERAL.messageError).exists({ count: 2 }, 'renders errors');
|
||||
|
||||
this.set('errors', []);
|
||||
await settled();
|
||||
assert.dom(SHAMIR_FORM.error).doesNotExist('errors cleared');
|
||||
assert.dom(GENERAL.messageError).doesNotExist('errors cleared');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user