Scrollable code
This commit is contained in:
parent
bd514dd1e9
commit
56f09d6d49
60
login.go
60
login.go
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
const EDGEDB_AUTH_BASE_URL = "http://127.0.0.1:10700/db/main/ext/auth"
|
const EDGEDB_AUTH_BASE_URL = "http://127.0.0.1:10700/db/main/ext/auth"
|
||||||
|
|
||||||
func generatePKCE() (string, string) {
|
func generatePKCE() (string, string) {
|
||||||
|
fmt.Println("Generating PKCE")
|
||||||
verifier := make([]byte, 32)
|
verifier := make([]byte, 32)
|
||||||
_, err := rand.Read(verifier)
|
_, err := rand.Read(verifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -22,7 +24,16 @@ func generatePKCE() (string, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
challenge := sha256.Sum256(verifier)
|
challenge := sha256.Sum256(verifier)
|
||||||
return base64.RawURLEncoding.EncodeToString(verifier), base64.RawURLEncoding.EncodeToString(challenge[:])
|
|
||||||
|
var URLEncoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")
|
||||||
|
var RawURLEncoding = URLEncoding.WithPadding(base64.NoPadding)
|
||||||
|
encodedVerifier := RawURLEncoding.EncodeToString(verifier)
|
||||||
|
encodedChallenge := RawURLEncoding.EncodeToString(challenge[:])
|
||||||
|
|
||||||
|
fmt.Println("verifier: " + encodedVerifier)
|
||||||
|
fmt.Println("challenge: " + encodedChallenge)
|
||||||
|
|
||||||
|
return encodedVerifier, encodedChallenge
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUiSignIn(c *fiber.Ctx) error {
|
func handleUiSignIn(c *fiber.Ctx) error {
|
||||||
@ -31,18 +42,13 @@ func handleUiSignIn(c *fiber.Ctx) error {
|
|||||||
fmt.Println("handleUiSignIn verifier: " + verifier)
|
fmt.Println("handleUiSignIn verifier: " + verifier)
|
||||||
fmt.Println("handleUiSignIn challenge: " + challenge)
|
fmt.Println("handleUiSignIn challenge: " + challenge)
|
||||||
|
|
||||||
redirectURL := fmt.Sprintf("%s/ui/signin?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge)
|
cookie := new(fiber.Cookie)
|
||||||
|
cookie.Name = "jade-edgedb-pkce-verifier"
|
||||||
|
cookie.Value = verifier
|
||||||
|
cookie.Expires = time.Now().Add(10 * time.Minute)
|
||||||
|
c.Cookie(cookie)
|
||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
return c.Redirect(fmt.Sprintf("%s/ui/signup?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge), fiber.StatusTemporaryRedirect)
|
||||||
Name: "jade-edgedb-pkce-verifier",
|
|
||||||
Value: verifier,
|
|
||||||
HTTPOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
Secure: true,
|
|
||||||
SameSite: "Strict",
|
|
||||||
})
|
|
||||||
|
|
||||||
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUiSignUp(c *fiber.Ctx) error {
|
func handleUiSignUp(c *fiber.Ctx) error {
|
||||||
@ -51,30 +57,13 @@ func handleUiSignUp(c *fiber.Ctx) error {
|
|||||||
fmt.Println("handleUiSignUp verifier: " + verifier)
|
fmt.Println("handleUiSignUp verifier: " + verifier)
|
||||||
fmt.Println("handleUiSignUp challenge: " + challenge)
|
fmt.Println("handleUiSignUp challenge: " + challenge)
|
||||||
|
|
||||||
redirectURL := fmt.Sprintf("%s/ui/signup?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge)
|
cookie := new(fiber.Cookie)
|
||||||
|
cookie.Name = "jade-edgedb-pkce-verifier"
|
||||||
|
cookie.Value = verifier
|
||||||
|
cookie.Expires = time.Now().Add(10 * time.Minute)
|
||||||
|
c.Cookie(cookie)
|
||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
return c.Redirect(fmt.Sprintf("%s/ui/signup?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge), fiber.StatusTemporaryRedirect)
|
||||||
Name: "jade-edgedb-pkce-verifier",
|
|
||||||
Value: verifier,
|
|
||||||
HTTPOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
Secure: true,
|
|
||||||
SameSite: "Strict",
|
|
||||||
})
|
|
||||||
|
|
||||||
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleCallbackSignup(c *fiber.Ctx) error {
|
|
||||||
code := c.Query("code")
|
|
||||||
fmt.Println("Callback signup code: " + code)
|
|
||||||
|
|
||||||
verifier := c.Cookies("jade-edgedb-pkce-verifier")
|
|
||||||
if verifier == "" {
|
|
||||||
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.SendString("OK")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCallback(c *fiber.Ctx) error {
|
func handleCallback(c *fiber.Ctx) error {
|
||||||
@ -93,6 +82,7 @@ func handleCallback(c *fiber.Ctx) error {
|
|||||||
fmt.Println("handleCallback verifier: " + verifier)
|
fmt.Println("handleCallback verifier: " + verifier)
|
||||||
|
|
||||||
codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier)
|
codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier)
|
||||||
|
fmt.Println("codeExchangeURL: " + codeExchangeURL)
|
||||||
resp, err := http.Get(codeExchangeURL)
|
resp, err := http.Get(codeExchangeURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error()))
|
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error()))
|
||||||
|
7
main.go
7
main.go
@ -42,10 +42,9 @@ func main() {
|
|||||||
app.Get("/generateMultipleMessages", GenerateMultipleMessages) // Generate multiple messages
|
app.Get("/generateMultipleMessages", GenerateMultipleMessages) // Generate multiple messages
|
||||||
app.Get("/messageContent", GetMessageContentHandler)
|
app.Get("/messageContent", GetMessageContentHandler)
|
||||||
|
|
||||||
app.Get("/auth/ui/signin", handleUiSignIn)
|
app.Get("/signin", handleUiSignIn)
|
||||||
app.Get("/auth/ui/signup", handleUiSignUp)
|
app.Get("/signup", handleUiSignUp)
|
||||||
app.Get("/auth/callback", handleCallback)
|
app.Get("/callback", handleCallback)
|
||||||
app.Get("/auth/callbackSignup", handleCallbackSignup)
|
|
||||||
|
|
||||||
app.Get("test", func(c *fiber.Ctx) error {
|
app.Get("test", func(c *fiber.Ctx) error {
|
||||||
fmt.Println("test")
|
fmt.Println("test")
|
||||||
|
17
static/animations.css
Normal file
17
static/animations.css
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
.message-bot.htmx-added {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-bot {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-user.htmx-added {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-user {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 1s ease-out;
|
||||||
|
}
|
109
static/style.css
Normal file
109
static/style.css
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
.my-indicator {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.htmx-request .my-indicator {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.htmx-request.my-indicator {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg text {
|
||||||
|
font-family: 'Russo One', sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
fill: #000;
|
||||||
|
stroke: #000;
|
||||||
|
font-size: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
background-color: #303030;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-messages .message-content pre {
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: pre;
|
||||||
|
max-width: 662px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-messages .message-content pre code {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 100%;
|
||||||
|
white-space: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content pre {
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: #363636 !important;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-messages {
|
||||||
|
max-width: 780px;
|
||||||
|
margin: auto;
|
||||||
|
width: 95%;
|
||||||
|
margin-bottom: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-input-form {
|
||||||
|
max-width: 900px;
|
||||||
|
margin: auto;
|
||||||
|
width: 98%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bulma-body-background-color: #202020;
|
||||||
|
--bulma-primary: #126d0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 10px;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 140px;
|
||||||
|
/* Adjust this value based on the button and dropdown width */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
1
utils.go
1
utils.go
@ -18,6 +18,7 @@ func markdownToHTML(markdownText string) string {
|
|||||||
if err := md.Convert([]byte(markdownText), &buf); err != nil {
|
if err := md.Convert([]byte(markdownText), &buf); err != nil {
|
||||||
panic(err) // Handle the error appropriately
|
panic(err) // Handle the error appropriately
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
<hx hx-get="/loadChat" hx-trigger="load" hx-swap="outerHTML"></hx>
|
<hx hx-get="/loadChat" hx-trigger="load" hx-swap="outerHTML"></hx>
|
||||||
|
|
||||||
|
|
||||||
<div class="chat-input-container mb-5">
|
<div class="chat-input-container mb-5">
|
||||||
<div class="textarea-wrapper">
|
<div class="textarea-wrapper">
|
||||||
<textarea class="textarea" placeholder="Type your message here..." name="message"></textarea>
|
<textarea class="textarea" placeholder="Type your message here..." name="message"></textarea>
|
||||||
|
@ -9,50 +9,8 @@
|
|||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Russo+One" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Russo+One" rel="stylesheet">
|
||||||
|
|
||||||
<style>
|
<link rel="stylesheet" href="/animations.css">
|
||||||
body,
|
<link rel="stylesheet" href="/style.css">
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 10px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 10px;
|
|
||||||
max-width: 800px;
|
|
||||||
/* Adjust this value to your desired maximum width */
|
|
||||||
margin: 0 auto;
|
|
||||||
/* Center the container horizontally */
|
|
||||||
}
|
|
||||||
|
|
||||||
.textarea-wrapper {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textarea {
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 140px;
|
|
||||||
/* Adjust this value based on the button and dropdown width */
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 10px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
|
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
|
||||||
</head>
|
</head>
|
||||||
@ -64,88 +22,6 @@
|
|||||||
|
|
||||||
{{embed}}
|
{{embed}}
|
||||||
|
|
||||||
<style>
|
|
||||||
.my-indicator {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.htmx-request .my-indicator {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.htmx-request.my-indicator {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Style stuff -->
|
|
||||||
|
|
||||||
<style>
|
|
||||||
svg text {
|
|
||||||
font-family: 'Russo One', sans-serif;
|
|
||||||
text-transform: uppercase;
|
|
||||||
fill: #000;
|
|
||||||
stroke: #000;
|
|
||||||
font-size: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content {
|
|
||||||
background-color: #303030;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content pre {
|
|
||||||
font-family: monospace;
|
|
||||||
background-color: #363636 !important;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat-messages {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: auto;
|
|
||||||
width: 95%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat-input-form {
|
|
||||||
max-width: 900px;
|
|
||||||
margin: auto;
|
|
||||||
width: 98%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--bulma-body-background-color: #202020;
|
|
||||||
--bulma-primary: #126d0f;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Animations stuff -->
|
|
||||||
<style>
|
|
||||||
.message-bot.htmx-added {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-bot {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 1s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-user.htmx-added {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-user {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 1s ease-out;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -14,8 +14,9 @@
|
|||||||
{{ Content|safe }}
|
{{ Content|safe }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button hx-post="/deleteMessage?id={{ ID }}" style="position: absolute; top: 3; right: 3;"
|
<button id="delete-button-{{ ID }}" hx-post="/deleteMessage?id={{ ID }}"
|
||||||
hx-swap="outerHTML" hx-target="#chat-container" class="delete" aria-label="delete"></button>
|
style="position: absolute; top: 3; right: 3;" hx-swap="outerHTML" hx-target="#chat-container"
|
||||||
|
class="delete" aria-label="delete"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="button is-light is-small" href="/auth/ui/signin">
|
<a class="button is-light is-small" href="/signin">
|
||||||
Log in
|
Log in
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-primary" href="/auth/ui/signup">
|
<a class="button is-primary" href="/signup">
|
||||||
<strong>Sign up</strong>
|
<strong>Sign up</strong>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user