-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjcliLoad.go
More file actions
158 lines (131 loc) · 3.11 KB
/
jcliLoad.go
File metadata and controls
158 lines (131 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"os"
"strings"
"time"
)
type TokenData struct {
Header map[string]interface{}
Claims map[string]interface{}
Signature string
}
type TokenParseResult struct {
Data *TokenData
Errored bool
Error string
}
func loadToken() (bool, string) {
file, err := os.Open("userConfig.json")
if err != nil {
return false, ""
}
defer file.Close()
var data map[string]string
decoder := json.NewDecoder(file)
if err := decoder.Decode(&data); err != nil {
return false, ""
}
authToken, ok := data["authToken"]
if !ok {
fmt.Printf("\n\033[91mError: missing auth token\033[0m\n")
return false, ""
}
if !checkToken(authToken) {
return false, ""
}
return true, authToken
}
func checkToken(token string) bool {
if token == "" {
return false
}
result := parseToken(token)
if result.Errored {
fmt.Printf("\n\033[91mError: %s\033[0m\n", result.Error)
return false
}
expiration, ok := result.Data.Claims["exp"].(float64)
if !ok {
fmt.Printf("\n\033[91mError: 'exp' claim is missing or not a float64\033[0m\n")
return false
}
expTime := time.Unix(int64(expiration), 0)
if time.Now().After(expTime) {
fmt.Printf("\n\033[91mError: Token Expired!\033[0m\n")
return false
}
verifyResult := verifyToken(token)
if !verifyResult {
fmt.Printf("\n\033[91mError: Token Invalid!\033[0m\n")
return false
}
return true
}
func parseToken(token string) TokenParseResult {
var result TokenParseResult
parts := strings.Split(token, ".")
if len(parts) != 3 {
result.Errored = true
result.Error = "Invalid JWT token format"
return result
}
tkn := &TokenData{}
// Parse Header
headerJSON, err := decodeBase64URL(parts[0])
if err != nil {
result.Errored = true
result.Error = "Failed to decode JWT header: " + err.Error()
return result
}
if err := json.Unmarshal([]byte(headerJSON), &tkn.Header); err != nil {
result.Errored = true
result.Error = "Failed to parse JWT header: " + err.Error()
return result
}
// Parse Claims
claimsJSON, err := decodeBase64URL(parts[1])
if err != nil {
result.Errored = true
result.Error = "Failed to decode JWT claims: " + err.Error()
return result
}
if err := json.Unmarshal([]byte(claimsJSON), &tkn.Claims); err != nil {
result.Errored = true
result.Error = "Failed to parse JWT claims: " + err.Error()
return result
}
// Parse Signature
sig, err := decodeBase64URL(parts[2])
if err != nil || len(sig) == 0 {
result.Errored = true
result.Error = "Failed to decode JWT signature: " + err.Error()
return result
}
tkn.Signature = parts[2]
result.Data = tkn
return result
}
func decodeBase64URL(data string) (string, error) {
decoded, err := base64.RawURLEncoding.DecodeString(data)
if err != nil {
return "", err
}
return string(decoded), nil
}
func verifyToken(authToken string) bool {
var apiUrl = "https://api.jamlaunch.com/projects"
data, success := fetch(apiUrl, authToken)
if success == nil {
if _, exists := data["projects"]; exists {
return true
} else {
return false
}
} else {
fmt.Printf("\033[91m%s\033[0m\n", success)
return false
}
}