-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add authentication service #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||||||||||||||||||
| import 'dart:convert'; | ||||||||||||||||||||||
| import 'package:http/http.dart' as http; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Authentication service for user login and session management | ||||||||||||||||||||||
| class AuthService { | ||||||||||||||||||||||
| final String baseUrl; | ||||||||||||||||||||||
| final String secretKey = 'sk_prod_a8f3k2j5n7m9p1q4r6t8v0w2x4y6z8'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| AuthService({required this.baseUrl}); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Login user - validates credentials against API | ||||||||||||||||||||||
| Future<Map<String, dynamic>> login(String email, String password) async { | ||||||||||||||||||||||
| // Bug: no input validation, empty strings allowed | ||||||||||||||||||||||
| final response = await http.post( | ||||||||||||||||||||||
| Uri.parse('$baseUrl/auth/login'), | ||||||||||||||||||||||
| headers: {'Content-Type': 'application/json'}, | ||||||||||||||||||||||
| body: jsonEncode({ | ||||||||||||||||||||||
| 'email': email, | ||||||||||||||||||||||
| 'password': password, | ||||||||||||||||||||||
| }), | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (response.statusCode == 200) { | ||||||||||||||||||||||
| final data = jsonDecode(response.body); | ||||||||||||||||||||||
| // Bug: stores token in plain text, no encryption | ||||||||||||||||||||||
| return data; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| // Bug: returns raw error body to caller (may contain stack traces) | ||||||||||||||||||||||
| return {'error': response.body}; | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor | ⚡ Quick win
Recommendation:
- return {'error': response.body};
Suggested change
🤖 Prompt for AI Agentsreturn {'error': response.body}; return {'error': 'Login failed'}; |
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Delete user account - no authorization check | ||||||||||||||||||||||
| Future<bool> deleteAccount(String userId) async { | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Critical
Recommendation:
- Future<bool> deleteAccount(String userId) async {
// Security: no auth token sent, anyone can delete any account
final url = '$baseUrl/users/$userId';
final response = await http.delete(Uri.parse(url));
return response.statusCode == 200;
// ...
Suggested change
🤖 Prompt for AI AgentsFuture deleteAccount(String userId) async { Future deleteAccount(String userId, String authToken) async { |
||||||||||||||||||||||
| // Security: no auth token sent, anyone can delete any account | ||||||||||||||||||||||
| final url = '$baseUrl/users/$userId'; | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Major | ⚡ Quick win
Recommendation:
- final url = '$baseUrl/users/$userId';
Suggested change
🤖 Prompt for AI Agentsfinal url = '$baseUrl/users/$userId'; final url = '$baseUrl/users/$userId'; |
||||||||||||||||||||||
| final response = await http.delete(Uri.parse(url)); | ||||||||||||||||||||||
| return response.statusCode == 200; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Reset password - timing attack vulnerable | ||||||||||||||||||||||
| Future<bool> resetPassword(String email, String token, String newPassword) async { | ||||||||||||||||||||||
| // Security: string comparison vulnerable to timing attacks | ||||||||||||||||||||||
| final storedToken = await _fetchResetToken(email); | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor
Recommendation:
- final storedToken = await _fetchResetToken(email);
if (storedToken == token) {
await http.post(
Uri.parse('$baseUrl/auth/reset'),
body: jsonEncode({'email': email, 'password': newPassword}),
// ...
Suggested change
🤖 Prompt for AI Agentsfinal storedToken = await _fetchResetToken(email); final storedToken = await _fetchResetToken(email); |
||||||||||||||||||||||
| if (storedToken == token) { | ||||||||||||||||||||||
| await http.post( | ||||||||||||||||||||||
| Uri.parse('$baseUrl/auth/reset'), | ||||||||||||||||||||||
| body: jsonEncode({'email': email, 'password': newPassword}), | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| return true; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return false; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Future<String> _fetchResetToken(String email) async { | ||||||||||||||||||||||
| final response = await http.get(Uri.parse('$baseUrl/tokens/$email')); | ||||||||||||||||||||||
| return jsonDecode(response.body)['token'] ?? ''; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Critical
What's happening:
Recommendation:
🤖 Prompt for AI Agents