Mercurial
annotate mrjunejune/src/login/index.html @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 04fee26ecce0 |
| children |
| rev | line source |
|---|---|
|
264
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
1 <!DOCTYPE html> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
2 <html lang="en" data-zen-theme="cyberpunk"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
3 <head> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
4 {{/parts/base_head.html}} |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
5 <title>Sign in — MrJuneJune</title> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
6 <style> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
7 .login-page main { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
8 display: flex; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
9 flex-direction: column; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
10 align-items: center; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
11 justify-content: center; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
12 min-height: 60vh; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
13 padding: var(--zenbu-sys-padding-lg) var(--zenbu-sys-padding-md); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
14 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
15 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
16 .login-card { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
17 width: 100%; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
18 max-width: 360px; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
19 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
20 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
21 .login-card h2 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
22 margin: 0 0 var(--zenbu-sys-padding-md); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
23 font-size: 1.4rem; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
24 font-weight: 700; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
25 text-align: center; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
26 letter-spacing: 0.08em; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
27 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
28 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
29 .login-form { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
30 display: flex; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
31 flex-direction: column; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
32 gap: var(--zenbu-sys-padding-sm); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
33 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
34 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
35 .login-actions { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
36 display: flex; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
37 justify-content: flex-end; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
38 gap: var(--zenbu-sys-space-control); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
39 margin-top: var(--zenbu-sys-padding-xs, 0.5rem); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
40 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
41 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
42 #loginError { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
43 display: none; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
44 padding: 0.6rem 0.75rem; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
45 border-left: var(--zenbu-sys-stroke-width-emphasis, 2px) solid var(--zenbu-sys-color-danger-foreground); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
46 background: color-mix(in srgb, var(--zenbu-sys-color-danger-foreground) 10%, transparent); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
47 color: var(--zenbu-sys-color-danger-foreground); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
48 font-size: 0.875rem; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
49 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
50 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
51 #loginError[aria-hidden="false"] { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
52 display: block; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
53 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
54 </style> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
55 </head> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
56 <body class="login-page"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
57 {{/parts/header.html}} |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
58 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
59 <main> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
60 <div class="login-card"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
61 <zen-heading size="xl"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
62 <h2>Sign in</h2> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
63 </zen-heading> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
64 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
65 <div id="loginError" role="alert" aria-live="assertive" aria-hidden="true"></div> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
66 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
67 <form class="login-form" id="loginForm" novalidate> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
68 <zen-field appearance="plain" size="md"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
69 <label for="username">Username</label> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
70 <input |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
71 id="username" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
72 name="username" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
73 type="text" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
74 autocomplete="username" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
75 autocapitalize="none" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
76 spellcheck="false" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
77 required |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
78 maxlength="32" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
79 > |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
80 </zen-field> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
81 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
82 <zen-field appearance="plain" size="md"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
83 <label for="password">Password</label> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
84 <input |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
85 id="password" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
86 name="password" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
87 type="password" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
88 autocomplete="current-password" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
89 required |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
90 minlength="12" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
91 maxlength="1024" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
92 > |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
93 </zen-field> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
94 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
95 <div class="login-actions"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
96 <zen-button appearance="plain" size="md"> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
97 <button type="submit" id="loginSubmit">Sign in</button> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
98 </zen-button> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
99 </div> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
100 </form> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
101 </div> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
102 </main> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
103 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
104 <script> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
105 (function () { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
106 'use strict'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
107 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
108 const form = document.getElementById('loginForm'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
109 const errorEl = document.getElementById('loginError'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
110 const submitBtn = document.getElementById('loginSubmit'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
111 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
112 function showError(message) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
113 errorEl.textContent = message; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
114 errorEl.setAttribute('aria-hidden', 'false'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
115 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
116 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
117 function hideError() { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
118 errorEl.textContent = ''; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
119 errorEl.setAttribute('aria-hidden', 'true'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
120 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
121 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
122 async function fetchSession() { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
123 const resp = await fetch('/api/auth/session', { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
124 credentials: 'same-origin', |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
125 }); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
126 if (!resp.ok) throw new Error('session unavailable'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
127 return resp.json(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
128 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
129 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
130 form.addEventListener('submit', async function (evt) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
131 evt.preventDefault(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
132 hideError(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
133 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
134 const username = form.username.value.trim(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
135 const password = form.password.value; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
136 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
137 if (!username || !password) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
138 showError('Please enter your username and password.'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
139 return; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
140 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
141 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
142 submitBtn.disabled = true; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
143 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
144 try { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
145 const session = await fetchSession(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
146 const csrfToken = session.csrfToken; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
147 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
148 const resp = await fetch('/api/auth/login', { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
149 method: 'POST', |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
150 headers: { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
151 'Content-Type': 'application/json', |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
152 'Origin': window.location.origin, |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
153 }, |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
154 credentials: 'same-origin', |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
155 body: JSON.stringify({ username, password, csrfToken }), |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
156 }); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
157 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
158 form.password.value = ''; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
159 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
160 let data = await resp.json().catch(function () { return null; }); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
161 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
162 if (!resp.ok) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
163 showError(resp.status === 429 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
164 ? 'Too many attempts. Please try again later.' |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
165 : 'Invalid username or password.'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
166 return; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
167 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
168 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
169 if (!data) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
170 data = await fetchSession(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
171 if (data.kind !== 'user') { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
172 window.location.reload(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
173 return; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
174 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
175 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
176 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
177 if (data.mustChangePassword) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
178 window.location.href = '/account/password'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
179 return; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
180 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
181 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
182 function safeNext(n) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
183 if (!n || typeof n !== 'string') return null; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
184 if (!n.startsWith('/') || n.startsWith('//') || n.startsWith('/\\')) return null; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
185 if (n.includes('\\')) return null; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
186 try { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
187 const url = new URL(n, window.location.origin); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
188 if (url.origin !== window.location.origin) return null; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
189 return url.pathname + url.search + url.hash; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
190 } catch (_) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
191 return null; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
192 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
193 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
194 const next = safeNext(new URLSearchParams(window.location.search).get('next')); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
195 window.location.href = next || '/jrpg'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
196 } catch (_) { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
197 form.password.value = ''; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
198 showError('Sign-in failed. Please try again.'); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
199 } finally { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
200 submitBtn.disabled = false; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
201 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
202 }); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
203 })(); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
204 </script> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
205 </body> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
206 </html> |