package main import ( "html/template" "log" "net/http" ) const css = ` body { font-family: Arial, sans-serif; background-color: #f2f2f2; margin: 0; } .header { text-align: center; margin-bottom: 20px; } .dex { font-size: 2em; font-weight: bold; color: #3F9FD8; /* Main color */ } .example-app { font-size: 1em; color: #EF4B5C; /* Secondary color */ } .form-instructions { text-align: center; margin-bottom: 15px; font-size: 1em; color: #555; } hr { border: none; border-top: 1px solid #ccc; margin-top: 10px; margin-bottom: 20px; } label { flex: 1; font-weight: bold; color: #333; } p { margin-bottom: 15px; display: flex; align-items: center; } input[type="text"] { flex: 2; padding: 8px; border: 1px solid #ccc; border-radius: 4px; outline: none; } input[type="checkbox"] { margin-left: 10px; transform: scale(1.2); } .back-button { display: inline-block; padding: 8px 16px; background-color: #EF4B5C; /* Secondary color */ color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; text-decoration: none; transition: background-color 0.3s ease, transform 0.2s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); position: fixed; right: 20px; bottom: 20px; } .back-button:hover { background-color: #C43B4B; /* Darker shade of secondary color */ } .token-block { background-color: #fff; padding: 10px 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); margin-bottom: 15px; word-wrap: break-word; display: flex; flex-direction: column; gap: 5px; position: relative; } .token-title { font-weight: bold; display: flex; justify-content: space-between; align-items: center; } .token-title a { font-size: 0.9em; text-decoration: none; color: #3F9FD8; /* Main color */ } .token-title a:hover { text-decoration: underline; } .token-code { overflow-wrap: break-word; word-break: break-all; white-space: normal; } pre { white-space: pre-wrap; background-color: #f9f9f9; padding: 8px; border-radius: 4px; border: 1px solid #ddd; margin: 0; font-family: 'Courier New', Courier, monospace; overflow-x: auto; font-size: 0.9em; position: relative; margin-top: 5px; } pre .key { color: #c00; } pre .string { color: #080; } pre .number { color: #00f; } ` var indexTmpl = template.Must(template.New("index.html").Parse(` Example App - Login
Dex
Example App
If needed, customize your login settings below, then click Login to proceed.

`)) func renderIndex(w http.ResponseWriter) { renderTemplate(w, indexTmpl, nil) } type tokenTmplData struct { IDToken string AccessToken string RefreshToken string RedirectURL string Claims string } var tokenTmpl = template.Must(template.New("token.html").Parse(` Tokens {{ if .IDToken }}
ID Token: Decode on jwt.io
{{ .IDToken }}
{{ end }} {{ if .AccessToken }}
Access Token: Decode on jwt.io
{{ .AccessToken }}
{{ end }} {{ if .Claims }}
Claims:
{{ .Claims }}
{{ end }} {{ if .RefreshToken }}
Refresh Token:
{{ .RefreshToken }}
{{ end }} Back to Home `)) func renderToken(w http.ResponseWriter, redirectURL, idToken, accessToken, refreshToken, claims string) { renderTemplate(w, tokenTmpl, tokenTmplData{ IDToken: idToken, AccessToken: accessToken, RefreshToken: refreshToken, RedirectURL: redirectURL, Claims: claims, }) } func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interface{}) { err := tmpl.Execute(w, data) if err == nil { return } switch err := err.(type) { case *template.Error: // An ExecError guarantees that Execute has not written to the underlying reader. log.Printf("Error rendering template %s: %s", tmpl.Name(), err) // TODO(ericchiang): replace with better internal server error. http.Error(w, "Internal server error", http.StatusInternalServerError) default: // An error with the underlying write, such as the connection being // dropped. Ignore for now. } }