FauziIsyrinApridal commited on
Commit
486c2a9
·
1 Parent(s): 1266fe8
Files changed (1) hide show
  1. app/auth.py +56 -49
app/auth.py CHANGED
@@ -6,41 +6,21 @@ from app.db import supabase
6
 
7
  def auth_view():
8
  """Render Supabase authentication with Login, Register, and Forgot Password tabs."""
9
-
10
- # --- Redirect handler: ubah fragment (#...) jadi query (?) sekali saja ---
11
- st.markdown(
12
- """
13
- <script>
14
- (function(){
15
- const hash = window.location.hash.startsWith('#') ? window.location.hash.substring(1) : window.location.hash;
16
- if (hash && !window.__hashMigrated) {
17
- const h = new URLSearchParams(hash);
18
- const qp = new URLSearchParams(window.location.search);
19
- for (const [k,v] of h.entries()) { qp.set(k, v); }
20
- const newUrl = window.location.pathname + '?' + qp.toString();
21
- window.history.replaceState(null, '', newUrl);
22
- window.location.hash = '';
23
- window.__hashMigrated = true;
24
- window.location.replace(newUrl); // redirect bersih
25
- }
26
- })();
27
- </script>
28
- """,
29
- unsafe_allow_html=True,
30
- )
31
-
32
- # --- Wrapper (centered) for all auth content ---
33
  left, center, right = st.columns([1, 2, 1])
34
  with center:
35
- # Header: PNP logo + title
 
36
  logo_path = os.path.join("assets", "pnp-logo.png")
37
 
 
38
  def get_base64_image(path):
39
  with open(path, "rb") as f:
40
  return base64.b64encode(f.read()).decode()
41
 
42
  encoded_logo = get_base64_image(logo_path)
43
 
 
44
  st.markdown(
45
  f"""
46
  <div style="text-align:center;">
@@ -51,7 +31,32 @@ def auth_view():
51
  unsafe_allow_html=True
52
  )
53
 
54
- # --- Password recovery flow ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  try:
56
  qp = st.query_params # Streamlit >= 1.30
57
  get_q = lambda k: qp.get(k, None)
@@ -77,42 +82,44 @@ def auth_view():
77
  st.error("Token pemulihan tidak ditemukan. Coba klik ulang tautan dari email.")
78
  else:
79
  try:
 
80
  supabase.auth.set_session(access_token, refresh_token)
 
81
  supabase.auth.update_user({"password": npw})
82
  st.success("Password berhasil diubah. Silakan login kembali.")
83
-
84
- # Bersihkan query param biar URL rapi
85
- st.markdown(
86
- """
87
- <script>
88
- (function(){
89
- const qp = new URLSearchParams(window.location.search);
90
- ["type","access_token","refresh_token","expires_in","expires_at","token_type"].forEach(k=>qp.delete(k));
91
- const newUrl = window.location.pathname + (qp.toString()?('?'+qp.toString()):'');
92
- window.history.replaceState(null, '', newUrl);
93
- })();
94
- </script>
95
- """,
96
- unsafe_allow_html=True,
97
- )
98
-
99
- # langsung rerun supaya balik ke tampilan login
100
- st.rerun()
101
-
102
  except Exception as e:
103
  st.error(f"Gagal mengubah password: {e}")
 
104
  return
105
 
106
- # --- Auth tabs ---
107
  tab_login, tab_register, tab_forgot = st.tabs(["Login", "Register", "Forgot Password"])
108
 
109
- # Login tab
110
  with tab_login:
111
  with st.form("login_form"):
112
  email = st.text_input("Email")
113
  password = st.text_input("Password", type="password")
114
  submitted = st.form_submit_button("Login")
115
  if submitted:
 
116
  shared_pw = os.getenv("APP_DEMO_PASSWORD")
117
  if shared_pw and password == shared_pw:
118
  st.session_state["user"] = {"id": "demo-user", "email": email or "demo@example.com"}
@@ -139,7 +146,6 @@ def auth_view():
139
  except Exception as e:
140
  st.error(f"Gagal login: {e}")
141
 
142
- # Register tab
143
  with tab_register:
144
  st.caption("Buat akun baru. Anda akan menerima email konfirmasi.")
145
  with st.form("register_form"):
@@ -152,6 +158,7 @@ def auth_view():
152
  st.error("Password tidak sama.")
153
  else:
154
  try:
 
155
  redirect_url = os.getenv(
156
  "SUPABASE_EMAIL_REDIRECT",
157
  os.getenv("NEXT_PUBLIC_SITE_URL", "http://localhost:8501"),
@@ -165,7 +172,6 @@ def auth_view():
165
  except Exception as e:
166
  st.error(f"Gagal registrasi: {e}")
167
 
168
- # Forgot password tab
169
  with tab_forgot:
170
  st.caption("Kirim tautan reset password ke email Anda.")
171
  with st.form("forgot_form"):
@@ -173,6 +179,7 @@ def auth_view():
173
  submitted_f = st.form_submit_button("Kirim Link Reset")
174
  if submitted_f:
175
  try:
 
176
  redirect_url = os.getenv(
177
  "SUPABASE_EMAIL_REDIRECT",
178
  os.getenv("NEXT_PUBLIC_SITE_URL", "http://localhost:8501"),
 
6
 
7
  def auth_view():
8
  """Render Supabase authentication with Login, Register, and Forgot Password tabs."""
9
+ # Wrapper (centered) for all auth content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  left, center, right = st.columns([1, 2, 1])
11
  with center:
12
+ # Header: smaller PNP logo and centered title
13
+ # Path logo
14
  logo_path = os.path.join("assets", "pnp-logo.png")
15
 
16
+ # Convert ke base64 biar bisa di-embed langsung
17
  def get_base64_image(path):
18
  with open(path, "rb") as f:
19
  return base64.b64encode(f.read()).decode()
20
 
21
  encoded_logo = get_base64_image(logo_path)
22
 
23
+ # Render dalam satu div center
24
  st.markdown(
25
  f"""
26
  <div style="text-align:center;">
 
31
  unsafe_allow_html=True
32
  )
33
 
34
+ # --- Password recovery handler (Supabase redirect) ---
35
+ # 1) Move hash params to query params on first load, then reload once
36
+ if not st.session_state.get("_hash_migrated"):
37
+ st.markdown(
38
+ """
39
+ <script>
40
+ (function(){
41
+ const hash = window.location.hash.startsWith('#') ? window.location.hash.substring(1) : window.location.hash;
42
+ if (hash && !window.__hashMigrated) {
43
+ const h = new URLSearchParams(hash);
44
+ const qp = new URLSearchParams(window.location.search);
45
+ for (const [k,v] of h.entries()) { qp.set(k, v); }
46
+ const newUrl = window.location.pathname + '?' + qp.toString();
47
+ window.history.replaceState(null, '', newUrl);
48
+ window.location.hash = '';
49
+ window.__hashMigrated = true;
50
+ window.location.reload();
51
+ }
52
+ })();
53
+ </script>
54
+ """,
55
+ unsafe_allow_html=True,
56
+ )
57
+ st.session_state["_hash_migrated"] = True
58
+
59
+ # 2) Read query params for recovery flow
60
  try:
61
  qp = st.query_params # Streamlit >= 1.30
62
  get_q = lambda k: qp.get(k, None)
 
82
  st.error("Token pemulihan tidak ditemukan. Coba klik ulang tautan dari email.")
83
  else:
84
  try:
85
+ # Set current session using tokens from redirect
86
  supabase.auth.set_session(access_token, refresh_token)
87
+ # Update user password
88
  supabase.auth.update_user({"password": npw})
89
  st.success("Password berhasil diubah. Silakan login kembali.")
90
+ # Optional: clear recovery query params
91
+ try:
92
+ # Best-effort to clear params
93
+ st.markdown(
94
+ """
95
+ <script>
96
+ (function(){
97
+ const qp = new URLSearchParams(window.location.search);
98
+ ["type","access_token","refresh_token","expires_in","expires_at","token_type"].forEach(k=>qp.delete(k));
99
+ const newUrl = window.location.pathname + (qp.toString()?('?'+qp.toString()):'');
100
+ window.history.replaceState(null, '', newUrl);
101
+ })();
102
+ </script>
103
+ """,
104
+ unsafe_allow_html=True,
105
+ )
106
+ except Exception:
107
+ pass
 
108
  except Exception as e:
109
  st.error(f"Gagal mengubah password: {e}")
110
+ # When in recovery mode, do not render login/register tabs
111
  return
112
 
113
+ # Auth tabs inside wrapper
114
  tab_login, tab_register, tab_forgot = st.tabs(["Login", "Register", "Forgot Password"])
115
 
 
116
  with tab_login:
117
  with st.form("login_form"):
118
  email = st.text_input("Email")
119
  password = st.text_input("Password", type="password")
120
  submitted = st.form_submit_button("Login")
121
  if submitted:
122
+ # Demo password fallback
123
  shared_pw = os.getenv("APP_DEMO_PASSWORD")
124
  if shared_pw and password == shared_pw:
125
  st.session_state["user"] = {"id": "demo-user", "email": email or "demo@example.com"}
 
146
  except Exception as e:
147
  st.error(f"Gagal login: {e}")
148
 
 
149
  with tab_register:
150
  st.caption("Buat akun baru. Anda akan menerima email konfirmasi.")
151
  with st.form("register_form"):
 
158
  st.error("Password tidak sama.")
159
  else:
160
  try:
161
+ # Prefer explicit env, then generic site URL, then localhost for dev
162
  redirect_url = os.getenv(
163
  "SUPABASE_EMAIL_REDIRECT",
164
  os.getenv("NEXT_PUBLIC_SITE_URL", "http://localhost:8501"),
 
172
  except Exception as e:
173
  st.error(f"Gagal registrasi: {e}")
174
 
 
175
  with tab_forgot:
176
  st.caption("Kirim tautan reset password ke email Anda.")
177
  with st.form("forgot_form"):
 
179
  submitted_f = st.form_submit_button("Kirim Link Reset")
180
  if submitted_f:
181
  try:
182
+ # Prefer explicit env, then generic site URL, then localhost for dev
183
  redirect_url = os.getenv(
184
  "SUPABASE_EMAIL_REDIRECT",
185
  os.getenv("NEXT_PUBLIC_SITE_URL", "http://localhost:8501"),