wu981526092 commited on
Commit
bfea55d
ยท
1 Parent(s): 726398b

Simplify login page and remove API key option

Browse files

โœจ Changes:
- Removed dual authentication options (HF OAuth vs API key)
- Simplified to single 'Access Research Platform' button
- Removed API key input form and JavaScript handling
- Cleaner, more focused user experience
- Back to original simple design without complexity

The login page now has a single clear path for users.

backend/dependencies.py CHANGED
@@ -111,18 +111,6 @@ def get_current_user_optional(request: Request) -> Optional[Dict[str, Any]]:
111
  logger.debug("๐Ÿ  Auth disabled - no user required")
112
  return None
113
 
114
- # Check for API key mode first
115
- api_key_header = request.headers.get("X-OpenAI-API-Key")
116
- if api_key_header and api_key_header.startswith("sk-"):
117
- logger.info("๐Ÿ”‘ User authenticated with API key mode")
118
- return {
119
- "id": "api_key_user",
120
- "username": "api_key_user",
121
- "name": "API Key User",
122
- "auth_method": "api_key",
123
- "api_key": api_key_header
124
- }
125
-
126
  # Try to get user from session
127
  try:
128
  user = request.session.get("user")
@@ -179,18 +167,6 @@ def get_current_user_required(request: Request) -> Dict[str, Any]:
179
  "auth_method": "local_dev"
180
  }
181
 
182
- # Check for API key mode first
183
- api_key_header = request.headers.get("X-OpenAI-API-Key")
184
- if api_key_header and api_key_header.startswith("sk-"):
185
- logger.info("๐Ÿ”‘ User authenticated with API key mode")
186
- return {
187
- "id": "api_key_user",
188
- "username": "api_key_user",
189
- "name": "API Key User",
190
- "auth_method": "api_key",
191
- "api_key": api_key_header
192
- }
193
-
194
  user = get_current_user_optional(request)
195
  if not user:
196
  logger.warning(f"๐Ÿšซ Authentication required for {request.url.path}")
@@ -209,19 +185,11 @@ def get_current_user_required(request: Request) -> Dict[str, Any]:
209
  def require_auth_in_hf_spaces(request: Request) -> None:
210
  """
211
  Dependency that enforces authentication only in HF Spaces.
212
- Supports both API key mode and OAuth login mode.
213
  Raises 401 if in HF Spaces and user is not authenticated.
214
  """
215
  from utils.environment import should_enable_auth
216
 
217
  if should_enable_auth():
218
- # Check for API key mode first
219
- api_key_header = request.headers.get("X-OpenAI-API-Key")
220
- if api_key_header and api_key_header.startswith("sk-"):
221
- # User is using API key mode, allow access
222
- logger.info("๐Ÿ”‘ API key authentication successful")
223
- return
224
-
225
  user = get_current_user_optional(request)
226
  if not user:
227
  logger.warning(f"๐Ÿšซ HF Spaces requires authentication for {request.url.path}")
 
111
  logger.debug("๐Ÿ  Auth disabled - no user required")
112
  return None
113
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  # Try to get user from session
115
  try:
116
  user = request.session.get("user")
 
167
  "auth_method": "local_dev"
168
  }
169
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  user = get_current_user_optional(request)
171
  if not user:
172
  logger.warning(f"๐Ÿšซ Authentication required for {request.url.path}")
 
185
  def require_auth_in_hf_spaces(request: Request) -> None:
186
  """
187
  Dependency that enforces authentication only in HF Spaces.
 
188
  Raises 401 if in HF Spaces and user is not authenticated.
189
  """
190
  from utils.environment import should_enable_auth
191
 
192
  if should_enable_auth():
 
 
 
 
 
 
 
193
  user = get_current_user_optional(request)
194
  if not user:
195
  logger.warning(f"๐Ÿšซ HF Spaces requires authentication for {request.url.path}")
backend/templates/login.html CHANGED
@@ -160,90 +160,32 @@
160
  actionable insights for AI system analysis and robustness testing.
161
  </p>
162
 
163
- <!-- Access Options -->
164
- <div class="space-y-6">
165
- <!-- Option 1: Use Our Service -->
166
- <div class="space-y-4">
167
- <h3 class="text-lg font-semibold text-foreground">
168
- Option 1: Use Our Service
169
- </h3>
170
- <a
171
- href="/auth/login"
172
- class="btn-primary inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg transition-all duration-300 group w-full"
 
 
173
  >
174
- Login with Hugging Face
175
- <svg
176
- class="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1"
177
- fill="none"
178
- stroke="currentColor"
179
- viewBox="0 0 24 24"
180
- >
181
- <path
182
- stroke-linecap="round"
183
- stroke-linejoin="round"
184
- stroke-width="2"
185
- d="M13 7l5 5m0 0l-5 5m5-5H6"
186
- ></path>
187
- </svg>
188
- </a>
189
- <div class="glass-card p-4 rounded-lg">
190
- <p class="text-sm text-muted-foreground">
191
- Use our OpenAI API credits with authentication for
192
- responsible usage tracking
193
- </p>
194
- </div>
195
- </div>
196
-
197
- <!-- Divider -->
198
- <div class="relative">
199
- <div class="absolute inset-0 flex items-center">
200
- <div class="w-full border-t border-border"></div>
201
- </div>
202
- <div class="relative flex justify-center text-xs uppercase">
203
- <span class="bg-background px-2 text-muted-foreground"
204
- >Or</span
205
- >
206
- </div>
207
- </div>
208
-
209
- <!-- Option 2: Use Your Own API Key -->
210
- <div class="space-y-4">
211
- <h3 class="text-lg font-semibold text-foreground">
212
- Option 2: Use Your Own OpenAI API Key
213
- </h3>
214
- <div class="space-y-3">
215
- <input
216
- type="password"
217
- id="apiKey"
218
- placeholder="sk-..."
219
- class="w-full px-4 py-3 border border-input rounded-lg bg-background text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
220
- />
221
- <button
222
- id="useApiKeyBtn"
223
- class="w-full inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg transition-all duration-300 group bg-secondary text-secondary-foreground hover:bg-secondary/80"
224
- >
225
- Continue with Your API Key
226
- <svg
227
- class="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1"
228
- fill="none"
229
- stroke="currentColor"
230
- viewBox="0 0 24 24"
231
- >
232
- <path
233
- stroke-linecap="round"
234
- stroke-linejoin="round"
235
- stroke-width="2"
236
- d="M13 7l5 5m0 0l-5 5m5-5H6"
237
- ></path>
238
- </svg>
239
- </button>
240
- </div>
241
- <div class="glass-card p-4 rounded-lg">
242
- <p class="text-sm text-muted-foreground">
243
- Your API key will be stored locally and used directly with
244
- OpenAI. No authentication required.
245
- </p>
246
- </div>
247
  </div>
248
  </div>
249
  </div>
@@ -266,51 +208,5 @@
266
  </div>
267
  </div>
268
  </div>
269
-
270
- <script>
271
- // Handle API key submission
272
- document
273
- .getElementById("useApiKeyBtn")
274
- .addEventListener("click", function () {
275
- const apiKey = document.getElementById("apiKey").value.trim();
276
-
277
- if (!apiKey) {
278
- alert("Please enter your OpenAI API key");
279
- return;
280
- }
281
-
282
- if (!apiKey.startsWith("sk-")) {
283
- alert("Please enter a valid OpenAI API key (starts with sk-)");
284
- return;
285
- }
286
-
287
- // Store API key in localStorage
288
- localStorage.setItem("openai_api_key", apiKey);
289
- localStorage.setItem("auth_mode", "api_key");
290
-
291
- // Redirect to main application
292
- window.location.href = "/";
293
- });
294
-
295
- // Allow Enter key to submit API key
296
- document
297
- .getElementById("apiKey")
298
- .addEventListener("keypress", function (e) {
299
- if (e.key === "Enter") {
300
- document.getElementById("useApiKeyBtn").click();
301
- }
302
- });
303
-
304
- // Check if user already has an API key stored
305
- window.addEventListener("load", function () {
306
- const storedApiKey = localStorage.getItem("openai_api_key");
307
- const authMode = localStorage.getItem("auth_mode");
308
-
309
- if (storedApiKey && authMode === "api_key") {
310
- // User already has API key, redirect to main app
311
- window.location.href = "/";
312
- }
313
- });
314
- </script>
315
  </body>
316
  </html>
 
160
  actionable insights for AI system analysis and robustness testing.
161
  </p>
162
 
163
+ <!-- CTA Section -->
164
+ <div class="space-y-4">
165
+ <a
166
+ href="/auth/login"
167
+ class="btn-primary inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg transition-all duration-300 group"
168
+ >
169
+ Access Research Platform
170
+ <svg
171
+ class="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1"
172
+ fill="none"
173
+ stroke="currentColor"
174
+ viewBox="0 0 24 24"
175
  >
176
+ <path
177
+ stroke-linecap="round"
178
+ stroke-linejoin="round"
179
+ stroke-width="2"
180
+ d="M13 7l5 5m0 0l-5 5m5-5H6"
181
+ ></path>
182
+ </svg>
183
+ </a>
184
+
185
+ <div class="glass-card p-4 rounded-lg">
186
+ <p class="text-sm text-muted-foreground">
187
+ Authentication required for responsible AI resource usage
188
+ </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  </div>
190
  </div>
191
  </div>
 
208
  </div>
209
  </div>
210
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  </body>
212
  </html>
frontend/src/components/shared/SettingsModal.tsx CHANGED
@@ -11,8 +11,6 @@ import { Button } from "@/components/ui/button";
11
  import { Badge } from "@/components/ui/badge";
12
  import { Separator } from "@/components/ui/separator";
13
  import { ScrollArea } from "@/components/ui/scroll-area";
14
- import { Input } from "@/components/ui/input";
15
- import { Label } from "@/components/ui/label";
16
  import {
17
  Settings,
18
  Palette,
@@ -27,11 +25,6 @@ import {
27
  Zap,
28
  Clock,
29
  DollarSign,
30
- Key,
31
- Shield,
32
- Eye,
33
- EyeOff,
34
- Trash2,
35
  } from "lucide-react";
36
  import { useKGDisplayMode } from "@/context/KGDisplayModeContext";
37
  import { useModelPreferences } from "@/hooks/useModelPreferences";
@@ -54,23 +47,6 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) {
54
  updateModelPreference,
55
  isLoading,
56
  } = useModelPreferences();
57
-
58
- // Authentication state
59
- const [showApiKey, setShowApiKey] = useState(false);
60
- const [apiKey, setApiKey] = useState("");
61
- const [authMode, setAuthMode] = useState<string | null>(null);
62
-
63
- // Load auth state on mount
64
- React.useEffect(() => {
65
- const storedApiKey = localStorage.getItem('openai_api_key');
66
- const storedAuthMode = localStorage.getItem('auth_mode');
67
- if (storedApiKey) {
68
- setApiKey(storedApiKey);
69
- }
70
- if (storedAuthMode) {
71
- setAuthMode(storedAuthMode);
72
- }
73
- }, []);
74
 
75
  const handleThemeChange = (theme: Theme) => {
76
  setCurrentTheme(theme);
@@ -138,11 +114,6 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) {
138
  name: "Models",
139
  icon: Brain,
140
  },
141
- {
142
- id: "authentication",
143
- name: "Authentication",
144
- icon: Shield,
145
- },
146
  {
147
  id: "general",
148
  name: "General",
@@ -378,197 +349,6 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) {
378
  </div>
379
  );
380
 
381
- // Authentication functions
382
- const handleApiKeyUpdate = () => {
383
- if (!apiKey.trim()) {
384
- alert('Please enter an API key');
385
- return;
386
- }
387
-
388
- if (!apiKey.startsWith('sk-')) {
389
- alert('Please enter a valid OpenAI API key (starts with sk-)');
390
- return;
391
- }
392
-
393
- localStorage.setItem('openai_api_key', apiKey);
394
- localStorage.setItem('auth_mode', 'api_key');
395
- setAuthMode('api_key');
396
-
397
- // Reload the page to update authentication state
398
- window.location.reload();
399
- };
400
-
401
- const handleRemoveApiKey = () => {
402
- if (confirm('Are you sure you want to remove your API key? You will need to authenticate again.')) {
403
- localStorage.removeItem('openai_api_key');
404
- localStorage.removeItem('auth_mode');
405
- setApiKey('');
406
- setAuthMode(null);
407
-
408
- // Redirect to login page
409
- window.location.href = '/auth/login-page';
410
- }
411
- };
412
-
413
- const renderAuthenticationSection = () => (
414
- <div className="space-y-6">
415
- <div>
416
- <h3 className="text-lg font-semibold mb-4">Authentication Method</h3>
417
-
418
- {authMode === 'api_key' ? (
419
- // Current API Key Section
420
- <Card className="border-green-200 bg-green-50/50 dark:border-green-800 dark:bg-green-950/50">
421
- <CardContent className="p-4">
422
- <div className="flex items-start justify-between">
423
- <div className="flex items-center gap-3">
424
- <div className="p-2 rounded-lg bg-green-100 dark:bg-green-900">
425
- <Key className="h-4 w-4 text-green-600 dark:text-green-400" />
426
- </div>
427
- <div>
428
- <h4 className="font-medium text-green-900 dark:text-green-100">
429
- Using Your OpenAI API Key
430
- </h4>
431
- <p className="text-sm text-green-700 dark:text-green-300">
432
- API Key: {apiKey.substring(0, 7)}...{apiKey.substring(apiKey.length - 4)}
433
- </p>
434
- <p className="text-xs text-green-600 dark:text-green-400 mt-1">
435
- Your API key is stored locally and sent directly to OpenAI
436
- </p>
437
- </div>
438
- </div>
439
- <Button
440
- variant="destructive"
441
- size="sm"
442
- onClick={handleRemoveApiKey}
443
- >
444
- <Trash2 className="h-4 w-4 mr-2" />
445
- Remove
446
- </Button>
447
- </div>
448
- </CardContent>
449
- </Card>
450
- ) : authMode === 'huggingface_oauth' ? (
451
- // HF OAuth Section
452
- <Card className="border-blue-200 bg-blue-50/50 dark:border-blue-800 dark:bg-blue-950/50">
453
- <CardContent className="p-4">
454
- <div className="flex items-center gap-3">
455
- <div className="p-2 rounded-lg bg-blue-100 dark:bg-blue-900">
456
- <Shield className="h-4 w-4 text-blue-600 dark:text-blue-400" />
457
- </div>
458
- <div>
459
- <h4 className="font-medium text-blue-900 dark:text-blue-100">
460
- Authenticated with Hugging Face
461
- </h4>
462
- <p className="text-sm text-blue-700 dark:text-blue-300">
463
- Using our provided OpenAI API credits
464
- </p>
465
- </div>
466
- </div>
467
- </CardContent>
468
- </Card>
469
- ) : (
470
- // No Authentication Section
471
- <Card className="border-yellow-200 bg-yellow-50/50 dark:border-yellow-800 dark:bg-yellow-950/50">
472
- <CardContent className="p-4">
473
- <div className="flex items-center gap-3 mb-4">
474
- <div className="p-2 rounded-lg bg-yellow-100 dark:bg-yellow-900">
475
- <Key className="h-4 w-4 text-yellow-600 dark:text-yellow-400" />
476
- </div>
477
- <div>
478
- <h4 className="font-medium text-yellow-900 dark:text-yellow-100">
479
- Add Your OpenAI API Key
480
- </h4>
481
- <p className="text-sm text-yellow-700 dark:text-yellow-300">
482
- Use your own API key to access AgentGraph features
483
- </p>
484
- </div>
485
- </div>
486
-
487
- <div className="space-y-3">
488
- <div>
489
- <Label htmlFor="api-key">OpenAI API Key</Label>
490
- <div className="flex gap-2 mt-1">
491
- <div className="relative flex-1">
492
- <Input
493
- id="api-key"
494
- type={showApiKey ? "text" : "password"}
495
- placeholder="sk-..."
496
- value={apiKey}
497
- onChange={(e) => setApiKey(e.target.value)}
498
- className="pr-10"
499
- />
500
- <Button
501
- type="button"
502
- variant="ghost"
503
- size="sm"
504
- className="absolute right-1 top-1/2 -translate-y-1/2 h-7 w-7 p-0"
505
- onClick={() => setShowApiKey(!showApiKey)}
506
- >
507
- {showApiKey ? (
508
- <EyeOff className="h-4 w-4" />
509
- ) : (
510
- <Eye className="h-4 w-4" />
511
- )}
512
- </Button>
513
- </div>
514
- <Button onClick={handleApiKeyUpdate} disabled={!apiKey.trim()}>
515
- Save
516
- </Button>
517
- </div>
518
- </div>
519
-
520
- <div className="text-xs text-muted-foreground bg-muted/50 p-2 rounded">
521
- <p>โ€ข Your API key will be stored locally in your browser</p>
522
- <p>โ€ข It will be sent directly to OpenAI for API calls</p>
523
- <p>โ€ข No authentication with our service required</p>
524
- </div>
525
- </div>
526
- </CardContent>
527
- </Card>
528
- )}
529
- </div>
530
-
531
- <Separator />
532
-
533
- <div>
534
- <h3 className="text-lg font-semibold mb-4">Authentication Options</h3>
535
- <div className="grid grid-cols-1 gap-3">
536
- <Card className="cursor-pointer transition-all hover:shadow-md hover:bg-muted/50">
537
- <CardContent className="p-4">
538
- <div className="flex items-center gap-3">
539
- <div className="p-2 rounded-lg bg-muted">
540
- <Key className="h-4 w-4" />
541
- </div>
542
- <div>
543
- <h4 className="font-medium">Use Your Own API Key</h4>
544
- <p className="text-sm text-muted-foreground">
545
- Provide your OpenAI API key for direct access
546
- </p>
547
- </div>
548
- </div>
549
- </CardContent>
550
- </Card>
551
-
552
- <Card className="cursor-pointer transition-all hover:shadow-md hover:bg-muted/50">
553
- <CardContent className="p-4">
554
- <div className="flex items-center gap-3">
555
- <div className="p-2 rounded-lg bg-muted">
556
- <Shield className="h-4 w-4" />
557
- </div>
558
- <div>
559
- <h4 className="font-medium">Login with Hugging Face</h4>
560
- <p className="text-sm text-muted-foreground">
561
- Use our provided API credits with authentication
562
- </p>
563
- </div>
564
- </div>
565
- </CardContent>
566
- </Card>
567
- </div>
568
- </div>
569
- </div>
570
- );
571
-
572
  const renderGeneralSection = () => (
573
  <div className="space-y-6">
574
  <div>
@@ -651,8 +431,6 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) {
651
  return renderAppearanceSection();
652
  case "models":
653
  return renderModelsSection();
654
- case "authentication":
655
- return renderAuthenticationSection();
656
  case "general":
657
  return renderGeneralSection();
658
  default:
 
11
  import { Badge } from "@/components/ui/badge";
12
  import { Separator } from "@/components/ui/separator";
13
  import { ScrollArea } from "@/components/ui/scroll-area";
 
 
14
  import {
15
  Settings,
16
  Palette,
 
25
  Zap,
26
  Clock,
27
  DollarSign,
 
 
 
 
 
28
  } from "lucide-react";
29
  import { useKGDisplayMode } from "@/context/KGDisplayModeContext";
30
  import { useModelPreferences } from "@/hooks/useModelPreferences";
 
47
  updateModelPreference,
48
  isLoading,
49
  } = useModelPreferences();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  const handleThemeChange = (theme: Theme) => {
52
  setCurrentTheme(theme);
 
114
  name: "Models",
115
  icon: Brain,
116
  },
 
 
 
 
 
117
  {
118
  id: "general",
119
  name: "General",
 
349
  </div>
350
  );
351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  const renderGeneralSection = () => (
353
  <div className="space-y-6">
354
  <div>
 
431
  return renderAppearanceSection();
432
  case "models":
433
  return renderModelsSection();
 
 
434
  case "general":
435
  return renderGeneralSection();
436
  default:
frontend/src/lib/api.ts CHANGED
@@ -24,26 +24,11 @@ async function fetchApi<T>(
24
  options?: RequestInit,
25
  retryCount = 0
26
  ): Promise<T> {
27
- // Get API key from localStorage if available
28
- const apiKey = localStorage.getItem("openai_api_key");
29
- const authMode = localStorage.getItem("auth_mode");
30
-
31
- const baseHeaders: Record<string, string> = {
32
- "Content-Type": "application/json",
33
- };
34
-
35
- // Add API key header if user is in API key mode
36
- if (apiKey && authMode === "api_key") {
37
- baseHeaders["X-OpenAI-API-Key"] = apiKey;
38
- }
39
-
40
- const headers = {
41
- ...baseHeaders,
42
- ...options?.headers,
43
- };
44
-
45
  const response = await fetch(`${API_BASE}${endpoint}`, {
46
- headers,
 
 
 
47
  ...options,
48
  });
49
 
 
24
  options?: RequestInit,
25
  retryCount = 0
26
  ): Promise<T> {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  const response = await fetch(`${API_BASE}${endpoint}`, {
28
+ headers: {
29
+ "Content-Type": "application/json",
30
+ ...options?.headers,
31
+ },
32
  ...options,
33
  });
34