diff --git a/backend/routes/auth/discord.go b/backend/routes/auth/discord.go index 036bcd5..8d3f088 100644 --- a/backend/routes/auth/discord.go +++ b/backend/routes/auth/discord.go @@ -153,6 +153,56 @@ func (s *Server) discordCallback(w http.ResponseWriter, r *http.Request) error { return nil } +type linkRequest struct { + Ticket string `json:"ticket"` +} + +func (s *Server) discordLink(w http.ResponseWriter, r *http.Request) error { + ctx := r.Context() + + claims, _ := server.ClaimsFromContext(ctx) + + // only site tokens can be used for this endpoint + if claims.APIToken || !claims.TokenWrite { + return server.APIError{Code: server.ErrInvalidToken} + } + + req, err := Decode[linkRequest](r) + if err != nil { + return server.APIError{Code: server.ErrBadRequest} + } + + u, err := s.DB.User(ctx, claims.UserID) + if err != nil { + return errors.Wrap(err, "getting user") + } + + if u.Discord != nil { + return server.APIError{Code: server.ErrAlreadyLinked} + } + + du := new(discordgo.User) + err = s.DB.GetJSON(ctx, "discord:"+req.Ticket, &du) + if err != nil { + log.Errorf("getting discord user for ticket: %v", err) + + return server.APIError{Code: server.ErrInvalidTicket} + } + + err = u.UpdateFromDiscord(ctx, s.DB, du) + if err != nil { + return errors.Wrap(err, "updating user from discord") + } + + fields, err := s.DB.UserFields(ctx, u.ID) + if err != nil { + return errors.Wrap(err, "getting user fields") + } + + render.JSON(w, r, dbUserToUserResponse(u, fields)) + return nil +} + type discordSignupRequest struct { Ticket string `json:"ticket"` Username string `json:"username"` diff --git a/backend/routes/auth/fedi_mastodon.go b/backend/routes/auth/fedi_mastodon.go index 0650a73..413bab8 100644 --- a/backend/routes/auth/fedi_mastodon.go +++ b/backend/routes/auth/fedi_mastodon.go @@ -184,6 +184,11 @@ func (s *Server) mastodonLink(w http.ResponseWriter, r *http.Request) error { claims, _ := server.ClaimsFromContext(ctx) + // only site tokens can be used for this endpoint + if claims.APIToken || !claims.TokenWrite { + return server.APIError{Code: server.ErrInvalidToken} + } + req, err := Decode[fediLinkRequest](r) if err != nil { return server.APIError{Code: server.ErrBadRequest} diff --git a/backend/routes/auth/routes.go b/backend/routes/auth/routes.go index 9f5baba..f8640fb 100644 --- a/backend/routes/auth/routes.go +++ b/backend/routes/auth/routes.go @@ -79,7 +79,7 @@ func Mount(srv *server.Server, r chi.Router) { // takes discord signup ticket to register account r.Post("/signup", server.WrapHandler(s.discordSignup)) // takes discord signup ticket to link to existing account - r.With(server.MustAuth).Post("/add-provider", server.WrapHandler(nil)) + r.With(server.MustAuth).Post("/add-provider", server.WrapHandler(s.discordLink)) }) r.Route("/mastodon", func(r chi.Router) { diff --git a/frontend/src/routes/auth/login/discord/+page.svelte b/frontend/src/routes/auth/login/discord/+page.svelte index 93d2d76..c26f486 100644 --- a/frontend/src/routes/auth/login/discord/+page.svelte +++ b/frontend/src/routes/auth/login/discord/+page.svelte @@ -1,10 +1,10 @@ @@ -80,33 +95,45 @@ {#if data.error} {/if} -{#if data.ticket} +{#if data.ticket && $userStore} +
+ + + +
+
+ + + +
+
+ + +
+{:else if data.ticket}
- - + + +
- - + + +
{#if data.require_invite}
- - + + +
You currently need an invite code to sign up. You can get one from an existing user.
{/if} -
+
By signing up, you agree to the terms of service and the privacy policy.
diff --git a/frontend/src/routes/auth/login/mastodon/[instance]/+page.svelte b/frontend/src/routes/auth/login/mastodon/[instance]/+page.svelte index 971815c..ac3c7e8 100644 --- a/frontend/src/routes/auth/login/mastodon/[instance]/+page.svelte +++ b/frontend/src/routes/auth/login/mastodon/[instance]/+page.svelte @@ -1,6 +1,6 @@