@@ -188,6 +188,11 @@ class DataOperationRegistry {
188188 item: item as Language ,
189189 userId: uid,
190190 ),
191+ // Handler for creating a new user.
192+ 'user' : (c, item, uid) => c.read <DataRepository <User >>().create (
193+ item: item as User ,
194+ userId: uid,
195+ ),
191196 'remote_config' : (c, item, uid) => c
192197 .read <DataRepository <RemoteConfig >>()
193198 .create (item: item as RemoteConfig , userId: uid),
@@ -220,13 +225,56 @@ class DataOperationRegistry {
220225 'language' : (c, id, item, uid) => c
221226 .read <DataRepository <Language >>()
222227 .update (id: id, item: item as Language , userId: uid),
228+ // Custom updater for the 'user' model.
229+ // This updater handles two distinct use cases:
230+ // 1. Admins updating user roles (`appRole`, `dashboardRole`).
231+ // 2. Regular users updating their own `feedDecoratorStatus`.
232+ // It accepts a raw Map<String, dynamic> as the `item` to prevent
233+ // mass assignment vulnerabilities, only applying allowed fields.
223234 'user' : (c, id, item, uid) {
224235 final repo = c.read <DataRepository <User >>();
225236 final existingUser = c.read <FetchedItem <dynamic >>().data as User ;
226- final updatedUser = existingUser.copyWith (
227- feedDecoratorStatus: (item as User ).feedDecoratorStatus,
237+ final requestBody = item as Map <String , dynamic >;
238+ 239+ AppUserRole ? newAppRole;
240+ if (requestBody.containsKey ('appRole' )) {
241+ try {
242+ newAppRole = AppUserRole .values.byName (
243+ requestBody['appRole' ] as String ,
244+ );
245+ } on ArgumentError {
246+ throw BadRequestException (
247+ 'Invalid value for "appRole": "${requestBody ['appRole' ]}".' ,
248+ );
249+ }
250+ }
251+ 252+ DashboardUserRole ? newDashboardRole;
253+ if (requestBody.containsKey ('dashboardRole' )) {
254+ try {
255+ newDashboardRole = DashboardUserRole .values.byName (
256+ requestBody['dashboardRole' ] as String ,
257+ );
258+ } on ArgumentError {
259+ throw BadRequestException (
260+ 'Invalid value for "dashboardRole": "${requestBody ['dashboardRole' ]}".' ,
261+ );
262+ }
263+ }
264+ 265+ Map <FeedDecoratorType , UserFeedDecoratorStatus >? newStatus;
266+ if (requestBody.containsKey ('feedDecoratorStatus' )) {
267+ newStatus = User .fromJson (
268+ {'feedDecoratorStatus' : requestBody['feedDecoratorStatus' ]},
269+ ).feedDecoratorStatus;
270+ }
271+ 272+ final userWithUpdates = existingUser.copyWith (
273+ appRole: newAppRole,
274+ dashboardRole: newDashboardRole,
275+ feedDecoratorStatus: newStatus,
228276 );
229- return repo.update (id: id, item: updatedUser , userId: uid);
277+ return repo.update (id: id, item: userWithUpdates , userId: uid);
230278 },
231279 'user_app_settings' : (c, id, item, uid) => c
232280 .read <DataRepository <UserAppSettings >>()
0 commit comments