Add some much-needed eye-candy :D

Signed-off-by: arzumify <jliwin98@danwin1210.de>
This commit is contained in:
Tracker-Friendly 2024-10-22 20:20:46 +01:00
parent 6eb9e76316
commit 93a984b951
18 changed files with 288 additions and 60 deletions

View File

@ -25,6 +25,14 @@
"adminKey": "supersecretkey",
"testAppIsInternalApp": true,
"testAppEnabled": true
},
"eternity": {
"hostName": "http://localhost:8000",
"gitDir": "./git",
"outputDir": "./output"
},
"datatracker": {
"hostName": "http://localhost:8000"
}
}
}

View File

@ -1,4 +1,16 @@
@import url("../fonts/inter.css");
@font-face {
font-family: 'Figtree';
src: url("fonts/Figtree.woff2") format("woff2");
font-style: normal;
}
html {
background: linear-gradient(to top left, rgb(217, 236, 255), rgb(228, 249, 255), rgb(221, 255, 238), rgb(249,255,253)) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
:root {
--invertdm: 0%;
@ -66,17 +78,16 @@ p#statusBox {
body {
margin: 0;
background-color: var(--editor);
font-family: "Inter", sans-serif;
font-family: "Figtree", sans-serif;
}
/* Sign up/log in div */
.inOutDiv {
border-radius: 8px;
border-radius: 25px;
margin: 10%;
padding: 30px;
border: solid 1px var(--border-color);
background-color: var(--inOutDiv);
padding: 35px 35px 50px;
}
table {
@ -87,14 +98,14 @@ input {
width: calc(100% - 35px);
margin-left: 10px;
margin-right: 10px;
height: 30px;
height: 35px;
padding-left: 10px;
padding-right: 10px;
border: solid;
border-color: var(--border-color);
border-width: 1px;
border-radius: 8px;
border-radius: 5px;
min-width: 20px;
}
@ -157,9 +168,6 @@ input {
.inOutDiv p {
font-size: 14px;
}
.inOutDiv h2 {
font-size: 21px;
}
.background {
display: none;
}
@ -201,27 +209,24 @@ input {
.newOauth, .oauthList, .sessionEntry, .oauthEntry {
text-align: center;
width: calc(100% - 17.5vh);
margin-top: 7vh;
margin-left: 7vh;
margin-right: 7vh;
padding: 15px 10px 30px;
border-style: solid;
border-image: none;
border-radius: 8px;
border-width: 1px;
border-radius: 25px;
font-size: 17px;
background-color: var(--inOutDiv);
border-color: var(--border-color);
}
.oauthEntry, .sessionEntry {
display: flex;
flex-direction: column;
justify-content: center;
padding: 5px;
padding: 20px;
margin-top: 0;
margin-bottom: 20px;
border: 3px dotted var(--border-color);
}
.oauthEntry button, .sessionEntry button {
@ -287,8 +292,9 @@ button:hover {
h2 {
display: block;
margin-top: 20px;
font-weight: 300;
margin-top: 10px;
font-weight: 600;
font-size: 22px;
}
.inOutDiv a {
@ -296,21 +302,6 @@ h2 {
text-align: center;
}
.background {
position: fixed;
z-index: -2;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
-webkit-user-drag: none;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
pointer-events: none;
}
.vAlign {
display: flex;
flex-direction: column;
@ -356,3 +347,82 @@ h2 {
.w900 {
font-weight: 900;
}
/* swipe animation */
.swipe {
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #fff;
animation: swipe 0.2s forwards;
display: none;
}
.swipe-animate {
display: initial;
}
/* swipe-out animation */
.swipe-out {
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #fff;
}
.swipe-out-animate {
animation: swipe-out 0.2s forwards;
}
@keyframes swipe {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
@keyframes swipe-out {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
}
}
@keyframes swipe-reduced {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes swipe-out-reduced {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.swipe {
animation: swipe-reduced 0.5s forwards;
}
.swipe-out {
animation: swipe-out-reduced 0.5s forwards;
}
}

View File

@ -12,9 +12,8 @@
<body>
<span id="passThrough" style="display: none;">{{ .name }}</span>
<span id="autoAccept" style="display: none;">0</span>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2 class="w300">Authorise Application</h2>
<h2>Authorise Application</h2>
<p id="statusBox">Loading...</p>
<br>
<div style="display: flex;justify-content: center;">
@ -24,6 +23,8 @@
<br>
<a href="/dashboard">Return to Dashboard</a>
</div>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
<script>
loadWasm("/static/wasm/authorize.wasm")
</script>

View File

@ -12,14 +12,15 @@
<body>
<span id="passThrough" style="display: none;">{{ .name }}</span>
<span id="autoAccept" style="display: none;">1</span>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2 class="w300">Authorizing application</h2>
<h2>Authorizing application</h2>
<p id="statusBox">Please wait...</p>
</div>
<script>
<script>
loadWasm("/static/wasm/authorize.wasm")
</script>
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -10,7 +10,6 @@
<script src="/static/js/wasm_exec.js"></script>
</head>
<body>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2>Relaying back information, please wait...</h2>
<p id="statusBox">Processing information sent...</p>
@ -18,5 +17,7 @@
<script>
loadWasm("/static/wasm/clientKeyShare.wasm")
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -10,7 +10,6 @@
<script src="/static/js/wasm_exec.js"></script>
</head>
<body>
<img src="/static/img/background.png" class="background" alt="">
<div class="newOauth">
<h2>Dashboard</h2>
<p>Welcome to the {{ .identifier }} dashboard!</p>
@ -50,5 +49,7 @@
<script>
loadWasm("/static/wasm/dashboard.wasm")
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -13,9 +13,8 @@
<body>
<span id="passThrough" style="display: none;">{{ .identifier }}</span>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2 class="w300">Login</h2>
<h2>Login</h2>
<p id="statusBox"></p>
<div class="inputContainer" id="inputContainer">
<div class="vAlign"><span id="inputNameBox"></span></div>
@ -33,4 +32,6 @@
<script>
loadWasm("/static/wasm/login.wasm")
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>

View File

@ -9,7 +9,4 @@
<link rel="icon" href="/static/svg/favicon.svg">
<script src="/static/js/logout.js"></script>
</head>
<body>
<p>Logging out...</p>
</body>
</html>

View File

@ -14,5 +14,7 @@
<body>
<p>Please wait...</p>
<p>If your browser does not refresh, please refresh the page manually.</p>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -11,9 +11,8 @@
<body>
<p style="display: none;" id="passthrough">{{ .unique_token }}</p>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2 class="w300">Signup</h2>
<div class="inOutDiv"></div>
<h2>Signup</h2>
<p>Signup to {{ .identifier }}!</p>
<p id="statusBox"></p>
<table id="inputContainer">
@ -48,5 +47,7 @@
<script>
loadWasm("/static/wasm/signup.wasm")
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -9,8 +9,7 @@
<link rel="stylesheet" type="text/css" href="/static/css/style.css"/>
<script src="/static/js/wasm_exec.js"></script>
</head>
<body>
<img src="/static/img/background.png" class="background" alt="">
<body style="display: none;">
<div class="inOutDiv">
<h2>{{ .identifier }} Tester</h2>
<p id="statusBox">Click authorize to begin the test</p>
@ -20,5 +19,7 @@
<script>
loadWasm("/static/wasm/testApp.wasm")
</script>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -9,10 +9,11 @@
<link rel="stylesheet" type="text/css" href="/static/css/style.css"/>
</head>
<body>
<img src="/static/img/background.png" class="background" alt="">
<div class="inOutDiv">
<h2>{{ .identifier }} Tester</h2>
<p>The tester has been disabled by the administrator.</p>
</div>
<div id="swipe" class="swipe"></div>
<div id="swipe-out" class="swipe-out"></div>
</body>
</html>

View File

@ -8,9 +8,10 @@ import (
"net/url"
"strings"
"syscall/js"
"time"
)
func authorize(deny bool, query url.Values) {
func authorize(deny bool, query url.Values, sleepTime time.Duration) {
// Get the token from local storage
localStorage := js.Global().Get("localStorage")
token := localStorage.Call("getItem", "DONOTSHARE-secretKey").String()
@ -79,6 +80,8 @@ func authorize(deny bool, query url.Values) {
denyUri += "&state=" + query.Get("state")
}
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", denyUri)
} else {
// Redirect to the redirect_uri with the code
@ -87,6 +90,8 @@ func authorize(deny bool, query url.Values) {
allowUri += "&state=" + query.Get("state")
}
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", allowUri)
}
} else if response.StatusCode == 401 {
@ -99,9 +104,22 @@ func authorize(deny bool, query url.Values) {
}
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Redirect to log-in if not signed in
localStorage := js.Global().Get("localStorage")
if localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/login"+js.Global().Get("window").Get("location").Get("search").String())
}
@ -151,6 +169,8 @@ func main() {
}
// Redirect to log-out if not signed in
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout"+js.Global().Get("window").Get("location").Get("search").String())
return
} else if response.StatusCode == 500 {
@ -187,18 +207,18 @@ func main() {
// Add an event listener to the Deny button
js.Global().Get("document").Call("getElementById", "denyButton").Call("addEventListener", "click", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
// We still partially authorize the user to prevent open redirects
go authorize(true, query)
go authorize(true, query, sleepTime)
return nil
}))
// Add an event listener to the Allow button
js.Global().Get("document").Call("getElementById", "allowButton").Call("addEventListener", "click", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
go authorize(false, query)
go authorize(false, query, sleepTime)
return nil
}))
} else {
// Auto-accept the request, as it's from an internal service
go authorize(false, query)
go authorize(false, query, sleepTime)
}
// Wait for events

View File

@ -9,12 +9,26 @@ import (
"net/url"
"strings"
"syscall/js"
"time"
)
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Redirect to log-in if not signed in
localStorage := js.Global().Get("localStorage")
if localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/login"+js.Global().Get("window").Get("location").Get("search").String())
}
@ -86,5 +100,7 @@ func main() {
// Redirect back to the referrer with the encrypted client key
redirectUri := strings.Split(js.Global().Get("document").Get("referrer").String(), "?")[0]
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", redirectUri+"?ecdhPublicKey="+base64.URLEncoding.EncodeToString(privateKey.PublicKey().Bytes())+"&nonce="+base64.URLEncoding.EncodeToString(nonce)+"&cipherText="+base64.URLEncoding.EncodeToString(encryptedClientKey))
}

View File

@ -191,9 +191,22 @@ func fetchOauthClients(oauthList js.Value, localStorage js.Value, body []byte) {
}
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Redirect to log-in if not signed in
localStorage := js.Global().Get("localStorage")
if localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/login"+js.Global().Get("window").Get("location").Get("search").String())
}
@ -248,6 +261,8 @@ func main() {
}
// Redirect to log-out if not signed in
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout")
return
} else if response.StatusCode == 500 {
@ -399,6 +414,8 @@ func main() {
if response.StatusCode == 200 {
sessionElement.Call("remove")
if session.(map[string]interface{})["session"].(string) == localStorage.Call("getItem", "DONOTSHARE-secretKey").String() {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout")
}
} else if response.StatusCode != 500 {
@ -604,6 +621,8 @@ func main() {
}
if response.StatusCode == 200 {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout")
} else if response.StatusCode != 500 {
js.Global().Call("alert", responseMap["error"].(string))
@ -673,6 +692,8 @@ func main() {
}
// We don't care about the response, we're logging out anyway
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout")
}()
return nil

View File

@ -8,6 +8,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"syscall/js"
"time"
@ -68,10 +69,34 @@ func showInput(inputType int, inputContainer js.Value, usernameBox js.Value, sig
}
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Parse the url parameters using url.ParseQuery
dashboard := false
_, err := url.ParseQuery(strings.TrimPrefix(js.Global().Get("window").Get("location").Get("search").String(), "?"))
if err != nil {
dashboard = true
}
// Redirect to app if already signed in
localStorage := js.Global().Get("localStorage")
if !localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
if !dashboard {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
} else {
js.Global().Get("window").Get("location").Call("replace", "/dashboard")
}
}
var usernameBox = js.Global().Get("document").Call("getElementById", "usernameBox")
@ -219,7 +244,13 @@ func main() {
// Redirect to app
statusBox.Set("innerText", "Welcome!")
time.Sleep(time.Second)
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
if !dashboard {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
} else {
js.Global().Get("window").Get("location").Call("replace", "/dashboard")
}
} else if response.StatusCode == 401 {
// Login failed
showInput(1, inputContainer, usernameBox, signupButton, passwordBox, backButton, inputNameBox, statusBox, nextButton)
@ -252,6 +283,8 @@ func main() {
}))
signupButton.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/signup"+js.Global().Get("window").Get("location").Get("search").String())
return nil
}))

View File

@ -9,6 +9,7 @@ import (
"encoding/hex"
"fmt"
"strconv"
"strings"
"time"
"encoding/json"
@ -57,10 +58,34 @@ func pow(resource string) (string, string, error) {
}
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Parse the url parameters using url.ParseQuery
dashboard := false
_, err := url.ParseQuery(strings.TrimPrefix(js.Global().Get("window").Get("location").Get("search").String(), "?"))
if err != nil {
dashboard = true
}
// Redirect to app if already signed in
localStorage := js.Global().Get("localStorage")
if !localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
if !dashboard {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
} else {
js.Global().Get("window").Get("location").Call("replace", "/dashboard")
}
}
var usernameBox = js.Global().Get("document").Call("getElementById", "usernameBox")
@ -179,7 +204,13 @@ func main() {
// Redirect to app
statusBox.Set("innerText", "Welcome!")
time.Sleep(time.Second)
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
if !dashboard {
js.Global().Get("window").Get("location").Call("replace", "/authorize"+js.Global().Get("window").Get("location").Get("search").String())
} else {
js.Global().Get("window").Get("location").Call("replace", "/dashboard")
}
} else if response.StatusCode == 409 {
// Username taken
showElements(true, inputContainer, signupButton, loginButton)
@ -199,6 +230,8 @@ func main() {
}))
loginButton.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/login"+js.Global().Get("window").Get("location").Get("search").String())
return nil
}))

View File

@ -17,6 +17,7 @@ import (
"strconv"
"strings"
"syscall/js"
"time"
)
func sha256Base64(s string) string {
@ -46,9 +47,22 @@ func randomChars(length int) (string, error) {
}
func main() {
// Transition in
js.Global().Get("document").Get("body").Set("style", "display: initial")
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)
// Redirect to log-in if not signed in
localStorage := js.Global().Get("localStorage")
if localStorage.Call("getItem", "DONOTSHARE-secretKey").IsNull() {
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/login"+js.Global().Get("window").Get("location").Get("search").String())
}
@ -88,6 +102,8 @@ func main() {
}
// Redirect to log-out if not signed in
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/logout"+js.Global().Get("window").Get("location").Get("search").String())
return
} else if response.StatusCode == 500 {
@ -217,6 +233,8 @@ func main() {
localStorage.Call("setItem", "TESTER-privateKey", base64.StdEncoding.EncodeToString(privateKey.Bytes()))
// Redirect to the client key exchange endpoint
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/clientKeyShare?ecdhPublicKey="+base64.URLEncoding.EncodeToString(privateKey.PublicKey().Bytes())+"&accessToken="+responseMap["access_token"].(string))
return
} else if response.StatusCode != 500 {
@ -317,6 +335,8 @@ func main() {
localStorage.Call("setItem", "TESTER-verifier", verifier)
// Redirect to the authorization page
js.Global().Get("swipe").Get("classList").Call("add", "swipe-animate")
time.Sleep(sleepTime)
js.Global().Get("window").Get("location").Call("replace", "/authorize?response_type=code&client_id=TestApp-DoNotUse&redirect_uri="+url.QueryEscape(js.Global().Get("window").Get("location").Get("origin").String()+"/testApp")+"&code_challenge="+verifierChallenge+"&code_challenge_method=S256")
}()
return nil