feat: Implement user validation and ownership checks for image, reward, and task APIs
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 36s
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 36s
- Added `get_validated_user_id` utility function to validate user authentication across multiple APIs. - Updated image upload, request, and listing endpoints to ensure user ownership and proper error handling. - Enhanced reward management endpoints to include user validation and ownership checks. - Modified task management endpoints to enforce user authentication and ownership verification. - Updated models to include `user_id` for images, rewards, tasks, and children to track ownership. - Implemented frontend changes to ensure UI reflects the ownership of tasks and rewards. - Added a new feature specification to prevent deletion of system tasks and rewards.
This commit is contained in:
10
.github/copilot-instructions.md
vendored
10
.github/copilot-instructions.md
vendored
@@ -13,22 +13,16 @@
|
||||
|
||||
- **Frontend Styling**: Use only `:root` CSS variables from `global.css` for all colors, spacing, and tokens. Example: `--btn-primary`, `--list-item-bg-good`.
|
||||
- **Scoped Styles**: All `.vue` files must use `<style scoped>`. Reference global variables for theme consistency.
|
||||
- **Rewards UI**: If `points >= cost`, apply `--item-card-ready-shadow` and `--item-card-ready-border`.
|
||||
- **API Error Handling**: Backend returns JSON with `error` and `code` (see `backend/api/error_codes.py`). Frontend extracts `{ msg, code }` using `parseErrorResponse(res)` from `api.ts`.
|
||||
- **Validation**: Use `isEmailValid` and `isPasswordStrong` (min 8 chars, 1 letter, 1 number) from `api.ts` for all user input. Use `sanitize_email()` for directory names and unique IDs (see `backend/api/utils.py`).
|
||||
- **JWT Auth**: Tokens are stored in HttpOnly, Secure, SameSite=Strict cookies.
|
||||
|
||||
## 🚦 Frontend Logic & Event Bus
|
||||
|
||||
- **SSE Event Management**: Register listeners in `onMounted`, clean up in `onUnmounted`. Listen for events like `child_task_triggered`, `child_reward_request`, `task_modified`, etc. See `frontend/vue-app/src/common/backendEvents.ts` and `components/BackendEventsListener.vue`.
|
||||
- **UI Guardrails**:
|
||||
- Before triggering a task, check for pending rewards. If found, prompt for cancellation before proceeding.
|
||||
- On `EDIT`, always refetch the full object from the API to ensure state integrity.
|
||||
- **Layout Hierarchy**: Use `ParentLayout` for admin/management, `ChildLayout` for dashboard/focus views.
|
||||
|
||||
## ⚖️ Business Logic & Safeguards
|
||||
|
||||
- **Points**: Always enforce `child.points = max(child.points, 0)` after any mutation.
|
||||
- **Token Expiry**: Verification tokens expire in 4 hours; password reset tokens in 10 minutes.
|
||||
- **Image Assets**: Models use `image_id` for storage; frontend resolves to `image_url` for rendering.
|
||||
|
||||
@@ -36,7 +30,7 @@
|
||||
|
||||
- **Backend**: Run Flask with `python -m flask run --host=0.0.0.0 --port=5000` from the `backend/` directory. Main entry: `backend/main.py`.
|
||||
- **Frontend**: From `frontend/vue-app/`, run `npm install` then `npm run dev`.
|
||||
- **Tests**: Run backend tests with `pytest` in `backend/`. Frontend tests: `npm run test` in `frontend/vue-app/`.
|
||||
- **Tests**: Run backend tests with `pytest` in `backend/tests/`. Frontend component tests: `npm run test` in `frontend/vue-app/components/__tests__/`.
|
||||
- **Debugging**: Use VS Code launch configs or run Flask/Vue dev servers directly. For SSE, use browser dev tools to inspect event streams.
|
||||
|
||||
## 📁 Key Files & Directories
|
||||
@@ -48,7 +42,7 @@
|
||||
- `frontend/vue-app/` — Vue 3 frontend (see `src/common/`, `src/components/`, `src/layout/`)
|
||||
- `frontend/vue-app/src/common/models.ts` — TypeScript interfaces (mirror Python models)
|
||||
- `frontend/vue-app/src/common/api.ts` — API helpers, error parsing, validation
|
||||
- `web/vue-app/src/common/backendEvents.ts` — SSE event types and handlers
|
||||
- `frontend/vue-app/src/common/backendEvents.ts` — SSE event types and handlers
|
||||
|
||||
## 🧠 Integration & Cross-Component Patterns
|
||||
|
||||
|
||||
26
.github/specs/active/no-delete-system-tasks-and-rewards.md
vendored
Normal file
26
.github/specs/active/no-delete-system-tasks-and-rewards.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Feature: Do Not Allow System Tasks or System Rewards To Be Deleted
|
||||
|
||||
## Context:
|
||||
|
||||
- **Goal:** In Task List view and Reward List view, do not allow items to be deleted by the user if they are system tasks.
|
||||
- **User Story:** As a [user], I want to only be able to press the delete button on a task or reward if that item is not a system task or reward so that shared system tasks are not deleted for other users.
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- **File Affected:** ItemList.vue, TaskView.vue, RewardView.vue, task_api.py, reward_api.py
|
||||
- **Logic:**
|
||||
1. Starting with ItemList.vue, we should check to see if any item in the list has an "user_id" property and if that property is null.
|
||||
2. If the property is null, that means the item is not owned by a user, so do no display a delete button.
|
||||
3. If the ItemList has it's deletable property as false, don't bother checking each item for user_id as the delete button will not display.
|
||||
4. As a safeguard, on the backend, the DELETE api requests should check to see if the "user_id" property of the requested task or reward is null. This is done by requesting the item from the database. The request provides the item's id. If the item is a system item, return 403. Let the return tell the requestor that the item is a system item and cannot be deleted.
|
||||
5. As a safeguard, make PUT/PATCH operations perform a copy-on-edit of the item. This is already implemented.
|
||||
6. Bulk deletion is not possible, don't make changes for this.
|
||||
7. For any item in the frontend or backend that does not have a "user_id" property, treat that as a system item (user_id=mull)
|
||||
8. For both task and reward api create an application level constraint on the database that checks for user_id before mutation logic.
|
||||
|
||||
## Acceptance Criteria (The "Definition of Done")
|
||||
|
||||
- [ ] Logic: Task or Reward does not display the delete button when props.deletable is true and a list item is a system item.
|
||||
- [ ] UI: Doesn't show delete button for system items.
|
||||
- [ ] Backend Tests: Unit tests cover a delete API request for a system task or reward and returns a 403.
|
||||
- [ ] Frontend Tests: Add vitest for this feature in the frontend to make sure the delete button hidden or shown.
|
||||
Reference in New Issue
Block a user