commit 510c3d7bcc75ee7fdc3dd1035cc9ba8e44af8a2b Author: enigmaquip Date: Thu Feb 14 09:39:45 2019 -0700 Initial Commit diff --git a/account-management.exe b/account-management.exe new file mode 100644 index 0000000..aa7ee88 Binary files /dev/null and b/account-management.exe differ diff --git a/amazon-api.json b/amazon-api.json new file mode 100644 index 0000000..fa65483 --- /dev/null +++ b/amazon-api.json @@ -0,0 +1,62 @@ +{ + "api_payload": { + "auth_data": { + "use_global_authentication": "true", + "user_id_password": { + "user_id": "email", + "password": "password" + } + }, + "registration_data": { + "domain": "Device", + "device_type": "A1MPSLFC7L5AFK", + "device_serial": "94908c6a28ff4aa191ef6dc9f3d7a5fe", + "app_name": "com.amazon.rabbit", + "app_version": "303558483", + "device_model": "A0001", + "os_version": "oneplus\/bacon\/A0001:6.0.1\/MHC19Q\/ZNH2KAS1KN:user\/release-keys", + "software_version": "130050002" + }, + "requested_token_type": [ + "bearer", + "mac_dms", + "store_authentication_cookie", + "website_cookies" + ], + "cookies": { + "domain": "amazon.com", + "website_cookies": [] + }, + "user_context_map": { + "frc": "AAaX8sTizWltIgbmD8Dlozbdss3Evn2UXP1OZ9jsqgmXa0fzhs6KH1FfP2mVf6kRsWz2LrxvfAIRbqWJMLNt8YAgxaz524w+voVxKvhjUKfi+LTfL+fGv\/HqJSUn76flmj1hvWzGrRkmSxOmb2uA2VVuMlVwZeCAbvoDTXrBvPLbMUNDL6Ydqf7qz\/Pv4jvFNOS5dRhvwfdt8iuYec8W1iXB\/UwLMCSnJqXMzEh0yhHnBIhZpsWzmwBORJ9ePySqtooYl7F9h6BJhhcDfMWVgaN7Y4Tb926j+1a6auCoGW5o3rei1lUlSwrIokENDEhg+NpJtCfm+7IYrsyVUYplGZQtrwOPukW0109+xBxTY5iGsn\/Je1NThQa7\/H6CQ7xth1mEaAiQNASBj18Iknij7cZ3MOWBp88orQ==" + }, + "device_metadata": { + "device_os_family": "android", + "device_type": "A1MPSLFC7L5AFK", + "device_serial": "94908c6a28ff4aa191ef6dc9f3d7a5fe", + "mac_address": "C248C629AF1FE0A8C46B95668064C1D2952A9E91D207BC0CC3C5D584C2F7553A", + "imei": "31C64C373E1BCA0EBE4C1916A7BBCDD39FAA98557290DF38B6748F3863C6D256", + "manufacturer": "OnePlus", + "model": "A0001", + "os_version": "23", + "android_id": "c3510a10140e5b33", + "build_serial": "16f68f70", + "product": "bacon" + }, + "requested_extensions": [ + "device_info", + "customer_info" + ] + }, + "headers": { + "login": "Dalvik\/2.1.0 (Linux; U; Android 6.0.1 Build\/MOI10E)", + "refresh": "AmazonWebView\/MAPClientLib\/130050002\/Android\/6.0.1\/A0001", + "main": "Dalvik\/2.1.0 (Linux; U; Android 6.0.1 Build\/MOI10E) RabbitAndroid\/3.7.33.0", + "app_instance": "d266005d-1ff8-4097-9499-152bc756c0d5", + "map_version": { + "current_version": "20180807N", + "package_name": "com.amazon.rabbit", + "platform": "Android" + } + } +} \ No newline at end of file diff --git a/auth_header.go b/auth_header.go new file mode 100644 index 0000000..d9f1587 --- /dev/null +++ b/auth_header.go @@ -0,0 +1,105 @@ +package main + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "net/http" + "strconv" + "strings" + "time" + "unicode/utf8" + + "github.com/google/uuid" +) + +type FlexHeader struct { + UserAgent string `header:"User-Agent"` + Host string `header:"Host"` + Connection string `header:"Connection"` + Encoding string `header:"Accept-Encoding"` + ContentType string `header:"Content-Type"` + RequestId string `header:"X-Amzn-RequestId"` + ClientTime string `header:"X-Flex-Client-Time"` + Instance string `header:"x-flex-instance-id"` + AccessToken string `header:"x-amz-access-token"` + Authorization string `header:"Authorization,omitempty"` + Date string `header:"X-Amz-Date,omitempty"` +} + +var ( + FlexHead = new(FlexHeader) + FlexClient = &http.Client{} +) + +func (h *FlexHeader) Setup() { + h.UserAgent = api.Headers.Main + h.Connection = "Keep-Alive" + h.Encoding = "gzip" + h.ContentType = "application/json" + h.Host = "flex-capacity-na.amazon.com" + h.Instance = api.Headers.Instance + h.AccessToken = bearer.Tokens.Bearer.AccessToken +} + +func (h *FlexHeader) Auth(method string, path string, host string) (head http.Header) { + h.Host = host + uuid, _ := uuid.NewRandom() + h.RequestId = uuid.String() + timenow := time.Now() + h.ClientTime = strconv.FormatInt(timenow.UnixNano()/1000000, 10) + h.Date = timenow.Format("20060102T150405Z") + filteredHeaders := []string{"Host", "x-amz-access-token", "X-Amz-Date", "X-Amzn-RequestId"} + canonicalRequestB := strings.ToLower(strings.Join(filteredHeaders, ";")) + keylist := make([]string, len(filteredHeaders)) + for pos, hkey := range filteredHeaders { + switch hkey { + case "Host": + keylist[pos] = fmt.Sprintf("%s:%s\n", "host", h.Host) + case "x-amz-access-token": + keylist[pos] = fmt.Sprintf("%s:%s\n", "x-amz-access-token", h.AccessToken) + case "X-Amz-Date": + keylist[pos] = fmt.Sprintf("%s:%s\n", "x-amz-date", h.Date) + case "X-Amzn-RequestId": + keylist[pos] = fmt.Sprintf("%s:%s\n", "x-amzn-requestid", h.RequestId) + } + } + canonicalRequestA := strings.Join([]string{method, path, strings.Join(keylist, ""), canonicalRequestB}, "\n") + canhash := sha256.New() + canhash.Write([]byte(canonicalRequestA)) + stringToSign := strings.Join([]string{"RABBIT3-HMAC-SHA256", h.Date, hex.EncodeToString(canhash.Sum(nil))}, "\n") + key := []byte("RABBIT" + Reverse(h.AccessToken)) + msgs := [3]string{h.Date[:8], "rabbit_request", stringToSign} + for _, msg := range msgs { + hash := hmac.New(sha256.New, key) + hash.Write([]byte(msg)) + key = hash.Sum(nil) + } + h.Authorization = "RABBIT3-HMAC-SHA256 SignedHeaders=" + canonicalRequestB + ",Signature=" + hex.EncodeToString(key) + head = http.Header{ + "Authorization": []string{h.Authorization}, + "User-Agent": []string{h.UserAgent}, + "Host": []string{h.Host}, + "Connection": []string{h.Connection}, + "Accept-Encoding": []string{h.Encoding}, + "Content-Type": []string{h.ContentType}, + "X-Amzn-RequestId": []string{h.RequestId}, + "X-Flex-Client-Time": []string{h.ClientTime}, + "x-flex-instance-id": []string{h.Instance}, + "x-amz-access-token": []string{h.AccessToken}, + "X-Amz-Date": []string{h.Date}, + } + return +} + +func Reverse(s string) string { + size := len(s) + buf := make([]byte, size) + for start := 0; start < size; { + r, n := utf8.DecodeRuneInString(s[start:]) + start += n + utf8.EncodeRune(buf[size-start:], r) + } + return string(buf) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..3081980 --- /dev/null +++ b/main.go @@ -0,0 +1,302 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "sort" + + "github.com/AlecAivazis/survey" +) + +type Region struct { + RegionID string `json:"regionID"` + BasicServiceAreas []ServiceArea `json:"basicServiceAreas"` + RegionName string `json:"regionName"` + Active bool `json:"active"` +} + +type ServiceArea struct { + ServiceAreaID string `json:"serviceAreaID"` + Operational bool `json:"operational"` + OnboardingEnabled bool `json:"onboardingEnabled"` + DefaultStationCode string `json:"defaultStationCode"` + AvailableOMWPrograms []string `json:"availableOMWPrograms"` + DefaultAccessPointID string `json:"defaultAccessPointId"` + ProgramTypes []string `json:"programTypes"` + CountryCode string `json:"countryCode"` + PickUpLocationAddress struct { + CountryCode string `json:"countryCode"` + PostalCode string `json:"postalCode"` + City string `json:"city"` + Phone interface{} `json:"phone"` + State string `json:"state"` + Address3 interface{} `json:"address3"` + Address2 interface{} `json:"address2"` + Address1 string `json:"address1"` + Name string `json:"name"` + } `json:"pickUpLocationAddress"` + OperatingEntity string `json:"operatingEntity"` + TimeZone string `json:"timeZone"` + PickUpLocation struct { + Longitude float64 `json:"longitude"` + Latitude float64 `json:"latitude"` + } `json:"pickUpLocation"` + ServiceAreaName string `json:"serviceAreaName"` +} + +type PersonalInfo struct { + Address string `json:"address"` + Address2 string `json:"address2"` + Fname string `json:"firstName"` + Lname string `json:"lastName"` + City string `json:"city"` + State string `json:"state"` + Zip string `json:"postalCode"` + Phone string `json:"phoneNumber"` + County string `json:"county"` + Country string `json:"countryCode"` +} + +func main() { + fmt.Println("First we need to log into our account before we can continue") + loginq := []*survey.Question{ + { + Name: "email", + Prompt: &survey.Input{Message: "Email:"}, + }, + { + Name: "password", + Prompt: &survey.Password{Message: "Password:"}, + }, + } + logina := struct { + Email string + Password string + }{} + survey.Ask(loginq, &logina) + api_file, err := os.Open("amazon-api.json") + defer api_file.Close() + if err != nil { + fmt.Println("Required files are missing, are you sure you have permission to run this?") + return + } + json.NewDecoder(api_file).Decode(&api) + api.Payload.AuthData.User.UserId = logina.Email + api.Payload.AuthData.User.Password = logina.Password + login() + log_cookies() + choicea := "" + choiceq := &survey.Select{ + Message: "Choose an option:", + Options: []string{"Region/Warehouse", "Personal Info"}, + } + survey.AskOne(choiceq, &choicea, nil) + switch choicea { + case "Region/Warehouse": + location() + case "Personal Info": + personal() + } +} + +func location() { + var regions []Region + resp, err := http.Get("https://logistics.amazon.com/flex/api/getOperationalRegions") + if err != nil { + fmt.Println(err.Error()) + } + json.NewDecoder(resp.Body).Decode(®ions) + var region_list []string + for _, reg := range regions { + region_list = append(region_list, reg.RegionName) + } + sort.Strings(region_list) + rega := "" + regq := &survey.Select{ + Message: "Choose Region:", + Options: region_list, + } + survey.AskOne(regq, ®a, nil) + var services []ServiceArea + var regionid string + for _, reg := range regions { + if reg.RegionName == rega { + regionid = reg.RegionID + services = reg.BasicServiceAreas + break + } + } + var wh_list []string + for _, wh := range services { + for _, prog := range wh.AvailableOMWPrograms { + if prog == "CSP" { + wh_list = append(wh_list, wh.ServiceAreaName) + break + } + } + } + sort.Strings(wh_list) + wha := "" + whq := &survey.Select{ + Message: "Choose Warehouse:", + Options: wh_list, + } + survey.AskOne(whq, &wha, nil) + var serviceareaid string + for _, wh := range services { + if wh.ServiceAreaName == wha { + serviceareaid = wh.ServiceAreaID + break + } + } + fmt.Printf("Region: %s\nWarehouse: %s\n", regionid, serviceareaid) + reg_body := struct { + Region string `json:"regionId"` + }{regionid} + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(reg_body) + reg_req, _ := http.NewRequest("POST", "https://logistics.amazon.com/onboarding/data/update-region", b) + reg_req.Header.Add("User-Agent", api.Headers.Refresh) + reg_req.Header.Add("X-Requested-With", "com.amazon.rabbit") + reg_req.Header.Add("Content-Type", "application/json;charset=UTF-8") + for _, one := range logistics.Response.Tokens.Cookies.AmazonCom { + reg_req.Header.Add("Cookie", fmt.Sprintf("%s=%s", one.Name, one.Value)) + } + client := &http.Client{} + reg_resp, _ := client.Do(reg_req) + defer reg_resp.Body.Close() + var body struct { + Success bool `json:"success"` + DirectTo string `json:"directTo"` + Error string `json:"errorReasonCode"` + Data string `json:"data"` + } + json.NewDecoder(reg_resp.Body).Decode(&body) + if body.Success { + fmt.Println("Region Successfully Changed") + } else { + fmt.Println("Region Change Failed", reg_resp.StatusCode, body.Error) + } + FlexHead.Setup() + wh_body := struct { + Type string `json:"__type"` + Service []string `json:"serviceAreaIds"` + }{"SetEligibleServiceAreasInput:http://internal.amazon.com/coral/com.amazon.omwbuseyservice/", []string{serviceareaid}} + wh_b := new(bytes.Buffer) + json.NewEncoder(wh_b).Encode(wh_body) + wh_req, _ := http.NewRequest("POST", "https://flex-capacity-na.amazon.com/eligibleServiceAreas", wh_b) + wh_req.Header = FlexHead.Auth(wh_req.Method, wh_req.URL.Path, wh_req.Host) + wh_resp, _ := client.Do(wh_req) + defer wh_resp.Body.Close() + if wh_resp.StatusCode == 200 { + fmt.Println("Warehouse Successfully Changed") + } else { + fmt.Println("Warehouse Change Failed") + } + io.Copy(ioutil.Discard, wh_resp.Body) +} + +func personal() { + fmt.Println("Changing User Info May Trigger a Tax Info Update") + var body_response struct { + Success bool `json:"success"` + DirectTo string `json:"directTo"` + Error string `json:"errorReasonCode"` + Data PersonalInfo `json:"data"` + } + get_req, _ := http.NewRequest("GET", "https://logistics.amazon.com/onboarding/account/data/get-personal-info", nil) + get_req.Header.Add("User-Agent", api.Headers.Refresh) + get_req.Header.Add("X-Requested-With", "com.amazon.rabbit") + get_req.Header.Add("Content-Type", "application/json;charset=UTF-8") + for _, one := range logistics.Response.Tokens.Cookies.AmazonCom { + get_req.Header.Add("Cookie", fmt.Sprintf("%s=%s", one.Name, one.Value)) + } + client := &http.Client{} + get_resp, _ := client.Do(get_req) + defer get_resp.Body.Close() + json.NewDecoder(get_resp.Body).Decode(&body_response) + infoq := []*survey.Question{ + { + Name: "fname", + Prompt: &survey.Input{Message: "First Name:", + Default: body_response.Data.Fname, + }, + }, + { + Name: "lname", + Prompt: &survey.Input{Message: "Last Name:", + Default: body_response.Data.Lname, + }, + }, + { + Name: "address", + Prompt: &survey.Input{Message: "Address:", + Default: body_response.Data.Address, + }, + }, + { + Name: "address2", + Prompt: &survey.Input{Message: "Address2:", + Default: body_response.Data.Address2, + }, + }, + { + Name: "city", + Prompt: &survey.Input{Message: "City:", + Default: body_response.Data.City, + }, + }, + { + Name: "state", + Prompt: &survey.Input{Message: "State:", + Default: body_response.Data.State, + }, + }, + { + Name: "zip", + Prompt: &survey.Input{Message: "Zip:", + Default: body_response.Data.Zip, + }, + }, + { + Name: "county", + Prompt: &survey.Input{Message: "County:", + Default: body_response.Data.County, + }, + }, + { + Name: "country", + Prompt: &survey.Input{Message: "Country:", + Default: body_response.Data.Country, + }, + }, + { + Name: "phone", + Prompt: &survey.Input{Message: "Phone Number:", + Default: body_response.Data.Phone, + }, + }, + } + var infoa PersonalInfo + survey.Ask(infoq, &infoa) + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(infoa) + set_req, _ := http.NewRequest("POST", "https://logistics.amazon.com/onboarding/account/data/submit-personal-info", b) + set_req.Header.Add("User-Agent", api.Headers.Refresh) + set_req.Header.Add("X-Requested-With", "com.amazon.rabbit") + set_req.Header.Add("Content-Type", "application/json;charset=UTF-8") + for _, one := range logistics.Response.Tokens.Cookies.AmazonCom { + set_req.Header.Add("Cookie", fmt.Sprintf("%s=%s", one.Name, one.Value)) + } + set_resp, _ := client.Do(set_req) + defer set_resp.Body.Close() + json.NewDecoder(set_resp.Body).Decode(&body_response) + if body_response.Success { + fmt.Println("Info Successfully Updated") + } +} diff --git a/token.go b/token.go new file mode 100644 index 0000000..c21388f --- /dev/null +++ b/token.go @@ -0,0 +1,291 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/cookiejar" + "net/url" + "os" + "regexp" + "strings" + + "github.com/google/uuid" +) + +type AmazonBearer struct { + CustomerId string `json:"customer_id"` + Extensions struct { + DeviceInfo struct { + DeviceSN string `json:"device_serial_number"` + DeviceType string `json:"device_type"` + DeviceName string `json:"device_name"` + } `json:"device_info"` + CustomerInfo struct { + Name string `json:"name"` + HomeRegion string `json:"home_region"` + AccountPool string `json:"account_pool"` + GivenName string `json:"given_name"` + UserId string `json:"user_id"` + } `json:"customer_info"` + } `json:"extensions"` + Tokens struct { + MacDMS struct { + ADPToken string `json:"adp_token"` + DevicePrivateKey string `json:"device_private_key"` + } `json:"mac_dms"` + StoreAuthCookie struct { + Cookie string `json:"cookie"` + } `json:"store_authentication_cookie"` + Bearer struct { + AccessToken string `json:"access_token"` + ExpiresIn string `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + } `json:"bearer"` + } `json:"tokens"` +} + +type AmazonApi struct { + Payload struct { + AuthData struct { + Global string `json:"use_global_authentication"` + User struct { + UserId string `json:"user_id"` + Password string `json:"password"` + } `json:"user_id_password"` + AccessToken string `json:"access_token,omitempty"` + } `json:"auth_data"` + RegistrationData struct { + Domain string `json:"domain"` + Type string `json:"device_type"` + Serial string `json:"device_serial"` + AppName string `json:"app_name"` + AppVersion string `json:"app_version"` + Model string `json:"device_model"` + OSVersion string `json:"os_version"` + SoftwareVersion string `json:"software_version"` + } `json:"registration_data"` + RequestedToken []string `json:"requested_token_type"` + Cookies struct { + Domain string `json:"domain"` + Website []string `json:"website_cookies"` + } `json:"cookies"` + UserContext struct { + Frc string `json:"frc"` + } `json:"user_context_map"` + DeviceMetadata DeviceMetadata `json:"device_metadata"` + Extenstions []string `json:"requested_extensions"` + } `json:"api_payload"` + Headers struct { + Login string `json:"login"` + Refresh string `json:"refresh"` + Main string `json:"main"` + Instance string `json:"app_instance"` + MapVersion MapVersion `json:"map_version"` + } `json:"headers"` +} +type DeviceMetadata struct { + DeviceOS string `json:"device_os_family"` + DeviceType string `json:"device_type"` + DeviceSerial string `json:"device_serial"` + MacAddress string `json:"mac_address"` + IMEI string `json:"imei"` + Manufacturer string `json:"manufacturer"` + Model string `json:"model"` + OSVersion string `json:"os_version"` + AndroidID string `json:"android_id"` + BuildSerial string `json:"build_serial"` + Product string `json:"product"` +} +type MapVersion struct { + Version string `json:"current_version"` + Package string `json:"package_name"` + Platform string `json:"platform"` +} +type RefreshPayload struct { + AppName string `json:"app_name"` + AppVersion string `json:"app_version"` + SourceType string `json:"source_token_type"` + Token string `json:"source_token"` + RequestedType string `json:"requested_token_type"` + MetaData DeviceMetadata `json:"device_metadata"` + MapVersion MapVersion `json:"map_version"` +} + +type LoginResponse struct { + Response struct { + Success *AmazonBearer `json:"success"` + Challenge *struct { + Reason string `json:"challenge_reason"` + URI string `json:"uri"` + Method string `json:"required_authentication_method"` + Context string `json:"challenge_context"` + } `json:"challenge"` + } `json:"response"` +} + +type CookiesResponse struct { + Response struct { + Tokens struct { + Cookies struct { + AmazonCom []struct { + Path string `json:"Path"` + Secure bool `json:"Secure"` + Value string `json:"Value"` + Expires string `json:"Expires"` + HTTPOnly bool `json:"HttpOnly"` + Name string `json:"Name"` + } `json:".amazon.com"` + } `json:"cookies"` + } `json:"tokens"` + URI string `json:"uri"` + } `json:"response"` + RequestID string `json:"request_id"` +} + +var ( + api AmazonApi + bearer AmazonBearer + logistics CookiesResponse +) + +func login() { + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(api.Payload) + client := &http.Client{} + req, _ := http.NewRequest("POST", "https://api.amazon.com/auth/register", b) + uuid, _ := uuid.NewRandom() + req.Header.Add("X-Amzn-RequestId", uuid.String()) + req.Header.Add("x-amzn-identity-auth-domain", ".amazon.com") + req.Header.Add("User-Agent", api.Headers.Login) + req.Header.Add("Content-Type", "application/json") + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + } + var response LoginResponse + defer resp.Body.Close() + json.NewDecoder(resp.Body).Decode(&response) + if response.Response.Success != nil { + bearer = *response.Response.Success + fmt.Println("Login Succeeded for Device: " + bearer.Extensions.DeviceInfo.DeviceName) + } else if response.Response.Challenge != nil { + scanner := bufio.NewScanner(os.Stdin) + cookieJar, _ := cookiejar.New(nil) + client2 := &http.Client{Jar: cookieJar} + uri, _ := url.Parse(response.Response.Challenge.URI) + data := uri.Query() + data.Add("openid.pape.max_auth_age", "0") + data.Add("openid.identity", "http://specs.openid.net/auth/2.0/identifier_select") + data.Add("accountStatusPolicy", "P1") + data.Add("language", "en_US") + data.Add("openid.return_to", "https://www.amazon.com/ap/maplanding") + data.Add("openid.assoc_handle", "amzn_device_na") + data.Add("openid.oa2.response_type", "token") + data.Add("openid.mode", "checkid_setup") + data.Add("openid.ns.pape", "http://specs.openid.net/extensions/pape/1.0") + data.Add("openid.ns.oa2", "http://www.amazon.com/ap/ext/oauth/2") + data.Add("openid.oa2.scope", "device_auth_access") + data.Add("openid.claimed_id", "http://specs.openid.net/auth/2.0/identifier_select") + data.Add("openid.oa2.client_id", "device:"+api.Payload.RegistrationData.Serial) + data.Add("disableLoginPrepopulate", "0") + data.Add("openid.ns", "http://specs.openid.net/auth/2.0") + uri.RawQuery = data.Encode() + req2, _ := http.NewRequest("GET", uri.String(), nil) + req2.Header.Add("x-amzn-identity-auth-domain", ".amazon.com") + req2.Header.Add("User-Agent", api.Headers.Login) + resp2, err := client2.Do(req2) + if err != nil { + fmt.Println(err) + } + referer := resp2.Request.URL.String() + fmt.Println(referer) + defer resp2.Body.Close() + body, err := ioutil.ReadAll(resp2.Body) + if err != nil { + fmt.Println(err) + } + if response.Response.Challenge.Reason == "MissingRequiredAuthenticationData" { + if response.Response.Challenge.Method == "OTPCode" { + client3 := &http.Client{Jar: cookieJar, CheckRedirect: func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }} + fmt.Println("Account set for 2 Factor Authentication") + fmt.Print("Enter One Time Code: ") + scanner.Scan() + otp := scanner.Text() + re := regexp.MustCompile(`