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