1package state
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7 "strings"
8
9 "tangled.org/core/appview/pages"
10)
11
12func (s *State) Login(w http.ResponseWriter, r *http.Request) {
13 switch r.Method {
14 case http.MethodGet:
15 returnURL := r.URL.Query().Get("return_url")
16 s.pages.Login(w, pages.LoginParams{
17 ReturnUrl: returnURL,
18 })
19 case http.MethodPost:
20 handle := r.FormValue("handle")
21
22 // when users copy their handle from bsky.app, it tends to have these characters around it:
23 //
24 // @nelind.dk:
25 // \u202a ensures that the handle is always rendered left to right and
26 // \u202c reverts that so the rest of the page renders however it should
27 handle = strings.TrimPrefix(handle, "\u202a")
28 handle = strings.TrimSuffix(handle, "\u202c")
29
30 // `@` is harmless
31 handle = strings.TrimPrefix(handle, "@")
32
33 // basic handle validation
34 if !strings.Contains(handle, ".") {
35 log.Println("invalid handle format", "raw", handle)
36 s.pages.Notice(
37 w,
38 "login-msg",
39 fmt.Sprintf("\"%s\" is an invalid handle. Did you mean %s.bsky.social or %s.tngl.sh?", handle, handle, handle),
40 )
41 return
42 }
43
44 redirectURL, err := s.oauth.ClientApp.StartAuthFlow(r.Context(), handle)
45 if err != nil {
46 http.Error(w, err.Error(), http.StatusInternalServerError)
47 return
48 }
49
50 s.pages.HxRedirect(w, redirectURL)
51 }
52}
53
54func (s *State) Logout(w http.ResponseWriter, r *http.Request) {
55 err := s.oauth.DeleteSession(w, r)
56 if err != nil {
57 log.Println("failed to logout", "err", err)
58 } else {
59 log.Println("logged out successfully")
60 }
61
62 s.pages.HxRedirect(w, "/login")
63}