diff --git a/assets/checkmark.css b/assets/checkmark.css new file mode 100644 index 0000000..aaf4baf --- /dev/null +++ b/assets/checkmark.css @@ -0,0 +1,67 @@ + svg { + width: 10rem; + height: 10rem; + display: block; + margin: 40px auto 0; + } + .path { + stroke-dasharray: 1000; + stroke-dashoffset: 0; + } + .path.circle { + -webkit-animation: dash 0.9s ease-in-out; + animation: dash 0.9s ease-in-out; + } + .path.line { + stroke-dashoffset: 1000; + -webkit-animation: dash 0.9s 0.35s ease-in-out forwards; + animation: dash 0.9s 0.35s ease-in-out forwards; + } + .path.check { + stroke-dashoffset: -100; + -webkit-animation: dash-check 0.9s 0.35s ease-in-out forwards; + animation: dash-check 0.9s 0.35s ease-in-out forwards; + } + p { + text-align: center; + margin: 20px 0 60px; + font-size: 1.25em; + } + p.success { + color: #73af55; + } + p.error { + color: #d06079; + } + @-webkit-keyframes dash { + 0% { + stroke-dashoffset: 1000; + } + 100% { + stroke-dashoffset: 0; + } + } + @keyframes dash { + 0% { + stroke-dashoffset: 1000; + } + 100% { + stroke-dashoffset: 0; + } + } + @-webkit-keyframes dash-check { + 0% { + stroke-dashoffset: -100; + } + 100% { + stroke-dashoffset: 900; + } + } + @keyframes dash-check { + 0% { + stroke-dashoffset: -100; + } + 100% { + stroke-dashoffset: 900; + } + } \ No newline at end of file diff --git a/csgo-hub-backend b/csgo-hub-backend deleted file mode 100755 index ce803fe..0000000 Binary files a/csgo-hub-backend and /dev/null differ diff --git a/main.go b/main.go index 6d06a1f..881ca92 100644 --- a/main.go +++ b/main.go @@ -218,7 +218,7 @@ func main() { router.HandleFunc("/discover", discoverHandler) router.HandleFunc("/openidcallback", callbackHandler) router.HandleFunc("/{token}", indexHandler) - router.Handle("/static/", (http.StripPrefix("/static", http.FileServer(http.Dir("./assets"))))) + router.PathPrefix("/static/").Handler(http.StripPrefix("/static", http.FileServer(http.Dir("./assets")))) router.HandleFunc("/api/v1/users", GetMultipleUsers) router.HandleFunc("/api/v1/token/{discord}", CreateToken) http.ListenAndServe(port, router) diff --git a/index.html b/sites/authenticate.html similarity index 89% rename from index.html rename to sites/authenticate.html index 8aa91eb..01d21e8 100644 --- a/index.html +++ b/sites/authenticate.html @@ -5,11 +5,9 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/static/style.css"> - <title>Steam OpenID</title> + <title>CS:GO Hub</title> </head> - <body> - {{if .DiscordName}} <div class="navbar"> <ul> <li style="float:right"><img alt="avatar" src="{{.DiscordAvatar}}" width="50" height="50px"></li> @@ -29,16 +27,9 @@ <span>Login with Steam</span> </a> <br> - {{else if .user}} - <div class="login"> - <p>{{.user}} Linked to your Discord account</p> - {{else}} - <p>An error occured</p> - {{end}} </div> <div class="footer"> <p><i>This site is not associated with Valve Corp.</i></p> </div> </body> - </html> \ No newline at end of file diff --git a/sites/success.html b/sites/success.html new file mode 100644 index 0000000..8408e9d --- /dev/null +++ b/sites/success.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="/static/style.css"> + <link rel="stylesheet" href="/static/checkmark.css"> + <title>CS:GO Hub</title> +</head> +<body> + <div class="navbar"> + <ul> + <li style="float:right"><img alt="avatar" src="{{.DiscordAvatar}}" width="50" height="50px"></li> + <li style="float:right"><a class="active" href="#"><b>{{.DiscordName}}</b></a></li> + </ul> + </div> + <div class="login"> + <h1>{{.Status}}</h1> + <br> + <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130.2 130.2"> + <circle class="path circle" fill="none" stroke="#73AF55" stroke-width="6" stroke-miterlimit="10" cx="65.1" cy="65.1" r="62.1"/> + <polyline class="path check" fill="none" stroke="#73AF55" stroke-width="6" stroke-linecap="round" stroke-miterlimit="10" points="100.2,40.2 51.5,88.8 29.8,67.5 "/> + </svg> + </div> + <div class="footer"> + <p><i>This site is not associated with Valve Corp.</i></p> + </div> +</body> +</html> \ No newline at end of file diff --git a/steam.go b/steam.go index 83fb559..b392a4e 100644 --- a/steam.go +++ b/steam.go @@ -16,9 +16,8 @@ import ( "github.com/yohcop/openid-go" ) -// Load the templates once -var templateDir = "./" -var indexTemplate = template.Must(template.ParseFiles(templateDir + "index.html")) +var authenticateTmpl = template.Must(template.ParseFiles("./sites/authenticate.html")) +var successTmpl = template.Must(template.ParseFiles("./sites/success.html")) // NoOpDiscoveryCache implements the DiscoveryCache interface and doesn't cache anything. // For a simple website, I'm not sure you need a cache. @@ -39,6 +38,11 @@ type IndexStruct struct { DiscordName string `json:"DiscordName"` DiscordAvatar string `json:"DiscordAvatar"` } +type SuccessStruct struct { + DiscordName string `json:"DiscordName"` + DiscordAvatar string `json:"DiscordAvatar"` + Status string `json:"Status"` +} type DiscordUser struct { Id string `json:"id"` @@ -93,7 +97,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { expiration := time.Now().Add(time.Hour) cookie := http.Cookie{Name: "token", Value: token, Expires: expiration} http.SetCookie(w, &cookie) - indexTemplate.Execute(w, tmpl) + authenticateTmpl.Execute(w, tmpl) } // discoverHandler calls the Steam openid API and redirects to steam for login. @@ -118,6 +122,7 @@ func ClearToken(token string) error { // callbackHandler handles the response back from Steam. It verifies the callback and then renders // the index template with the logged in user's id. func callbackHandler(w http.ResponseWriter, r *http.Request) { + var tmpl SuccessStruct fullURL := "http://" + domain + r.URL.String() id, err := openid.Verify(fullURL, discoveryCache, nonceStore) @@ -150,6 +155,31 @@ func callbackHandler(w http.ResponseWriter, r *http.Request) { } ClearToken(token) + req, _ := http.NewRequest("GET", "https://discord.com/api/v9/users/"+discordId, nil) + req.Header.Add("Authorization", bearer) + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Println("Error on response.\n[ERROR] -", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Println("Error while reading the response bytes:", err) + } + var discord DiscordUser + json.Unmarshal(body, &discord) + var discordAvatarURL string + if discord.Avatar == "" { + discordAvatarURL = "https://csgohub.xyz/assets/empty-avatar.png" + } else { + discordAvatarURL = "https://cdn.discordapp.com/avatars/" + discord.Id + "/" + discord.Avatar + ".png?size=100" + } + tmpl.DiscordName = discord.Username + tmpl.DiscordAvatar = discordAvatarURL + var checkId, checkFriend string query = `SELECT discord_id, friend_code FROM users where discord_id = ?` err = db.QueryRow(query, discordId).Scan(&checkId, &checkFriend) @@ -161,8 +191,10 @@ func callbackHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Bad request") } log.Print(err) - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, "Account link updated") + // w.WriteHeader(http.StatusCreated) + // fmt.Fprintf(w, "Account link updated") + tmpl.Status = "Account link updated" + successTmpl.Execute(w, tmpl) return } @@ -171,10 +203,12 @@ func callbackHandler(w http.ResponseWriter, r *http.Request) { log.Println(err) w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "Bad request") + return } + tmpl.Status = "Account linked" w.WriteHeader(http.StatusCreated) data["user"] = id - indexTemplate.Execute(w, data) + successTmpl.Execute(w, tmpl) } }