+5
-6
appview/oauth/handler/handler.go
+5
-6
appview/oauth/handler/handler.go
···
35
35
func (o *OAuthHandler) Router() http.Handler {
36
36
r := chi.NewRouter()
37
37
38
-
// gets mounted on /oauth
39
-
r.Get("/client-metadata.json", o.clientMetadata)
40
-
r.Get("/jwks.json", o.jwks)
41
38
r.Get("/login", o.login)
42
39
r.Post("/login", o.login)
43
-
r.Get("/callback", o.callback)
40
+
41
+
r.Get("/oauth/client-metadata.json", o.clientMetadata)
42
+
r.Get("/oauth/jwks.json", o.jwks)
43
+
r.Get("/oauth/callback", o.callback)
44
44
return r
45
45
}
46
46
···
84
84
json.NewEncoder(w).Encode(response)
85
85
}
86
86
87
-
// temporary until we swap out the main login page
88
87
func (o *OAuthHandler) login(w http.ResponseWriter, r *http.Request) {
89
88
switch r.Method {
90
89
case http.MethodGet:
91
-
o.Pages.OAuthLogin(w, pages.LoginParams{})
90
+
o.Pages.Login(w, pages.LoginParams{})
92
91
case http.MethodPost:
93
92
handle := strings.TrimPrefix(r.FormValue("handle"), "@")
94
93
-4
appview/pages/pages.go
-4
appview/pages/pages.go
···
249
249
return p.executePlain("user/login", w, params)
250
250
}
251
251
252
-
func (p *Pages) OAuthLogin(w io.Writer, params LoginParams) error {
253
-
return p.executePlain("user/oauthlogin", w, params)
254
-
}
255
-
256
252
type TimelineParams struct {
257
253
LoggedInUser *oauth.User
258
254
Timeline []db.TimelineEvent
+22
-33
appview/pages/templates/user/login.html
+22
-33
appview/pages/templates/user/login.html
···
8
8
content="width=device-width, initial-scale=1.0"
9
9
/>
10
10
<script src="/static/htmx.min.js"></script>
11
-
<link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" />
11
+
<link
12
+
rel="stylesheet"
13
+
href="/static/tw.css?{{ cssContentHash }}"
14
+
type="text/css"
15
+
/>
12
16
<title>login</title>
13
17
</head>
14
18
<body class="flex items-center justify-center min-h-screen">
15
-
<main class="max-w-7xl px-6 -mt-4">
16
-
<h1 class="text-center text-2xl font-semibold italic dark:text-white">
19
+
<main class="max-w-md px-6 -mt-4">
20
+
<h1
21
+
class="text-center text-2xl font-semibold italic dark:text-white"
22
+
>
17
23
tangled
18
24
</h1>
19
25
<h2 class="text-center text-xl italic dark:text-white">
20
26
tightly-knit social coding.
21
27
</h2>
22
28
<form
23
-
class="w-full mt-4"
24
-
hx-post="/login"
29
+
class="mt-4 max-w-sm mx-auto"
30
+
hx-post="/oauth/login"
25
31
hx-swap="none"
26
32
hx-disabled-elt="this"
27
33
>
28
34
<div class="flex flex-col">
29
35
<label for="handle">handle</label>
30
-
<input
31
-
type="text"
32
-
id="handle"
33
-
name="handle"
34
-
tabindex="1"
35
-
required
36
-
/>
37
-
<span class="text-xs text-gray-500 mt-1">
38
-
You need to use your
39
-
<a href="https://bsky.app">Bluesky</a> handle to log
40
-
in.
41
-
</span>
42
-
</div>
43
-
44
-
<div class="flex flex-col mt-2">
45
-
<label for="app_password">app password</label>
46
36
<input
47
-
type="password"
48
-
id="app_password"
49
-
name="app_password"
50
-
tabindex="2"
37
+
type="text"
38
+
id="handle"
39
+
name="handle"
40
+
tabindex="1"
51
41
required
52
42
/>
53
-
<span class="text-xs text-gray-500 mt-1">
54
-
Generate an app password
55
-
<a
56
-
href="https://bsky.app/settings/app-passwords"
57
-
target="_blank"
58
-
>here</a
59
-
>.
43
+
<span class="text-sm text-gray-500 mt-1">
44
+
Use your
45
+
<a href="https://bsky.app">Bluesky</a> handle to log
46
+
in. You will then be redirected to your PDS to
47
+
complete authentication.
60
48
</span>
61
49
</div>
62
50
···
70
58
</button>
71
59
</form>
72
60
<p class="text-sm text-gray-500">
73
-
Join our <a href="https://chat.tangled.sh">Discord</a> or IRC channel:
61
+
Join our <a href="https://chat.tangled.sh">Discord</a> or
62
+
IRC channel:
74
63
<a href="https://web.libera.chat/#tangled"
75
64
><code>#tangled</code> on Libera Chat</a
76
65
>.
-71
appview/pages/templates/user/oauthlogin.html
-71
appview/pages/templates/user/oauthlogin.html
···
1
-
{{ define "user/oauthlogin" }}
2
-
<!doctype html>
3
-
<html lang="en" class="dark:bg-gray-900">
4
-
<head>
5
-
<meta charset="UTF-8" />
6
-
<meta
7
-
name="viewport"
8
-
content="width=device-width, initial-scale=1.0"
9
-
/>
10
-
<script src="/static/htmx.min.js"></script>
11
-
<link
12
-
rel="stylesheet"
13
-
href="/static/tw.css?{{ cssContentHash }}"
14
-
type="text/css"
15
-
/>
16
-
<title>login</title>
17
-
</head>
18
-
<body class="flex items-center justify-center min-h-screen">
19
-
<main class="max-w-7xl px-6 -mt-4">
20
-
<h1
21
-
class="text-center text-2xl font-semibold italic dark:text-white"
22
-
>
23
-
tangled
24
-
</h1>
25
-
<h2 class="text-center text-xl italic dark:text-white">
26
-
tightly-knit social coding.
27
-
</h2>
28
-
<form
29
-
class="w-full mt-4"
30
-
hx-post="/oauth/login"
31
-
hx-swap="none"
32
-
hx-disabled-elt="this"
33
-
>
34
-
<div class="flex flex-col">
35
-
<label for="handle">handle</label>
36
-
<input
37
-
type="text"
38
-
id="handle"
39
-
name="handle"
40
-
tabindex="1"
41
-
required
42
-
/>
43
-
<span class="text-xs text-gray-500 mt-1">
44
-
Use your
45
-
<a href="https://bsky.app">Bluesky</a> handle to log
46
-
in. You will then be redirected to your PDS to
47
-
complete authentication.
48
-
</span>
49
-
</div>
50
-
51
-
<button
52
-
class="btn w-full my-2 mt-6"
53
-
type="submit"
54
-
id="login-button"
55
-
tabindex="3"
56
-
>
57
-
<span>login</span>
58
-
</button>
59
-
</form>
60
-
<p class="text-sm text-gray-500">
61
-
Join our <a href="https://chat.tangled.sh">Discord</a> or
62
-
IRC channel:
63
-
<a href="https://web.libera.chat/#tangled"
64
-
><code>#tangled</code> on Libera Chat</a
65
-
>.
66
-
</p>
67
-
<p id="login-msg" class="error w-full"></p>
68
-
</main>
69
-
</body>
70
-
</html>
71
-
{{ end }}
+1
-6
appview/state/router.go
+1
-6
appview/state/router.go
···
200
200
201
201
r.With(middleware.AuthMiddleware(s.oauth)).Post("/logout", s.Logout)
202
202
203
-
// r.Route("/login", func(r chi.Router) {
204
-
// r.Get("/", s.Login)
205
-
// r.Post("/", s.Login)
206
-
// })
207
-
208
203
r.Route("/knots", func(r chi.Router) {
209
204
r.Use(middleware.AuthMiddleware(s.oauth))
210
205
r.Get("/", s.Knots)
···
250
245
})
251
246
252
247
r.Mount("/settings", s.SettingsRouter())
253
-
r.Mount("/oauth", s.OAuthRouter())
248
+
r.Mount("/", s.OAuthRouter())
254
249
r.Get("/keys/{user}", s.Keys)
255
250
256
251
r.NotFound(func(w http.ResponseWriter, r *http.Request) {