@@ -2,7 +2,8 @@ import 'dart:io';
2
2
3
3
import 'package:dart_frog/dart_frog.dart' ;
4
4
import 'package:ht_api/src/services/auth_service.dart' ;
5
- import 'package:ht_shared/ht_shared.dart' ; // For exceptions and models
5
+ // Import exceptions, User, SuccessApiResponse, AND AuthSuccessResponse
6
+ import 'package:ht_shared/ht_shared.dart' ;
6
7
7
8
/// Handles POST requests to `/api/v1/auth/verify-code` .
8
9
///
@@ -22,60 +23,65 @@ Future<Response> onRequest(RequestContext context) async {
22
23
try {
23
24
body = await context.request.json ();
24
25
} catch (_) {
25
- return Response (
26
- statusCode: HttpStatus .badRequest,
27
- body: 'Invalid JSON format in request body.' ,
28
- );
26
+ // Handle JSON parsing errors by throwing
27
+ throw const InvalidInputException ('Invalid JSON format in request body.' );
29
28
}
30
29
31
30
if (body is ! Map <String , dynamic >) {
32
- return Response (
33
- statusCode: HttpStatus .badRequest,
34
- body: 'Request body must be a JSON object.' ,
35
- );
31
+ throw const InvalidInputException ('Request body must be a JSON object.' );
36
32
}
37
33
38
34
// Extract and validate email
39
35
final email = body['email' ] as String ? ;
40
36
if (email == null || email.isEmpty) {
41
- return Response (
42
- statusCode: HttpStatus .badRequest,
43
- body: 'Missing or empty "email" field in request body.' ,
37
+ throw const InvalidInputException (
38
+ 'Missing or empty "email" field in request body.' ,
44
39
);
45
40
}
46
- if (! RegExp (r'^.+@.+\..+$' ).hasMatch (email)) {
47
- return Response (
48
- statusCode: HttpStatus .badRequest,
49
- body: 'Invalid email format provided.' ,
50
- );
41
+ // Using a slightly more common regex pattern
42
+ final emailRegex = RegExp (
43
+ r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@"
44
+ r'[a-zA-Z0-9]+\.[a-zA-Z]+' ,
45
+ );
46
+ if (! emailRegex.hasMatch (email)) {
47
+ throw const InvalidInputException ('Invalid email format provided.' );
51
48
}
52
49
53
50
// Extract and validate code
54
51
final code = body['code' ] as String ? ;
55
52
if (code == null || code.isEmpty) {
56
- return Response (
57
- statusCode: HttpStatus .badRequest,
58
- body: 'Missing or empty "code" field in request body.' ,
53
+ throw const InvalidInputException (
54
+ 'Missing or empty "code" field in request body.' ,
59
55
);
60
56
}
61
57
// Basic validation (e.g., check if it's 6 digits)
62
58
if (! RegExp (r'^\d{6}$' ).hasMatch (code)) {
63
- return Response (
64
- statusCode: HttpStatus .badRequest,
65
- body: 'Invalid code format. Code must be 6 digits.' ,
59
+ throw const InvalidInputException (
60
+ 'Invalid code format. Code must be 6 digits.' ,
66
61
);
67
62
}
68
63
69
64
try {
70
65
// Call the AuthService to handle the verification and sign-in logic
71
66
final result = await authService.completeEmailSignIn (email, code);
72
67
73
- // Return 200 OK with the user and token
68
+ // Create the specific payload containing user and token
69
+ final authPayload = AuthSuccessResponse (
70
+ user: result.user,
71
+ token: result.token,
72
+ );
73
+
74
+ // Wrap the payload in the standard SuccessApiResponse
75
+ final responsePayload = SuccessApiResponse <AuthSuccessResponse >(
76
+ data: authPayload,
77
+ // Optionally add metadata if needed/available
78
+ // metadata: ResponseMetadata(timestamp: DateTime.now().toUtc()),
79
+ );
80
+
81
+ // Return 200 OK with the standardized, serialized response
74
82
return Response .json (
75
- body: {
76
- 'user' : result.user.toJson (), // Serialize the User object
77
- 'token' : result.token,
78
- },
83
+ // Use the toJson method, providing the toJson factory for the inner type
84
+ body: responsePayload.toJson ((authSuccess) => authSuccess.toJson ()),
79
85
);
80
86
} on HtHttpException catch (_) {
81
87
// Let the central errorHandler middleware handle known exceptions
0 commit comments