init: can do full login:
ooo muh gut Signed-off-by: HeshamTB <hishaminv@gmail.com>
This commit is contained in:
commit
9c1014ac72
5
internal/constants/common.go
Normal file
5
internal/constants/common.go
Normal file
@ -0,0 +1,5 @@
|
||||
package constants
|
||||
|
||||
const (
|
||||
CONTENT_TYPE_JSON = "application/json"
|
||||
)
|
10
internal/urls/common.go
Normal file
10
internal/urls/common.go
Normal file
@ -0,0 +1,10 @@
|
||||
package urls
|
||||
|
||||
const (
|
||||
URL_MYSTC_API_BASE = "https://mystc.stc.com.sa"
|
||||
PATH_API_AUTH_BASE = URL_MYSTC_API_BASE + "/api/mystc-api-authentication"
|
||||
PATH_PHONES_LIST = PATH_API_AUTH_BASE + "/phones-list"
|
||||
PATH_LOGIN = PATH_API_AUTH_BASE + "/login"
|
||||
PATH_LOGIN_VERIFICATION = PATH_API_AUTH_BASE + "/login-verification"
|
||||
)
|
||||
|
75
main.go
Normal file
75
main.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"mystcapi/pkg/endpoints"
|
||||
"mystcapi/pkg/models"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const URL_MYSTC_API_BASE = "https://mystc.stc.com.sa"
|
||||
const PATH_PHONES_LIST = "/api/mystc-api-authentication/phones-list"
|
||||
|
||||
func main() {
|
||||
|
||||
id := flag.String("id", "", "National ID or Iqama")
|
||||
pw := flag.String("password", "", "MySTC Password")
|
||||
flag.Parse()
|
||||
|
||||
phones, err := endpoints.GetPhonesList(*id, *pw)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
var selectedNumber models.PhoneNumber
|
||||
|
||||
mainloop:
|
||||
for {
|
||||
for idx, n := range phones.PhoneNumbers {
|
||||
fmt.Printf("%d: %s %s\n", idx, n.Number, n.Type.String())
|
||||
}
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
input = strings.Trim(input, "\n")
|
||||
for idx, n := range phones.PhoneNumbers {
|
||||
if input == fmt.Sprint(idx) {
|
||||
selectedNumber = n
|
||||
break mainloop
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fmt.Printf("selectedNumber: %v\n", selectedNumber)
|
||||
|
||||
loginOTP, err := endpoints.RequestLoginOTP(phones.LoginToken, selectedNumber.Number)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("OTP Sent!")
|
||||
fmt.Printf("loginOTP: %v\n", loginOTP)
|
||||
fmt.Print("Enter OTP: ")
|
||||
otp, err := reader.ReadString('\n')
|
||||
otp = strings.Trim(otp, "\n")
|
||||
|
||||
login, err := endpoints.VerifyLoginOTP(*id, loginOTP.OtpToken, otp)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Logged in!")
|
||||
fmt.Printf("login: %v\n", login)
|
||||
|
||||
|
||||
}
|
9
pkg/endpoints/common.go
Normal file
9
pkg/endpoints/common.go
Normal file
@ -0,0 +1,9 @@
|
||||
package endpoints
|
||||
|
||||
import "net/http"
|
||||
|
||||
var client *http.Client
|
||||
|
||||
func init() {
|
||||
client = &http.Client{}
|
||||
}
|
123
pkg/endpoints/login.go
Normal file
123
pkg/endpoints/login.go
Normal file
@ -0,0 +1,123 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mystcapi/internal/constants"
|
||||
"mystcapi/internal/urls"
|
||||
"mystcapi/pkg/models"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
func GetPhonesList(id, password string) (models.LoginPhoneListResponse, error) {
|
||||
|
||||
phoneList := models.LoginPhoneListResponse{}
|
||||
|
||||
reqJson, err := json.Marshal(models.LoginPhoneListRequest{
|
||||
Username: id,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
return phoneList, err
|
||||
}
|
||||
|
||||
resp, err := client.Post(
|
||||
urls.PATH_PHONES_LIST,
|
||||
constants.CONTENT_TYPE_JSON,
|
||||
bytes.NewReader(reqJson),
|
||||
)
|
||||
if err != nil {
|
||||
return phoneList, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return phoneList, fmt.Errorf("http: Login got %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return phoneList, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &phoneList)
|
||||
return phoneList, err
|
||||
}
|
||||
|
||||
func RequestLoginOTP(loginToken, phoneNumber string) (models.LoginResponse, error) {
|
||||
loginResp := models.LoginResponse{}
|
||||
|
||||
reqJson, err := json.Marshal(
|
||||
models.LoginRequest{
|
||||
LoginToken: loginToken,
|
||||
PhoneNumber: phoneNumber,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return loginResp, err
|
||||
}
|
||||
|
||||
resp, err := client.Post(
|
||||
urls.PATH_LOGIN,
|
||||
constants.CONTENT_TYPE_JSON,
|
||||
bytes.NewReader(reqJson),
|
||||
)
|
||||
if err != nil {
|
||||
return loginResp, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return loginResp, fmt.Errorf("http: RequestLoginOTP got %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return loginResp, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &loginResp)
|
||||
return loginResp, err
|
||||
}
|
||||
|
||||
func VerifyLoginOTP(
|
||||
username, otpToken,
|
||||
otp string) (models.LoginVerificationResponse, error) {
|
||||
loginVerResp := models.LoginVerificationResponse{}
|
||||
|
||||
reqJson, err := json.Marshal(
|
||||
models.LoginVerificationRequest{
|
||||
Username: username,
|
||||
OtpToken: otpToken,
|
||||
Otp: otp,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return loginVerResp, err
|
||||
}
|
||||
|
||||
resp, err := client.Post(
|
||||
urls.PATH_LOGIN_VERIFICATION,
|
||||
constants.CONTENT_TYPE_JSON,
|
||||
bytes.NewReader(reqJson),
|
||||
)
|
||||
if err != nil {
|
||||
return loginVerResp, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return loginVerResp, fmt.Errorf("http: RequestLoginOTP got %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return loginVerResp, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &loginVerResp)
|
||||
return loginVerResp, err
|
||||
}
|
||||
|
59
pkg/models/login.go
Normal file
59
pkg/models/login.go
Normal file
@ -0,0 +1,59 @@
|
||||
package models
|
||||
|
||||
type LoginPhoneListRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginPhoneListResponse struct {
|
||||
PhoneNumbers []PhoneNumber `json:"phoneNumbers"`
|
||||
LoginToken string `json:"loginToken"`
|
||||
}
|
||||
|
||||
type PhoneNumberType string
|
||||
var (
|
||||
POSTPAID PhoneNumberType = "1"
|
||||
PREPAID PhoneNumberType = "2"
|
||||
)
|
||||
|
||||
func (p PhoneNumberType) String() string {
|
||||
switch p {
|
||||
case "1":
|
||||
return "POSTPAID"
|
||||
case "2":
|
||||
return "PREPAID"
|
||||
default:
|
||||
return "UNKOWN"
|
||||
}
|
||||
}
|
||||
|
||||
type PhoneNumber struct {
|
||||
Number string `json:"number"`
|
||||
Type PhoneNumberType `json:"type"`
|
||||
Contact string `json:"contact"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
LoginToken string `json:"loginToken"`
|
||||
PhoneNumber string `json:"phoneNumber"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
OtpToken string `json:"otpToken"`
|
||||
ExpiresIn string `json:"expiresIn"`
|
||||
TokenType string `json:"tokenType"`
|
||||
}
|
||||
|
||||
type LoginVerificationRequest struct {
|
||||
Username string `json:"username"`
|
||||
OtpToken string `json:"otpToken"`
|
||||
Otp string `json:"otp"`
|
||||
}
|
||||
|
||||
type LoginVerificationResponse struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
TokenType string `json:"tokenType"`
|
||||
ExpiresIn string `json:"expiresIn"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user