AOSSIE-Org / AOSSIE-Org/NeuroTrack
BUG: changeAppointmentStatus has no ownership check - any therapist can accept or decline another therapist's session
- Dominant language
- Dart
- Stars
- 29
- Forks
- 50
- PR merge metrics
- No merged PRs in 30d
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### What happened?
## 📌 Issue Overview
`changeAppointmentStatus` updates a session's status by `id` alone with
no check that the session belongs to the currently authenticated therapist.
Any authenticated therapist who knows another session's UUID can accept,
decline, or modify it. RLS is also disabled on the `session` table, so
there is no database-level safety net either.
## 🔍 Steps to Reproduce
1. Authenticate as Therapist A
2. Obtain any session UUID assigned to Therapist B
3. Call `changeAppointmentStatus` with Therapist B's session ID and
`status = 'declined'`
4. Therapist B's session is modified without any authorization error
**SQL proof — this is exactly what the current code executes:**
```sql
-- No ownership check — succeeds for ANY session ID
UPDATE session SET status = 'declined' WHERE id = '';
-- Success — modified without auth check
```
**RLS check:**
```sql
SELECT tablename, rowsecurity FROM pg_tables
WHERE schemaname = 'public' AND tablename = 'session';
-- returns: session | false (no database-level protection)
```
## 🎯 Expected Behavior
`changeAppointmentStatus` should only update sessions where `therapist_id`
matches the currently authenticated therapist's ID. Any attempt to modify
another therapist's session should fail silently (0 rows affected) or
return an authorization error.
## 🚨 Actual Behavior
Any authenticated therapist can accept, decline, or modify any session in
the database by supplying its UUID.
**`therapist/lib/repository/supabase_therapist_repository.dart`, line 58:**
```dart
await _supabaseClient.from('session')
.update({'status': status})
.eq('id', appointmentId); // no ownership check
```
## 📷 Screenshot
N/A
## 💡 Suggested Improvements
Add `.eq('therapist_id', _supabaseClient.auth.currentUser!.id)` to scope
the update to the authenticated therapist only:
```dart
await _supabaseClient.from('session')
.update({'status': status})
.eq('id', appointmentId)
.eq('therapist_id', _supabaseClient.auth.currentUser!.id); // ownership check
```
### Record
- [x] I agree to follow this project's Code of Conduct
- [x] I want to work on this issue
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.