mirror of https://github.com/daffainfo/nuclei.git
Use auth helpers from utils (#4620)
parent
5a430a31e5
commit
53207a0bb0
6
go.mod
6
go.mod
|
@ -90,14 +90,14 @@ require (
|
|||
github.com/projectdiscovery/sarif v0.0.1
|
||||
github.com/projectdiscovery/tlsx v1.1.6-0.20231116215000-e842dc367a74
|
||||
github.com/projectdiscovery/uncover v1.0.7
|
||||
github.com/projectdiscovery/utils v0.0.72
|
||||
github.com/projectdiscovery/utils v0.0.73-0.20240110205148-46f474b2947f
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.109
|
||||
github.com/redis/go-redis/v9 v9.1.0
|
||||
github.com/ropnop/gokrb5/v8 v8.0.0-20201111231119-729746023c02
|
||||
github.com/sashabaranov/go-openai v1.15.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706
|
||||
golang.org/x/term v0.15.0
|
||||
golang.org/x/term v0.16.0
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
@ -286,7 +286,7 @@ require (
|
|||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.15.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
|
12
go.sum
12
go.sum
|
@ -851,8 +851,8 @@ github.com/projectdiscovery/tlsx v1.1.6-0.20231116215000-e842dc367a74 h1:G0gw+3z
|
|||
github.com/projectdiscovery/tlsx v1.1.6-0.20231116215000-e842dc367a74/go.mod h1:YH8el7/6pyZbNed1IibjzbGpeigiCVyvE28g5+LsPAw=
|
||||
github.com/projectdiscovery/uncover v1.0.7 h1:ut+2lTuvmftmveqF5RTjMWAgyLj8ltPQC7siFy9sj0A=
|
||||
github.com/projectdiscovery/uncover v1.0.7/go.mod h1:HFXgm1sRPuoN0D4oATljPIdmbo/EEh1wVuxQqo/dwFE=
|
||||
github.com/projectdiscovery/utils v0.0.72 h1:sJ1lBcaWO6dJ65F+fVhSJbguhgWjixgy9mjj7jKBUW8=
|
||||
github.com/projectdiscovery/utils v0.0.72/go.mod h1:VPnijH51D8wB1VJiEujUp7UZ+TUTKN8PpoW82nivUVY=
|
||||
github.com/projectdiscovery/utils v0.0.73-0.20240110205148-46f474b2947f h1:gjp9RyGSh507ARIrUUBE0u13mMYPDWZxoZEOAneCT4E=
|
||||
github.com/projectdiscovery/utils v0.0.73-0.20240110205148-46f474b2947f/go.mod h1:B+4cyms2mQtG6KC2qaV5zEVJgyIWzjCwrgO+kpSR5SY=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.109 h1:BERfwTRn1dvB1tbhyc5m67R8VkC9zbVuPsEq4VEm07k=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.109/go.mod h1:4Z3DKhi75zIPMuA+qSDDWxZvnhL4qTLmDx4dxNMu7MA=
|
||||
github.com/projectdiscovery/yamldoc-go v1.0.4 h1:eZoESapnMw6WAHiVgRwNqvbJEfNHEH148uthhFbG5jE=
|
||||
|
@ -1348,8 +1348,8 @@ 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.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
@ -1361,8 +1361,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
|||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
// pdcp contains projectdiscovery cloud platform related features
|
||||
// like result upload , dashboard etc.
|
||||
package pdcp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
|
||||
"github.com/projectdiscovery/utils/env"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var (
|
||||
DashBoardURL = "https://cloud.projectdiscovery.io"
|
||||
DefaultApiServer = "https://api.projectdiscovery.io"
|
||||
)
|
||||
|
||||
// CheckNValidateCredentials checks if credentials exist on filesystem
|
||||
// if not waits for user to enter credentials and validates them
|
||||
// and saves them to filesystem
|
||||
// when validate is true any existing credentials are validated
|
||||
// Note: this is meant to be used in cli only (interactive mode)
|
||||
func CheckNValidateCredentials(toolName string) {
|
||||
h := &PDCPCredHandler{}
|
||||
creds, err := h.GetCreds()
|
||||
if err == nil {
|
||||
// validate by fetching user profile
|
||||
gotCreds, err := h.ValidateAPIKey(creds.APIKey, creds.Server, config.BinaryName)
|
||||
if err == nil {
|
||||
gologger.Info().Msgf("You are logged in as (@%v)", gotCreds.Username)
|
||||
os.Exit(0)
|
||||
}
|
||||
gologger.Error().Msgf("Invalid API key found in file, please recheck or recreate your API key and retry.")
|
||||
}
|
||||
if err != nil && err != ErrNoCreds {
|
||||
// this is unexpected error log it
|
||||
gologger.Error().Msgf("Could not read credentials from file: %s\n", err)
|
||||
}
|
||||
|
||||
// if we are here, we need to get credentials from user
|
||||
gologger.Info().Msgf("Get your free api key by signing up at %v", DashBoardURL)
|
||||
fmt.Printf("[*] Enter PDCP API Key (exit to abort): ")
|
||||
bin, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
gologger.Fatal().Msgf("Could not read input from terminal: %s\n", err)
|
||||
}
|
||||
apiKey := string(bin)
|
||||
if strings.EqualFold(apiKey, "exit") {
|
||||
os.Exit(0)
|
||||
}
|
||||
fmt.Println()
|
||||
// if env variable is set use that for validating api key
|
||||
apiServer := env.GetEnvOrDefault(apiServerEnv, DefaultApiServer)
|
||||
// validate by fetching user profile
|
||||
validatedCreds, err := h.ValidateAPIKey(apiKey, apiServer, toolName)
|
||||
if err == nil {
|
||||
gologger.Info().Msgf("Successfully logged in as (@%v)", validatedCreds.Username)
|
||||
if saveErr := h.SaveCreds(validatedCreds); saveErr != nil {
|
||||
gologger.Warning().Msgf("Could not save credentials to file: %s\n", saveErr)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
gologger.Error().Msgf("Invalid API key '%v' got error: %v", maskKey(apiKey), err)
|
||||
gologger.Fatal().Msgf("please recheck or recreate your API key and retry")
|
||||
}
|
||||
|
||||
func maskKey(key string) string {
|
||||
if len(key) < 6 {
|
||||
// this is invalid key
|
||||
return key
|
||||
}
|
||||
return fmt.Sprintf("%v%v", key[:3], strings.Repeat("*", len(key)-3))
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
package pdcp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/projectdiscovery/retryablehttp-go"
|
||||
"github.com/projectdiscovery/utils/env"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
folderutil "github.com/projectdiscovery/utils/folder"
|
||||
urlutil "github.com/projectdiscovery/utils/url"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
PDCPDir = filepath.Join(folderutil.HomeDirOrDefault(""), ".pdcp")
|
||||
PDCPCredFile = filepath.Join(PDCPDir, "credentials.yaml")
|
||||
ErrNoCreds = fmt.Errorf("no credentials found in %s", PDCPDir)
|
||||
)
|
||||
|
||||
const (
|
||||
userProfileURL = "https://%s/v1/user?utm_source=%s"
|
||||
apiKeyEnv = "PDCP_API_KEY"
|
||||
apiServerEnv = "PDCP_API_SERVER"
|
||||
ApiKeyHeaderName = "X-Api-Key"
|
||||
dashBoardEnv = "PDCP_DASHBOARD_URL"
|
||||
)
|
||||
|
||||
type PDCPCredentials struct {
|
||||
Username string `yaml:"username"`
|
||||
APIKey string `yaml:"api-key"`
|
||||
Server string `yaml:"server"`
|
||||
}
|
||||
|
||||
type PDCPUserProfileResponse struct {
|
||||
UserName string `json:"name"`
|
||||
// there are more fields but we don't need them
|
||||
/// below fields are added later on and not part of the response
|
||||
}
|
||||
|
||||
// PDCPCredHandler is interface for adding / retrieving pdcp credentials
|
||||
// from file system
|
||||
type PDCPCredHandler struct{}
|
||||
|
||||
// GetCreds retrieves the credentials from the file system or environment variables
|
||||
func (p *PDCPCredHandler) GetCreds() (*PDCPCredentials, error) {
|
||||
credsFromEnv := p.getCredsFromEnv()
|
||||
if credsFromEnv != nil {
|
||||
return credsFromEnv, nil
|
||||
}
|
||||
if !fileutil.FolderExists(PDCPDir) || !fileutil.FileExists(PDCPCredFile) {
|
||||
return nil, ErrNoCreds
|
||||
}
|
||||
bin, err := os.Open(PDCPCredFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// for future use-cases
|
||||
var creds []PDCPCredentials
|
||||
err = yaml.NewDecoder(bin).Decode(&creds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(creds) == 0 {
|
||||
return nil, ErrNoCreds
|
||||
}
|
||||
return &creds[0], nil
|
||||
}
|
||||
|
||||
// getCredsFromEnv retrieves the credentials from the environment
|
||||
// if not or incomplete credentials are found it return nil
|
||||
func (p *PDCPCredHandler) getCredsFromEnv() *PDCPCredentials {
|
||||
apiKey := env.GetEnvOrDefault(apiKeyEnv, "")
|
||||
apiServer := env.GetEnvOrDefault(apiServerEnv, "")
|
||||
if apiKey == "" || apiServer == "" {
|
||||
return nil
|
||||
}
|
||||
return &PDCPCredentials{APIKey: apiKey, Server: apiServer}
|
||||
}
|
||||
|
||||
// SaveCreds saves the credentials to the file system
|
||||
func (p *PDCPCredHandler) SaveCreds(resp *PDCPCredentials) error {
|
||||
if resp == nil {
|
||||
return fmt.Errorf("invalid response")
|
||||
}
|
||||
if !fileutil.FolderExists(PDCPDir) {
|
||||
_ = fileutil.CreateFolder(PDCPDir)
|
||||
}
|
||||
bin, err := yaml.Marshal([]*PDCPCredentials{resp})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(PDCPCredFile, bin, 0600)
|
||||
}
|
||||
|
||||
// ValidateAPIKey validates the api key and retrieves associated user metadata like username
|
||||
// from given api server/host
|
||||
func (p *PDCPCredHandler) ValidateAPIKey(key string, host string, toolName string) (*PDCPCredentials, error) {
|
||||
// get address from url
|
||||
urlx, err := urlutil.Parse(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := retryablehttp.NewRequest("GET", fmt.Sprintf(userProfileURL, urlx.Host, toolName), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set(ApiKeyHeaderName, key)
|
||||
resp, err := retryablehttp.DefaultHTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
_, _ = io.Copy(io.Discard, resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bin, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var profile PDCPUserProfileResponse
|
||||
err = json.Unmarshal(bin, &profile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if profile.UserName == "" {
|
||||
return nil, fmt.Errorf("invalid response from server got %v", string(bin))
|
||||
}
|
||||
return &PDCPCredentials{Username: profile.UserName, APIKey: key, Server: host}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
DashBoardURL = env.GetEnvOrDefault("PDCP_DASHBOARD_URL", DashBoardURL)
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package pdcp
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var exampleCred = `
|
||||
- username: test
|
||||
api-key: testpassword
|
||||
server: https://scanme.sh
|
||||
`
|
||||
|
||||
func TestLoadCreds(t *testing.T) {
|
||||
// temporarily change PDCP file location for testing
|
||||
f, err := os.CreateTemp("", "creds-test-*")
|
||||
require.Nil(t, err)
|
||||
_, _ = f.WriteString(strings.TrimSpace(exampleCred))
|
||||
defer os.Remove(f.Name())
|
||||
PDCPCredFile = f.Name()
|
||||
PDCPDir = filepath.Dir(f.Name())
|
||||
h := &PDCPCredHandler{}
|
||||
value, err := h.GetCreds()
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, value)
|
||||
require.Equal(t, "test", value.Username)
|
||||
require.Equal(t, "testpassword", value.APIKey)
|
||||
require.Equal(t, "https://scanme.sh", value.Server)
|
||||
}
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
||||
"github.com/projectdiscovery/retryablehttp-go"
|
||||
pdcpauth "github.com/projectdiscovery/utils/auth/pdcp"
|
||||
errorutil "github.com/projectdiscovery/utils/errors"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
folderutil "github.com/projectdiscovery/utils/folder"
|
||||
|
@ -32,14 +33,14 @@ var _ output.Writer = &UploadWriter{}
|
|||
// server to enable web dashboard and more
|
||||
type UploadWriter struct {
|
||||
*output.StandardWriter
|
||||
creds *PDCPCredentials
|
||||
creds *pdcpauth.PDCPCredentials
|
||||
tempFile *os.File
|
||||
done atomic.Bool
|
||||
uploadURL *url.URL
|
||||
}
|
||||
|
||||
// NewUploadWriter creates a new upload writer
|
||||
func NewUploadWriter(creds *PDCPCredentials) (*UploadWriter, error) {
|
||||
func NewUploadWriter(creds *pdcpauth.PDCPCredentials) (*UploadWriter, error) {
|
||||
if creds == nil {
|
||||
return nil, fmt.Errorf("no credentials provided")
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ func (u *UploadWriter) upload() (string, error) {
|
|||
if err != nil {
|
||||
return "", errorutil.NewWithErr(err).Msgf("could not create cloud upload request")
|
||||
}
|
||||
req.Header.Set(ApiKeyHeaderName, u.creds.APIKey)
|
||||
req.Header.Set(pdcpauth.ApiKeyHeaderName, u.creds.APIKey)
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
|
@ -149,7 +150,7 @@ func (u *UploadWriter) Close() {
|
|||
}
|
||||
|
||||
func getScanDashBoardURL(id string) string {
|
||||
ux, _ := urlutil.Parse(DashBoardURL)
|
||||
ux, _ := urlutil.Parse(pdcpauth.DashBoardURL)
|
||||
ux.Path = "/scans/" + id
|
||||
ux.Update()
|
||||
return ux.String()
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v3/internal/pdcp"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
|
||||
pdcpauth "github.com/projectdiscovery/utils/auth/pdcp"
|
||||
updateutils "github.com/projectdiscovery/utils/update"
|
||||
)
|
||||
|
||||
|
@ -33,5 +33,5 @@ func NucleiToolUpdateCallback() {
|
|||
// AuthWithPDCP is used to authenticate with PDCP
|
||||
func AuthWithPDCP() {
|
||||
showBanner()
|
||||
pdcp.CheckNValidateCredentials(config.BinaryName)
|
||||
pdcpauth.CheckNValidateCredentials(config.BinaryName)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v3/internal/pdcp"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/installer"
|
||||
uncoverlib "github.com/projectdiscovery/uncover"
|
||||
pdcpauth "github.com/projectdiscovery/utils/auth/pdcp"
|
||||
"github.com/projectdiscovery/utils/env"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
permissionutil "github.com/projectdiscovery/utils/permission"
|
||||
|
@ -351,18 +352,18 @@ func (r *Runner) setupPDCPUpload(writer output.Writer) output.Writer {
|
|||
return writer
|
||||
}
|
||||
color := aurora.NewAurora(!r.options.NoColor)
|
||||
h := &pdcp.PDCPCredHandler{}
|
||||
h := &pdcpauth.PDCPCredHandler{}
|
||||
creds, err := h.GetCreds()
|
||||
if err != nil {
|
||||
if err != pdcp.ErrNoCreds && !HideAutoSaveMsg {
|
||||
if err != pdcpauth.ErrNoCreds && !HideAutoSaveMsg {
|
||||
gologger.Verbose().Msgf("Could not get credentials for cloud upload: %s\n", err)
|
||||
}
|
||||
r.pdcpUploadErrMsg = fmt.Sprintf("[%v] To view results on Cloud Dashboard, Configure API key from %v", color.BrightYellow("WRN"), pdcp.DashBoardURL)
|
||||
r.pdcpUploadErrMsg = fmt.Sprintf("[%v] To view results on Cloud Dashboard, Configure API key from %v", color.BrightYellow("WRN"), pdcpauth.DashBoardURL)
|
||||
return writer
|
||||
}
|
||||
uploadWriter, err := pdcp.NewUploadWriter(creds)
|
||||
if err != nil {
|
||||
r.pdcpUploadErrMsg = fmt.Sprintf("[%v] PDCP (%v) Auto-Save Failed: %s\n", color.BrightYellow("WRN"), pdcp.DashBoardURL, err)
|
||||
r.pdcpUploadErrMsg = fmt.Sprintf("[%v] PDCP (%v) Auto-Save Failed: %s\n", color.BrightYellow("WRN"), pdcpauth.DashBoardURL, err)
|
||||
return writer
|
||||
}
|
||||
return output.NewMultiWriter(writer, uploadWriter)
|
||||
|
@ -592,7 +593,7 @@ func (r *Runner) displayExecutionInfo(store *loader.Store) {
|
|||
if r.pdcpUploadErrMsg != "" {
|
||||
gologger.Print().Msgf("%s", r.pdcpUploadErrMsg)
|
||||
} else {
|
||||
gologger.Info().Msgf("To view results on cloud dashboard, visit %v/scans upon scan completion.", pdcp.DashBoardURL)
|
||||
gologger.Info().Msgf("To view results on cloud dashboard, visit %v/scans upon scan completion.", pdcpauth.DashBoardURL)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue