added TOKEN for users,
added user*() method for API, added check TOKEN for all methods in API
This commit is contained in:
61
AGENTS.md
61
AGENTS.md
@ -41,7 +41,7 @@ It describes what the project is, what is already implemented, and what still ne
|
||||
Migration creates these tables:
|
||||
|
||||
- `options` (`key`, `value`) for internal settings, including DB version.
|
||||
- `users` (`user_id`, `email`, `password_hash`, `created_at`).
|
||||
- `users` (`user_id`, `email`, `password_hash`, `token`, `token_expires`, `created_at`).
|
||||
- `ingredients`:
|
||||
- `ingredient_id`, `user_id`, `name`
|
||||
- per-100g values: `protein_g_100`, `carbs_g_100`, `sugar_g_100`, `fat_g_100`, `fiber_g_100`, `kcal_100`
|
||||
@ -62,31 +62,36 @@ All actions are invoked through `backend/public/API.php` with `?action=<method_n
|
||||
|
||||
- Utility:
|
||||
- `health`
|
||||
- Auth / Users:
|
||||
- `userRegistration(email, password)`
|
||||
- `userLogin(email, password)`
|
||||
- `userLogout(token)`
|
||||
- `userDelete(email, password)`
|
||||
- Ingredients:
|
||||
- `ingredientList(user_id, query = "", include_global = true)`
|
||||
- `ingredientGet(user_id, ingredient_id)`
|
||||
- `ingredientCreate(user_id, name, protein_g_100, carbs_g_100, sugar_g_100, fat_g_100, fiber_g_100 = 0, kcal_100 = 0)`
|
||||
- `ingredientUpdate(user_id, ingredient_id, name, protein_g_100, carbs_g_100, sugar_g_100, fat_g_100, fiber_g_100 = 0, kcal_100 = 0)`
|
||||
- `ingredientDelete(user_id, ingredient_id)`
|
||||
- `ingredientList(token, query = "", include_global = true)`
|
||||
- `ingredientGet(token, ingredient_id)`
|
||||
- `ingredientCreate(token, name, protein_g_100, carbs_g_100, sugar_g_100, fat_g_100, fiber_g_100 = 0, kcal_100 = 0)`
|
||||
- `ingredientUpdate(token, ingredient_id, name, protein_g_100, carbs_g_100, sugar_g_100, fat_g_100, fiber_g_100 = 0, kcal_100 = 0)`
|
||||
- `ingredientDelete(token, ingredient_id)`
|
||||
- Meals:
|
||||
- `mealList(user_id, meal_type = "", with_items = false, with_totals = false)`
|
||||
- `mealGet(user_id, meal_id, with_items = true, with_totals = true)`
|
||||
- `mealCreate(user_id, name, meal_type)`
|
||||
- `mealUpdate(user_id, meal_id, name, meal_type)`
|
||||
- `mealDelete(user_id, meal_id)`
|
||||
- `mealList(token, meal_type = "", with_items = false, with_totals = false)`
|
||||
- `mealGet(token, meal_id, with_items = true, with_totals = true)`
|
||||
- `mealCreate(token, name, meal_type)`
|
||||
- `mealUpdate(token, meal_id, name, meal_type)`
|
||||
- `mealDelete(token, meal_id)`
|
||||
- Meal items:
|
||||
- `mealItemList(user_id, meal_id, with_calculated = true)`
|
||||
- `mealItemAdd(user_id, meal_id, ingredient_id, grams, position = 1)`
|
||||
- `mealItemUpdate(user_id, meal_item_id, ingredient_id, grams, position)`
|
||||
- `mealItemDelete(user_id, meal_item_id)`
|
||||
- `mealItemReorder(user_id, meal_id, ordered_item_ids)`
|
||||
- `mealItemList(token, meal_id, with_calculated = true)`
|
||||
- `mealItemAdd(token, meal_id, ingredient_id, grams, position = 1)`
|
||||
- `mealItemUpdate(token, meal_item_id, ingredient_id, grams, position)`
|
||||
- `mealItemDelete(token, meal_item_id)`
|
||||
- `mealItemReorder(token, meal_id, ordered_item_ids)`
|
||||
- Calculations:
|
||||
- `mealTotals(user_id, meal_id)`
|
||||
- `mealTotals(token, meal_id)`
|
||||
- Diary:
|
||||
- `diaryDayGet(user_id, day_date, with_totals = true)`
|
||||
- `diaryDaySetMeal(user_id, day_date, meal_type, meal_id)`
|
||||
- `diaryDayUnsetMeal(user_id, day_date, meal_type)`
|
||||
- `diaryRange(user_id, date_from, date_to)`
|
||||
- `diaryDayGet(token, day_date, with_totals = true)`
|
||||
- `diaryDaySetMeal(token, day_date, meal_type, meal_id)`
|
||||
- `diaryDayUnsetMeal(token, day_date, meal_type)`
|
||||
- `diaryRange(token, date_from, date_to)`
|
||||
|
||||
## Behavior and Validation Rules
|
||||
|
||||
@ -96,10 +101,16 @@ All actions are invoked through `backend/public/API.php` with `?action=<method_n
|
||||
- Nutrition input values are validated as non-negative.
|
||||
- If `kcal_100` is `0`, API computes kcal by formula:
|
||||
- `protein*4 + carbs*4 + fat*9`
|
||||
- Ownership checks are enforced by `user_id`:
|
||||
- User-bound actions now require `token` and resolve `user_id` from it at method start.
|
||||
- Token validation path:
|
||||
- `Users::getUserIDbyToken(token)` -> `Users::verifyToken(user_id, token)`
|
||||
- valid token refreshes `token_expires`
|
||||
- expired token clears `token` and `token_expires` to `NULL`
|
||||
- Ownership checks are enforced by resolved `user_id`:
|
||||
- meals and meal items must belong to the user
|
||||
- ingredients can be user-owned or global (`user_id = null`) for read/select
|
||||
- API currently requires an existing `users` record for almost all actions.
|
||||
- Registration/login generate and store user token in DB.
|
||||
- `userLogout(token)` invalidates session by setting `token` and `token_expires` to `NULL`.
|
||||
|
||||
## Known Pitfalls and Notes
|
||||
|
||||
@ -108,7 +119,7 @@ All actions are invoked through `backend/public/API.php` with `?action=<method_n
|
||||
- If someone ran migrations before FK fix, old MySQL state may still be broken.
|
||||
In that case reset affected table(s) or rebuild DB from clean state.
|
||||
- Some comments in `Maintenance.php` show encoding artifacts, but SQL structure is valid.
|
||||
- Authentication is not implemented yet; `user_id` is passed as an action parameter.
|
||||
- Basic token auth is implemented, but token is still passed as plain API parameter.
|
||||
- For `array` parameters (for example `ordered_item_ids`), APIlite expects JSON in request payload.
|
||||
- APIlite wraps responses with a nested `data` object. Keep this in mind on frontend parsing.
|
||||
|
||||
@ -131,7 +142,7 @@ Frontend:
|
||||
|
||||
## Product Behavior Target (what to build next)
|
||||
|
||||
- Implement auth and session handling (replace plain `user_id` input model).
|
||||
- Harden auth (token transport/header strategy, token revoke strategy, brute-force/rate-limits).
|
||||
- Build frontend screens for ingredients, meals, meal item editor, diary day, diary range.
|
||||
- Connect frontend to implemented backend actions.
|
||||
- Add API tests for validation, ownership checks, and totals calculation consistency.
|
||||
|
||||
Reference in New Issue
Block a user