2024-09-28 19:41:34 +01:00
package main
import (
"bytes"
2024-10-29 11:20:01 +00:00
"strings"
"time"
2024-09-28 19:41:34 +01:00
"encoding/json"
"net/url"
"syscall/js"
2024-10-29 11:20:01 +00:00
"git.ailur.dev/ailur/jsFetch"
2024-09-28 19:41:34 +01:00
)
func fetchOauthClients ( oauthList js . Value , localStorage js . Value , body [ ] byte ) {
// Fetch the OAuth clients
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/oauth/list" )
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error joining URL: " + err . Error ( ) )
oauthList . Call ( "appendChild" , statusText )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( body ) )
2024-09-28 19:41:34 +01:00
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error contacting server: " + err . Error ( ) )
oauthList . Call ( "appendChild" , statusText )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error decoding server response: " + err . Error ( ) )
oauthList . Call ( "appendChild" , statusText )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
for i := 0 ; i < oauthList . Get ( "childNodes" ) . Length ( ) ; i ++ {
this := oauthList . Get ( "childNodes" ) . Index ( i )
if this . Get ( "tagName" ) . String ( ) != "H2" {
this . Call ( "remove" )
}
}
clients , ok := responseMap [ "apps" ] . ( [ ] interface { } )
if ! ok {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Hi there! You don't have any OAuth2 clients yet. Create one above!" )
oauthList . Call ( "appendChild" , statusText )
} else {
for _ , app := range clients {
var oauthElement = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "div" )
var oauthText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
var oauthName = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
var oauthUrl = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
var oauthRemoveButton = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "button" )
oauthText . Set ( "innerText" , app . ( map [ string ] interface { } ) [ "appId" ] . ( string ) )
oauthName . Set ( "innerText" , app . ( map [ string ] interface { } ) [ "name" ] . ( string ) )
oauthUrl . Set ( "innerText" , app . ( map [ string ] interface { } ) [ "redirectUri" ] . ( string ) )
oauthRemoveButton . Set ( "innerText" , "Delete permanently" )
oauthRemoveButton . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
go func ( ) {
if js . Global ( ) . Call ( "confirm" , "Are you sure you want to delete this client? This action cannot be undone." ) . Bool ( ) {
// Create the request body
requestBody := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
"appId" : app . ( map [ string ] interface { } ) [ "appId" ] . ( string ) ,
}
// Marshal the body
bodyBytes , err := json . Marshal ( requestBody )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error marshaling body: " + err . Error ( ) )
return
}
// Send the request
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/oauth/remove" )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error joining URL: " + err . Error ( ) )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( bodyBytes ) )
2024-09-28 19:41:34 +01:00
if err != nil {
js . Global ( ) . Call ( "alert" , "Error contacting server: " + err . Error ( ) )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
oauthElement . Call ( "remove" )
if oauthList . Get ( "childNodes" ) . Length ( ) == 1 {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Hi there! You don't have any OAuth2 clients yet. Create one above!" )
oauthList . Call ( "appendChild" , statusText )
}
} else if response . StatusCode != 500 {
js . Global ( ) . Call ( "alert" , responseMap [ "error" ] . ( string ) )
} else {
js . Global ( ) . Call ( "alert" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
}
}
} ( )
return nil
} ) )
oauthElement . Call ( "append" , oauthName )
oauthElement . Call ( "append" , oauthText )
oauthElement . Call ( "append" , oauthUrl )
openId := false
clientKeyShare := false
scopes , ok := app . ( map [ string ] interface { } ) [ "scopes" ] . ( [ ] interface { } )
if ok {
for _ , scope := range scopes {
if scope . ( string ) == "openid" {
openId = true
} else if scope . ( string ) == "clientKeyShare" {
if app . ( map [ string ] interface { } ) [ "keyShareUri" ] . ( string ) != "" {
clientKeyShare = true
keyShareUri := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
keyShareUri . Set ( "innerText" , "Key Share URI: " + app . ( map [ string ] interface { } ) [ "keyShareUri" ] . ( string ) )
oauthElement . Call ( "append" , keyShareUri )
}
}
}
oauthScopes := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
var scopeText strings . Builder
if openId {
scopeText . WriteString ( "OpenID" )
}
if clientKeyShare {
if openId {
scopeText . WriteString ( ", " )
}
scopeText . WriteString ( "clientKeyShare" )
}
oauthScopes . Set ( "innerText" , "Scopes: " + scopeText . String ( ) )
oauthElement . Call ( "append" , oauthScopes )
}
oauthElement . Call ( "append" , oauthRemoveButton )
oauthElement . Get ( "classList" ) . Call ( "add" , "oauthEntry" )
oauthList . Call ( "appendChild" , oauthElement )
}
}
} else if response . StatusCode != 500 {
statusText := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , responseMap [ "error" ] . ( string ) )
oauthList . Call ( "appendChild" , statusText )
} else {
statusText := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
oauthList . Call ( "appendChild" , statusText )
}
}
func main ( ) {
2024-10-22 20:20:46 +01:00
// Transition in
2024-10-23 19:13:35 +01:00
js . Global ( ) . Get ( "document" ) . Get ( "documentElement" ) . Get ( "style" ) . Set ( "display" , "initial" )
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe-out" ) . Get ( "classList" ) . Call ( "add" , "swipe-out-animate" )
var sleepTime = 200 * time . Millisecond
if js . Global ( ) . Get ( "window" ) . Call ( "matchMedia" , "(prefers-reduced-motion: reduce)" ) . Get ( "matches" ) . Bool ( ) {
sleepTime = 500 * time . Millisecond
}
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
// Redirect to log-in if not signed in
localStorage := js . Global ( ) . Get ( "localStorage" )
if localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . IsNull ( ) {
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe" ) . Get ( "classList" ) . Call ( "add" , "swipe-animate" )
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Call ( "replace" , "/login" + js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "search" ) . String ( ) )
}
var submitButton = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "submitButton" )
var nameBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "nameBox" )
var usernameBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "usernameBox" )
var dateBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "dateBox" )
var clientKeyShareBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "clientKeyShareBox" )
var redirectUriBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "redirectUriBox" )
var openIdBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "openIdBox" )
var statusBox = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "statusBox" )
var oauthList = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "oauthList" )
var sessionList = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "sessionList" )
var deleteAccountButton = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "deleteAccountButton" )
var logoutButton = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "logoutButton" )
var devAccountSwitcher = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "devAccountSwitcher" )
var developers = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "developers" )
var account = js . Global ( ) . Get ( "document" ) . Call ( "getElementById" , "account" )
// Fetch the OAuth clients and sessions
go func ( ) {
// Check if the token is valid
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/loggedIn" )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error joining URL: " + err . Error ( ) )
return
}
loggedInBody := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
}
// Marshal the body
body , err := json . Marshal ( loggedInBody )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error marshaling signup body: " + err . Error ( ) )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( body ) )
2024-09-28 19:41:34 +01:00
if err != nil {
js . Global ( ) . Call ( "alert" , "Error contacting server: " + err . Error ( ) )
return
}
// Check if the response is 200
if response . StatusCode == 401 {
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
// Redirect to log-out if not signed in
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe" ) . Get ( "classList" ) . Call ( "add" , "swipe-animate" )
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Call ( "replace" , "/logout" )
return
} else if response . StatusCode == 500 {
// Read the response
var responseMap map [ string ] interface { }
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
// Alert the user if the server is down
js . Global ( ) . Call ( "alert" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
// Fetch the OAuth clients
fetchOauthClients ( oauthList , localStorage , body )
// Fetch the sessions
requestUri , err = url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/session/list" )
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error joining URL: " + err . Error ( ) )
sessionList . Call ( "appendChild" , statusText )
return
}
2024-10-29 11:20:01 +00:00
response , err = jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( body ) )
2024-09-28 19:41:34 +01:00
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error contacting server: " + err . Error ( ) )
sessionList . Call ( "appendChild" , statusText )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Error decoding server response: " + err . Error ( ) )
sessionList . Call ( "appendChild" , statusText )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
if len ( responseMap [ "sessions" ] . ( [ ] interface { } ) ) == 0 {
var statusText = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Hi there! You don't have any sessions logged in, somehow. Congrats on breaking the laws of physics!" )
sessionList . Call ( "appendChild" , statusText )
} else {
for i := 0 ; i < sessionList . Get ( "childNodes" ) . Length ( ) ; i ++ {
this := sessionList . Get ( "childNodes" ) . Index ( i )
if this . Get ( "tagName" ) . String ( ) != "H2" {
this . Call ( "remove" )
}
}
for _ , session := range responseMap [ "sessions" ] . ( [ ] interface { } ) {
var sessionElement = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "div" )
var sessionDevice = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
var sessionImage = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "img" )
var sessionRemoveButton = js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "button" )
if session . ( map [ string ] interface { } ) [ "session" ] . ( string ) == localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) {
sessionDevice . Set ( "innerText" , "(current) " + session . ( map [ string ] interface { } ) [ "device" ] . ( string ) )
} else {
sessionDevice . Set ( "innerText" , session . ( map [ string ] interface { } ) [ "device" ] . ( string ) )
}
if strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "nt" ) || strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "macintosh" ) {
sessionImage . Set ( "src" , "/static/svg/device_computer.svg" )
} else if strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "iphone" ) || strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "android" ) || strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "ipod" ) {
sessionImage . Set ( "src" , "/static/svg/device_smartphone.svg" )
} else if strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "curl" ) || strings . Contains ( strings . ToLower ( session . ( map [ string ] interface { } ) [ "device" ] . ( string ) ) , "go-http-client" ) {
sessionImage . Set ( "src" , "/static/svg/device_terminal.svg" )
} else {
sessionImage . Set ( "src" , "/static/svg/device_other.svg" )
}
sessionRemoveButton . Set ( "innerText" , "Force log out" )
sessionRemoveButton . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
go func ( ) {
// Create the request body
body := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
"session" : session . ( map [ string ] interface { } ) [ "session" ] . ( string ) ,
}
// Marshal the body
bodyBytes , err := json . Marshal ( body )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error marshaling body: " + err . Error ( ) )
return
}
// Send the request
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/session/remove" )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error joining URL: " + err . Error ( ) )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( bodyBytes ) )
2024-09-28 19:41:34 +01:00
if err != nil {
js . Global ( ) . Call ( "alert" , "Error contacting server: " + err . Error ( ) )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
sessionElement . Call ( "remove" )
if session . ( map [ string ] interface { } ) [ "session" ] . ( string ) == localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) {
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe" ) . Get ( "classList" ) . Call ( "add" , "swipe-animate" )
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Call ( "replace" , "/logout" )
}
} else if response . StatusCode != 500 {
js . Global ( ) . Call ( "alert" , responseMap [ "error" ] . ( string ) )
} else {
js . Global ( ) . Call ( "alert" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
}
} ( )
return nil
} ) )
sessionElement . Call ( "append" , sessionImage )
sessionElement . Call ( "append" , sessionDevice )
sessionElement . Call ( "append" , sessionRemoveButton )
sessionElement . Get ( "classList" ) . Call ( "add" , "sessionEntry" )
sessionList . Call ( "appendChild" , sessionElement )
}
}
} else if response . StatusCode != 500 {
statusText := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , responseMap [ "error" ] . ( string ) )
sessionList . Call ( "appendChild" , statusText )
} else {
statusText := js . Global ( ) . Get ( "document" ) . Call ( "createElement" , "p" )
statusText . Set ( "innerText" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
sessionList . Call ( "appendChild" , statusText )
}
// Fetch user information
requestUri , err = url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/userinfo" )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error joining URL: " + err . Error ( ) )
return
}
// Re-use the body variable for this request
2024-10-29 11:20:01 +00:00
response , err = jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( body ) )
2024-09-28 19:41:34 +01:00
if err != nil {
js . Global ( ) . Call ( "alert" , "Error contacting server: " + err . Error ( ) )
return
}
// Read the response
decoder = json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
js . Global ( ) . Call ( "alert" , "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
}
if response . StatusCode == 200 {
usernameBox . Set ( "innerText" , "Username: " + responseMap [ "username" ] . ( string ) )
dateBox . Set ( "innerText" , "Account created: " + time . Unix ( int64 ( responseMap [ "created" ] . ( float64 ) ) , 0 ) . Format ( "2006-01-02 15:04:05" ) )
} else if response . StatusCode != 500 {
js . Global ( ) . Call ( "alert" , responseMap [ "error" ] . ( string ) )
} else {
js . Global ( ) . Call ( "alert" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
}
} ( )
submitButton . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
go func ( ) {
// Validate the input
if nameBox . Get ( "value" ) . String ( ) == "" {
statusBox . Set ( "innerText" , "An App Name is required!" )
return
} else if redirectUriBox . Get ( "value" ) . String ( ) == "" {
statusBox . Set ( "innerText" , "A Redirect URI is required!" )
return
}
// Check for scopes
var scopes [ ] string
if openIdBox . Get ( "checked" ) . Bool ( ) {
scopes = append ( scopes , "openid" )
}
if clientKeyShareBox . Get ( "value" ) . String ( ) != "" {
scopes = append ( scopes , "clientKeyShare" )
}
// Create the request body
body := map [ string ] interface { } {
"name" : nameBox . Get ( "value" ) . String ( ) ,
"redirectUri" : redirectUriBox . Get ( "value" ) . String ( ) ,
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
"scopes" : scopes ,
"keyShareUri" : redirectUriBox . Get ( "value" ) . String ( ) ,
}
// Marshal the body
bodyBytes , err := json . Marshal ( body )
if err != nil {
statusBox . Set ( "innerText" , "Error marshaling body: " + err . Error ( ) )
return
}
// Send the request
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/oauth/add" )
if err != nil {
statusBox . Set ( "innerText" , "Error joining URL: " + err . Error ( ) )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( bodyBytes ) )
2024-09-28 19:41:34 +01:00
if err != nil {
statusBox . Set ( "innerText" , "Error contacting server: " + err . Error ( ) )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
statusBox . Set ( "innerText" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
statusBox . Set ( "innerText" , "Your secret key is: " + responseMap [ "key" ] . ( string ) + " and your client ID is: " + responseMap [ "appId" ] . ( string ) + ". This will only ever be shown once!" )
// Update the OAuth clients
bodyMap := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
}
// Marshal the body
body , err := json . Marshal ( bodyMap )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Error marshaling body: " + err . Error ( ) + ", this is non-fatal." )
2024-09-28 19:41:34 +01:00
return
}
// Perform the request
fetchOauthClients ( oauthList , localStorage , body )
} else if response . StatusCode != 500 {
statusBox . Set ( "innerText" , responseMap [ "error" ] . ( string ) )
} else {
statusBox . Set ( "innerText" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
}
} ( )
return nil
} ) )
deleteAccountButton . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
go func ( ) {
if js . Global ( ) . Call ( "confirm" , "Are you sure you would like to delete your account forever? This cannot be undone." ) . Bool ( ) {
// Create the request body
body := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
}
// Marshal the body
bodyBytes , err := json . Marshal ( body )
if err != nil {
statusBox . Set ( "innerText" , "Error marshaling body: " + err . Error ( ) )
return
}
// Send the request
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/deleteAccount" )
if err != nil {
statusBox . Set ( "innerText" , "Error joining URL: " + err . Error ( ) )
return
}
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( bodyBytes ) )
2024-09-28 19:41:34 +01:00
if err != nil {
statusBox . Set ( "innerText" , "Error contacting server: " + err . Error ( ) )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
statusBox . Set ( "innerText" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
if response . StatusCode == 200 {
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe" ) . Get ( "classList" ) . Call ( "add" , "swipe-animate" )
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Call ( "replace" , "/logout" )
} else if response . StatusCode != 500 {
js . Global ( ) . Call ( "alert" , responseMap [ "error" ] . ( string ) )
} else {
js . Global ( ) . Call ( "alert" , "Something went wrong! (error code: " + responseMap [ "code" ] . ( string ) + ")" )
}
}
} ( )
return nil
} ) )
devAccountSwitcher . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
developers . Get ( "classList" ) . Call ( "toggle" , "hidden" )
account . Get ( "classList" ) . Call ( "toggle" , "hidden" )
if devAccountSwitcher . Get ( "innerText" ) . String ( ) == "Switch to developer view" {
devAccountSwitcher . Set ( "innerText" , "Switch to account view" )
} else {
devAccountSwitcher . Set ( "innerText" , "Switch to developer view" )
}
return nil
} ) )
logoutButton . Call ( "addEventListener" , "click" , js . FuncOf ( func ( this js . Value , args [ ] js . Value ) interface { } {
go func ( ) {
// Try to remove the session
requestUri , err := url . JoinPath ( js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Get ( "origin" ) . String ( ) , "/api/session/remove" )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error joining URL: " + err . Error ( ) )
return
}
// Create the request body
body := map [ string ] interface { } {
"token" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
"session" : localStorage . Call ( "getItem" , "DONOTSHARE-secretKey" ) . String ( ) ,
}
// Marshal the body
bodyBytes , err := json . Marshal ( body )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error marshaling body: " + err . Error ( ) )
return
}
// Send the request
2024-10-29 11:20:01 +00:00
response , err := jsFetch . Post ( requestUri , "application/json" , bytes . NewReader ( bodyBytes ) )
2024-09-28 19:41:34 +01:00
if err != nil {
js . Global ( ) . Call ( "alert" , "Error contacting server: " + err . Error ( ) )
return
}
// Get all our ducks in a row
var responseMap map [ string ] interface { }
// Read the response
decoder := json . NewDecoder ( response . Body )
err = decoder . Decode ( & responseMap )
if err != nil {
js . Global ( ) . Call ( "alert" , "Error decoding server response: " + err . Error ( ) )
return
}
// Close the response body
err = response . Body . Close ( )
if err != nil {
2024-10-29 11:20:01 +00:00
println ( "Could not close response body: " + err . Error ( ) + ", memory leaks may occur" )
2024-09-28 19:41:34 +01:00
}
// We don't care about the response, we're logging out anyway
2024-10-22 20:20:46 +01:00
js . Global ( ) . Get ( "swipe" ) . Get ( "classList" ) . Call ( "add" , "swipe-animate" )
time . Sleep ( sleepTime )
2024-09-28 19:41:34 +01:00
js . Global ( ) . Get ( "window" ) . Get ( "location" ) . Call ( "replace" , "/logout" )
} ( )
return nil
} ) )
// Wait for events
select { }
}