Skip to content

Commit f5a5363

Browse files
authored
Merge pull request #21 from headlines-toolkit/refactor_use_mongodb_objectid_isntead_of_uuid
Refactor use mongodb objectid isntead of UUID
2 parents 3a8c878 + 8c29087 commit f5a5363

File tree

7 files changed

+20
-22
lines changed

7 files changed

+20
-22
lines changed

lib/src/config/app_dependencies.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import 'package:ht_email_inmemory/ht_email_inmemory.dart';
1515
import 'package:ht_email_repository/ht_email_repository.dart';
1616
import 'package:ht_shared/ht_shared.dart';
1717
import 'package:logging/logging.dart';
18-
import 'package:uuid/uuid.dart';
1918

2019
/// {@template app_dependencies}
2120
/// A singleton class responsible for initializing and providing all application
@@ -173,7 +172,6 @@ class AppDependencies {
173172
authTokenService = JwtAuthTokenService(
174173
userRepository: userRepository,
175174
blacklistService: tokenBlacklistService,
176-
uuidGenerator: const Uuid(),
177175
log: Logger('JwtAuthTokenService'),
178176
);
179177
verificationCodeStorageService = InMemoryVerificationCodeStorageService();
@@ -186,7 +184,6 @@ class AppDependencies {
186184
emailRepository: emailRepository,
187185
userAppSettingsRepository: userAppSettingsRepository,
188186
userContentPreferencesRepository: userContentPreferencesRepository,
189-
uuidGenerator: const Uuid(),
190187
log: Logger('AuthService'),
191188
);
192189
dashboardSummaryService = DashboardSummaryService(

lib/src/services/auth_service.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:ht_data_repository/ht_data_repository.dart';
66
import 'package:ht_email_repository/ht_email_repository.dart';
77
import 'package:ht_shared/ht_shared.dart';
88
import 'package:logging/logging.dart';
9-
import 'package:uuid/uuid.dart';
9+
import 'package:mongo_dart/mongo_dart.dart';
1010

1111
/// {@template auth_service}
1212
/// Service responsible for orchestrating authentication logic on the backend.
@@ -25,7 +25,6 @@ class AuthService {
2525
required HtDataRepository<UserContentPreferences>
2626
userContentPreferencesRepository,
2727
required PermissionService permissionService,
28-
required Uuid uuidGenerator,
2928
required Logger log,
3029
}) : _userRepository = userRepository,
3130
_authTokenService = authTokenService,
@@ -34,7 +33,6 @@ class AuthService {
3433
_emailRepository = emailRepository,
3534
_userAppSettingsRepository = userAppSettingsRepository,
3635
_userContentPreferencesRepository = userContentPreferencesRepository,
37-
_uuid = uuidGenerator,
3836
_log = log;
3937

4038
final HtDataRepository<User> _userRepository;
@@ -46,7 +44,6 @@ class AuthService {
4644
_userContentPreferencesRepository;
4745
final PermissionService _permissionService;
4846
final Logger _log;
49-
final Uuid _uuid;
5047

5148
/// Initiates the email sign-in process.
5249
///
@@ -212,7 +209,7 @@ class AuthService {
212209
// All new users created via the public API get the standard role.
213210
// Admin users must be provisioned out-of-band (e.g., via fixtures).
214211
user = User(
215-
id: _uuid.v4(),
212+
id: ObjectId().oid,
216213
email: email,
217214
appRole: AppUserRole.standardUser,
218215
dashboardRole: DashboardUserRole.none,
@@ -268,11 +265,12 @@ class AuthService {
268265
// 1. Create anonymous user
269266
User user;
270267
try {
268+
final newId = ObjectId().oid;
271269
user = User(
272-
id: _uuid.v4(),
270+
id: newId,
273271
// Use a unique placeholder email for anonymous users to satisfy the
274272
// non-nullable email constraint.
275-
email: '${_uuid.v4()}@anonymous.com',
273+
email: '$newId@anonymous.com',
276274
appRole: AppUserRole.guestUser,
277275
dashboardRole: DashboardUserRole.none,
278276
createdAt: DateTime.now(),

lib/src/services/jwt_auth_token_service.dart

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:ht_api/src/services/token_blacklist_service.dart';
44
import 'package:ht_data_repository/ht_data_repository.dart';
55
import 'package:ht_shared/ht_shared.dart';
66
import 'package:logging/logging.dart';
7-
import 'package:uuid/uuid.dart';
7+
import 'package:mongo_dart/mongo_dart.dart';
88

99
/// {@template jwt_auth_token_service}
1010
/// An implementation of [AuthTokenService] using JSON Web Tokens (JWT).
@@ -19,20 +19,16 @@ class JwtAuthTokenService implements AuthTokenService {
1919
/// - [userRepository]: To fetch user details after validating the token's
2020
/// subject claim.
2121
/// - [blacklistService]: To manage the blacklist of invalidated tokens.
22-
/// - [uuidGenerator]: For creating unique JWT IDs (jti).
2322
const JwtAuthTokenService({
2423
required HtDataRepository<User> userRepository,
2524
required TokenBlacklistService blacklistService,
26-
required Uuid uuidGenerator,
2725
required Logger log,
2826
}) : _userRepository = userRepository,
2927
_blacklistService = blacklistService,
30-
_uuid = uuidGenerator,
3128
_log = log;
3229

3330
final HtDataRepository<User> _userRepository;
3431
final TokenBlacklistService _blacklistService;
35-
final Uuid _uuid;
3632
final Logger _log;
3733

3834
// --- Configuration ---
@@ -61,7 +57,7 @@ class JwtAuthTokenService implements AuthTokenService {
6157
'exp': expiry.millisecondsSinceEpoch ~/ 1000, // Expiration Time
6258
'iat': now.millisecondsSinceEpoch ~/ 1000, // Issued At
6359
'iss': _issuer, // Issuer
64-
'jti': _uuid.v4(), // JWT ID (for potential blacklisting)
60+
'jti': ObjectId().oid, // JWT ID (for potential blacklisting)
6561
// Custom claims (optional, include what's useful)
6662
'email': user.email, // Kept for convenience
6763
// Embed the new enum-based roles. Use .name for string value.
@@ -70,7 +66,7 @@ class JwtAuthTokenService implements AuthTokenService {
7066
},
7167
issuer: _issuer,
7268
subject: user.id,
73-
jwtId: _uuid.v4(), // Re-setting jti here for clarity if needed
69+
jwtId: ObjectId().oid, // Re-setting jti here for clarity if needed
7470
);
7571

7672
// Sign the token using HMAC-SHA256

pubspec.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ dependencies:
3939
meta: ^1.16.0
4040
mongo_dart: ^0.10.5
4141
shelf_cors_headers: ^0.1.5
42-
uuid: ^4.5.1
4342

4443
dev_dependencies:
4544
mocktail: ^1.0.3

routes/_middleware.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import 'package:ht_data_repository/ht_data_repository.dart';
1414
import 'package:ht_email_repository/ht_email_repository.dart';
1515
import 'package:ht_shared/ht_shared.dart';
1616
import 'package:logging/logging.dart';
17-
import 'package:uuid/uuid.dart';
17+
import 'package:mongo_dart/mongo_dart.dart';
1818

1919
// --- Middleware Definition ---
2020
final _log = Logger('RootMiddleware');
@@ -55,8 +55,7 @@ Handler middleware(Handler handler) {
5555
_log.info(
5656
'[REQ_LIFECYCLE] Request received. Generating RequestId...',
5757
);
58-
final uuid = context.read<Uuid>();
59-
final requestId = RequestId(uuid.v4());
58+
final requestId = RequestId(ObjectId().oid);
6059
_log.info('[REQ_LIFECYCLE] RequestId generated: ${requestId.id}');
6160
return innerHandler(context.provide<RequestId>(() => requestId));
6261
};
@@ -76,7 +75,6 @@ Handler middleware(Handler handler) {
7675
final deps = AppDependencies.instance;
7776
return handler
7877
.use(provider<ModelRegistryMap>((_) => modelRegistry))
79-
.use(provider<Uuid>((_) => const Uuid()))
8078
.use(
8179
provider<HtDataRepository<Headline>>(
8280
(_) => deps.headlineRepository,

routes/api/v1/data/[id]/index.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ Future<Response> _handlePut(
185185
throw const BadRequestException('Missing or invalid request body.');
186186
}
187187

188+
// Standardize timestamp before model creation
189+
requestBody['updatedAt'] = DateTime.now().toUtc().toIso8601String();
190+
188191
// Deserialize using ModelConfig's fromJson, catching TypeErrors locally
189192
dynamic itemToUpdate;
190193
try {

routes/api/v1/data/index.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:ht_api/src/rbac/permission_service.dart';
77
import 'package:ht_api/src/registry/model_registry.dart';
88
import 'package:ht_data_repository/ht_data_repository.dart';
99
import 'package:ht_shared/ht_shared.dart';
10+
import 'package:mongo_dart/mongo_dart.dart';
1011

1112
/// Handles requests for the /api/v1/data collection endpoint.
1213
/// Dispatches requests to specific handlers based on the HTTP method.
@@ -152,6 +153,12 @@ Future<Response> _handlePost(RequestContext context) async {
152153
throw const BadRequestException('Missing or invalid request body.');
153154
}
154155

156+
// Standardize ID and timestamps before model creation
157+
final now = DateTime.now().toUtc().toIso8601String();
158+
requestBody['id'] = ObjectId().oid;
159+
requestBody['createdAt'] = now;
160+
requestBody['updatedAt'] = now;
161+
155162
dynamic itemToCreate;
156163
try {
157164
itemToCreate = modelConfig.fromJson(requestBody);

0 commit comments

Comments
 (0)