diff --git a/.github/workflows/release-tests.yaml b/.github/workflows/release-tests.yaml index 3189179f..3cbd44f0 100644 --- a/.github/workflows/release-tests.yaml +++ b/.github/workflows/release-tests.yaml @@ -27,7 +27,7 @@ jobs: uses: goreleaser/goreleaser-action@v1 with: version: latest - args: release --snapshot --skip-publish --skip-sign + args: release --snapshot --skip=publish,sign env: GOPATH: ${{ runner.workspace }} - uses: actions/upload-artifact@master diff --git a/.goreleaser.yml b/.goreleaser.yml index efbb708f..b35ea796 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: doppler before: diff --git a/Makefile b/Makefile index dbd20d6b..9fd6a9fc 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ test-packages: ./tests/packages.sh test-release: - doppler run -- goreleaser release --snapshot --skip-publish --clean --parallelism=4 + doppler run -- goreleaser release --snapshot --skip publish --clean --parallelism=4 scan: if [ ! -f "$$GOPATH/bin/gosec" ]; then echo "Error: gosec is not installed\n\nYou can install gosec with 'go get github.com/securego/gosec/cmd/gosec'\n" && exit 1; fi diff --git a/pkg/cmd/mfa.go b/pkg/cmd/mfa.go new file mode 100644 index 00000000..cbbdc69c --- /dev/null +++ b/pkg/cmd/mfa.go @@ -0,0 +1,66 @@ +/* +Copyright © 2023 Doppler + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "github.com/DopplerHQ/cli/pkg/configuration" + "github.com/DopplerHQ/cli/pkg/http" + "github.com/DopplerHQ/cli/pkg/utils" + "github.com/spf13/cobra" +) + +var mfaCommand = &cobra.Command{ + Use: "mfa", + Short: "Account MFA commands", + Args: cobra.NoArgs, +} + +var mfaRecoveryCmd = &cobra.Command{ + Use: "recovery", + Short: "Initiate an MFA recovery", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + yes := utils.GetBoolFlag(cmd, "yes") + localConfig := configuration.LocalConfig(cmd) + + utils.RequireValue("token", localConfig.Token.Value) + + if !yes { + utils.Print("MFA recovery allows you to use the Doppler CLI to generate a short-lived, one-time recovery code to log into the Doppler dashboard.") + utils.Print("The code will be sent to your email address.") + } + + confirmed := yes || utils.ConfirmationPrompt("Initiate MFA recovery", false) + if !confirmed { + return + } + + err := http.InitiateMfaRecovery(localConfig.APIHost.Value, utils.GetBool(localConfig.VerifyTLS.Value, true), localConfig.Token.Value) + if !err.IsNil() { + utils.HandleError(err.Unwrap(), err.Message) + } + + utils.Print("A one-time recovery code has been sent to your email address.") + }, +} + +func init() { + mfaRecoveryCmd.Flags().BoolP("yes", "y", false, "proceed without confirmation") + + mfaCommand.AddCommand(mfaRecoveryCmd) + + rootCmd.AddCommand(mfaCommand) +} diff --git a/pkg/http/api.go b/pkg/http/api.go index 79fa7798..99128026 100644 --- a/pkg/http/api.go +++ b/pkg/http/api.go @@ -1384,3 +1384,17 @@ func GetActorInfo(host string, verifyTLS bool, apiKey string) (models.ActorInfo, return info, Error{} } + +func InitiateMfaRecovery(host string, verifyTLS bool, apiKey string) Error { + url, err := generateURL(host, "/v3/me/mfa_recovery", nil) + if err != nil { + return Error{Err: err, Message: "Unable to generate url"} + } + + statusCode, _, _, err := PostRequest(url, verifyTLS, apiKeyHeader(apiKey), nil) + if err != nil { + return Error{Err: err, Message: "Unable to initiate MFA recovery", Code: statusCode} + } + + return Error{} +}