From dfea953381f9dff3f6587257fdabea8b9f1e1352 Mon Sep 17 00:00:00 2001 From: sam Date: Sat, 17 Feb 2024 03:31:39 +0100 Subject: [PATCH] feat: add email/password signup --- backend/routes/v2/auth/email_signup.go | 2 - backend/routes/v2/auth/send_email.go | 1 + backend/routes/v2/auth/templates/signup.html | 2 +- backend/routes/v2/auth/templates/signup.txt | 2 +- frontend/src/routes/auth/login/+page.svelte | 4 +- .../src/routes/auth/signup/+page.server.ts | 57 +++++++++++++ frontend/src/routes/auth/signup/+page.svelte | 83 +++++++++++++++++++ .../signup/confirm/[ticket]/+page.server.ts | 39 +++++++++ .../auth/signup/confirm/[ticket]/+page.svelte | 48 +++++++++++ 9 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 frontend/src/routes/auth/signup/+page.server.ts create mode 100644 frontend/src/routes/auth/signup/+page.svelte create mode 100644 frontend/src/routes/auth/signup/confirm/[ticket]/+page.server.ts create mode 100644 frontend/src/routes/auth/signup/confirm/[ticket]/+page.svelte diff --git a/backend/routes/v2/auth/email_signup.go b/backend/routes/v2/auth/email_signup.go index 28c4022..989c139 100644 --- a/backend/routes/v2/auth/email_signup.go +++ b/backend/routes/v2/auth/email_signup.go @@ -1,7 +1,6 @@ package auth import ( - "fmt" "net/http" "strings" @@ -73,7 +72,6 @@ func (s *Server) postEmailSignupConfirm(w http.ResponseWriter, r *http.Request) } var email string - fmt.Println(emailSignupTicketKey(req.Ticket)) err = s.DB.Redis.Do(ctx, radix.Cmd(&email, "GET", emailSignupTicketKey(req.Ticket))) if err != nil { return errors.Wrap(err, "getting email signup key") diff --git a/backend/routes/v2/auth/send_email.go b/backend/routes/v2/auth/send_email.go index e327333..59cdda7 100644 --- a/backend/routes/v2/auth/send_email.go +++ b/backend/routes/v2/auth/send_email.go @@ -15,6 +15,7 @@ func (s *Server) SendEmail(to, title, template string, data map[string]any) { e := email.NewEmail() e.From = s.emailAddress e.To = []string{to} + e.Subject = title text, html, err := s.Template(template, data) if err != nil { diff --git a/backend/routes/v2/auth/templates/signup.html b/backend/routes/v2/auth/templates/signup.html index f365f03..2058064 100644 --- a/backend/routes/v2/auth/templates/signup.html +++ b/backend/routes/v2/auth/templates/signup.html @@ -11,6 +11,6 @@

Please continue creating a new pronouns.cc account by using the following link:

-

Confirm your email address

+

Confirm your email address

diff --git a/backend/routes/v2/auth/templates/signup.txt b/backend/routes/v2/auth/templates/signup.txt index 7c7b1c2..2bb1489 100644 --- a/backend/routes/v2/auth/templates/signup.txt +++ b/backend/routes/v2/auth/templates/signup.txt @@ -1,4 +1,4 @@ Please continue creating a new pronouns.cc account by using the following link: -{{.BaseURL}}/auth/email/signup/{{.Ticket}} +{{.BaseURL}}/auth/signup/confirm/{{.Ticket}} If you didn't mean to create a new account, feel free to ignore this email. diff --git a/frontend/src/routes/auth/login/+page.svelte b/frontend/src/routes/auth/login/+page.svelte index 6189f45..0cb7923 100644 --- a/frontend/src/routes/auth/login/+page.svelte +++ b/frontend/src/routes/auth/login/+page.svelte @@ -81,10 +81,10 @@
- + - +

diff --git a/frontend/src/routes/auth/signup/+page.server.ts b/frontend/src/routes/auth/signup/+page.server.ts new file mode 100644 index 0000000..f9b1d9f --- /dev/null +++ b/frontend/src/routes/auth/signup/+page.server.ts @@ -0,0 +1,57 @@ +import { PUBLIC_BASE_URL } from "$env/static/public"; +import { ErrorCode, type APIError } from "$lib/api/entities"; +import { apiFetch, fastFetch } from "$lib/api/fetch"; +import type { UrlsResponse } from "$lib/api/responses"; +import { error, redirect } from "@sveltejs/kit"; + +export const load = async ({ parent }) => { + const data = await parent(); + if (!data.email_signup) { + redirect(303, "/auth/login"); + } + + const resp = await apiFetch("/auth/urls", { + method: "POST", + body: { + callback_domain: PUBLIC_BASE_URL, + }, + }); + + return resp; +}; + +export const actions = { + signup: async ({ request }) => { + const data = await request.formData(); + const email = data.get("email"); + + try { + await fastFetch("/auth/email/signup", { + method: "POST", + version: 2, + body: { email }, + }); + + return { status: "ok", email }; + } catch (e) { + return { status: "error", error: e as APIError }; + } + }, + + fedi: async ({ request }) => { + const data = await request.formData(); + const instance = data.get("instance"); + if (!instance) error(400, { code: ErrorCode.BadRequest, message: "Empty instance domain" }); + + let resp: { url: string }; + try { + resp = await apiFetch<{ url: string }>( + `/auth/urls/fediverse?instance=${encodeURIComponent(instance as string)}`, + {}, + ); + } catch (e) { + return { status: "error", error: e as APIError }; + } + redirect(303, resp.url); + }, +}; diff --git a/frontend/src/routes/auth/signup/+page.svelte b/frontend/src/routes/auth/signup/+page.svelte new file mode 100644 index 0000000..ba946d2 --- /dev/null +++ b/frontend/src/routes/auth/signup/+page.svelte @@ -0,0 +1,83 @@ + + + + Sign up - pronouns.ccc + + +

Sign up

+ +

+ Enter your email address to get started. After confirming it, you can choose a username and + password. +

+ + + {#if form?.error} + + {/if} + + {#if ok} + +

Check your email

+ Check your email to continue signing up! +
+ {/if} + + + {#if !ok} + + {:else} + + {/if} + +

+ +

+ + +
+ +

Or, if you would rather sign up using another provider:

+ +
+
+ {#if data.discord} + + {/if} + {#if data.tumblr} + + {/if} + {#if data.google} + + {/if} +
+ +
+
+ + + + +
+
+
diff --git a/frontend/src/routes/auth/signup/confirm/[ticket]/+page.server.ts b/frontend/src/routes/auth/signup/confirm/[ticket]/+page.server.ts new file mode 100644 index 0000000..8a17e81 --- /dev/null +++ b/frontend/src/routes/auth/signup/confirm/[ticket]/+page.server.ts @@ -0,0 +1,39 @@ +import { ErrorCode, type APIError, type MeUser } from "$lib/api/entities"; +import { apiFetch } from "$lib/api/fetch"; + +export const load = async ({ params }) => { + return { ticket: params.ticket }; +}; + +interface SignupConfirmData { + user: MeUser; + token: string; +} + +export const actions = { + default: async ({ request, params }) => { + const data = await request.formData(); + const username = data.get("username"); + const password = data.get("password"); + const password2 = data.get("password2"); + + if (password !== password2) { + return { + status: "error", + error: { code: ErrorCode.BadRequest, message: "Passwords do not match" } as APIError, + }; + } + + try { + const resp = await apiFetch("/auth/email/signup/confirm", { + method: "POST", + version: 2, + body: { username, password, ticket: params.ticket }, + }); + + return { status: "ok", data: resp }; + } catch (e) { + return { status: "error", error: e as APIError }; + } + }, +}; diff --git a/frontend/src/routes/auth/signup/confirm/[ticket]/+page.svelte b/frontend/src/routes/auth/signup/confirm/[ticket]/+page.svelte new file mode 100644 index 0000000..f4c29a4 --- /dev/null +++ b/frontend/src/routes/auth/signup/confirm/[ticket]/+page.svelte @@ -0,0 +1,48 @@ + + + + Sign up - pronouns.cc + + +

Sign up

+ +
+ {#if form?.error} + + {/if} + + + + + + + + + + +

+ +

+