@@ -12,11 +12,14 @@ type LinkRequest struct {
1212 ProfileID uint32 `json:"pid"`
1313 DiscordID string `json:"discordID"`
1414 Action string `json:"action"`
15+ Force bool `json:"force"`
1516}
1617
1718type LinkResponse struct {
1819 Success bool
1920 Error string
21+ // The overwritten discordID if forcing.
22+ Replaced string
2023}
2124
2225var LinkRoute = MakeRouteSpec [LinkRequest , LinkResponse ](
@@ -59,11 +62,36 @@ func HandleLink(req any, _ bool, _ *http.Request) (any, int, error) {
5962 }
6063
6164 linkStage , discordID , err := gpcm .GetSessionDiscordInfo (_req .ProfileID )
62- if err != nil {
65+ // If forcing, then we don't care about the session
66+ if err != nil && ! _req .Force {
6367 return res , http .StatusInternalServerError , gpcm .ErrNoSession
6468 }
6569
6670 if _req .Action == "link" {
71+ // This is kind of just stuck in here, bits of duplicate code. Should
72+ // be cleaned up eventually.
73+ if _req .Force {
74+ user , err := database .GetProfile (pool , ctx , _req .ProfileID )
75+ if err != nil {
76+ return res , http .StatusInternalServerError , ErrUserQuery
77+ }
78+
79+ if user .DiscordID != "" {
80+ res .Replaced = user .DiscordID
81+ }
82+
83+ // Ignore any errors. If we can set the session, great, but when
84+ // forcing a link we don't need the session to exist.
85+ _ = gpcm .SetSessionDiscordInfo (_req .ProfileID , database .LS_FINISHED , _req .DiscordID )
86+
87+ // ID is persisted to DB finally
88+ if user .UpdateDiscordID (pool , ctx , _req .DiscordID ) != nil {
89+ return res , http .StatusInternalServerError , ErrTransaction
90+ }
91+
92+ return res , http .StatusOK , nil
93+ }
94+
6795 // LinkStage is not persisted in the DB (so if the server resets in the
6896 // middle of linking, nothing has persisted so it cannot get stuck in
6997 // an invalid state). Field is inferred to be LS_FINISHED on load from
0 commit comments