@@ -2,28 +2,14 @@ import 'dart:io';
2
2
3
3
import 'package:core/core.dart' ; // For exceptions
4
4
import 'package:dart_frog/dart_frog.dart' ;
5
+ import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/rate_limiter_middleware.dart' ;
5
6
import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart' ;
6
7
import 'package:logging/logging.dart' ;
7
8
8
9
// Create a logger for this file.
9
10
final _logger = Logger ('request_code_handler' );
10
11
11
- /// Handles POST requests to `/api/v1/auth/request-code` .
12
- ///
13
- /// Initiates an email-based sign-in process. This endpoint is context-aware.
14
- ///
15
- /// - For the user-facing app, it sends a verification code to the provided
16
- /// email, supporting both sign-in and sign-up.
17
- /// - For the dashboard, the request body must include `"isDashboardLogin": true` .
18
- /// In this mode, it first verifies the user exists and has 'admin' or
19
- /// 'publisher' roles before sending a code, effectively acting as a
20
- /// login-only gate.
21
- Future <Response > onRequest (RequestContext context) async {
22
- // Ensure this is a POST request
23
- if (context.request.method != HttpMethod .post) {
24
- return Response (statusCode: HttpStatus .methodNotAllowed);
25
- }
26
-
12
+ Future <Response > _onRequest (RequestContext context) async {
27
13
// Read the AuthService provided by middleware
28
14
final authService = context.read <AuthService >();
29
15
@@ -70,25 +56,53 @@ Future<Response> onRequest(RequestContext context) async {
70
56
}
71
57
72
58
try {
73
- // Call the AuthService to handle the logic, passing the context flag.
74
- await authService.initiateEmailSignIn (
75
- email,
76
- isDashboardLogin: isDashboardLogin,
77
- );
59
+ // Call the AuthService to handle the logic, passing the context flag.
60
+ await authService.initiateEmailSignIn (
61
+ email,
62
+ isDashboardLogin: isDashboardLogin,
63
+ );
78
64
79
- // Return 202 Accepted: The request is accepted for processing,
80
- // but the processing (email sending) hasn't necessarily completed.
81
- // 200 OK is also acceptable if you consider the API call itself complete.
82
- return Response (statusCode: HttpStatus .accepted);
83
- } on HttpException catch (_) {
84
- // Let the central errorHandler middleware handle known exceptions
85
- rethrow ;
86
- } catch (e, s) {
87
- // Catch unexpected errors from the service layer
88
- _logger.severe ('Unexpected error in /request-code handler' , e, s);
89
- // Let the central errorHandler handle this as a 500
90
- throw const OperationFailedException (
91
- 'An unexpected error occurred while requesting the sign-in code.' ,
92
- );
65
+ // Return 202 Accepted: The request is accepted for processing,
66
+ // but the processing (email sending) hasn't necessarily completed.
67
+ // 200 OK is also acceptable if you consider the API call itself complete.
68
+ return Response (statusCode: HttpStatus .accepted);
69
+ } on HttpException catch (_) {
70
+ // Let the central errorHandler middleware handle known exceptions
71
+ rethrow ;
72
+ } catch (e, s) {
73
+ // Catch unexpected errors from the service layer
74
+ _logger.severe ('Unexpected error in /request-code handler' , e, s);
75
+ // Let the central errorHandler handle this as a 500
76
+ throw const OperationFailedException (
77
+ 'An unexpected error occurred while requesting the sign-in code.' ,
78
+ );
79
+ }
80
+ }
81
+
82
+ /// Handles POST requests to `/api/v1/auth/request-code` .
83
+ ///
84
+ /// Initiates an email-based sign-in process. This endpoint is context-aware.
85
+ ///
86
+ /// - For the user-facing app, it sends a verification code to the provided
87
+ /// email, supporting both sign-in and sign-up.
88
+ /// - For the dashboard, the request body must include `"isDashboardLogin": true` .
89
+ /// In this mode, it first verifies the user exists and has 'admin' or
90
+ /// 'publisher' roles before sending a code, effectively acting as a
91
+ /// login-only gate.
92
+ Future <Response > onRequest (RequestContext context) async {
93
+ // Ensure this is a POST request
94
+ if (context.request.method != HttpMethod .post) {
95
+ return Response (statusCode: HttpStatus .methodNotAllowed);
93
96
}
97
+
98
+ // Apply the rate limiter middleware before calling the actual handler.
99
+ final handler = const Pipeline ().addMiddleware (
100
+ rateLimiter (
101
+ limit: 3 ,
102
+ window: const Duration (hours: 24 ),
103
+ keyExtractor: ipKeyExtractor,
104
+ ),
105
+ ).addHandler (_onRequest);
106
+
107
+ return handler (context);
94
108
}
0 commit comments