mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-23 18:55:15 -05:00
feat(frontend): ✨ Fix scheduler, forgot password flow, and minor bug fixes (#725)
* feat(frontend): 💄 add recipe title * fix(frontend): 🐛 fixes #722 side-bar issue * feat(frontend): ✨ Add page titles to all pages * minor cleanup * refactor(backend): ♻️ rewrite scheduler to be more modulare and work * feat(frontend): ✨ start password reset functionality * refactor(backend): ♻️ refactor application settings to facilitate dependency injection * refactor(backend): 🔥 remove RECIPE_SETTINGS env variables in favor of group settings * formatting * refactor(backend): ♻️ align naming convention * feat(backend): ✨ password reset * test(backend): ✅ password reset * feat(frontend): ✨ self-service password reset * purge password schedule * update user creation for tests Co-authored-by: Hayden <hay-kot@pm.me>
This commit is contained in:
@@ -16,6 +16,7 @@ from mealie.db.models.recipe.tag import Tag
|
||||
from mealie.db.models.settings import SiteSettings
|
||||
from mealie.db.models.sign_up import SignUp
|
||||
from mealie.db.models.users import LongLiveToken, User
|
||||
from mealie.db.models.users.password_reset import PasswordResetModel
|
||||
from mealie.schema.admin import SiteSettings as SiteSettingsSchema
|
||||
from mealie.schema.cookbook.cookbook import ReadCookBook
|
||||
from mealie.schema.events import Event as EventSchema
|
||||
@@ -27,6 +28,7 @@ from mealie.schema.meal_plan.new_meal import ReadPlanEntry
|
||||
from mealie.schema.recipe import CommentOut, Recipe, RecipeCategoryResponse, RecipeTagResponse
|
||||
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
|
||||
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
|
||||
from mealie.schema.user.user_passwords import PrivatePasswordResetToken
|
||||
|
||||
from ._access_model import AccessModel
|
||||
from .group_access_model import GroupDataAccessModel
|
||||
@@ -117,6 +119,10 @@ class Database:
|
||||
def api_tokens(self) -> AccessModel:
|
||||
return AccessModel(self.session, pk_id, LongLiveToken, LongLiveTokenInDB)
|
||||
|
||||
@cached_property
|
||||
def tokens_pw_reset(self) -> AccessModel[PrivatePasswordResetToken, PasswordResetModel]:
|
||||
return AccessModel(self.session, pk_token, PasswordResetModel, PrivatePasswordResetToken)
|
||||
|
||||
# ================================================================
|
||||
# Group Items
|
||||
|
||||
@@ -126,7 +132,7 @@ class Database:
|
||||
|
||||
@cached_property
|
||||
def group_invite_tokens(self) -> AccessModel:
|
||||
return AccessModel(self.session, "token", GroupInviteToken, ReadInviteToken)
|
||||
return AccessModel(self.session, pk_token, GroupInviteToken, ReadInviteToken)
|
||||
|
||||
@cached_property
|
||||
def group_preferences(self) -> AccessModel:
|
||||
|
||||
@@ -5,9 +5,9 @@ from ._access_model import AccessModel
|
||||
|
||||
|
||||
class UserDataAccessModel(AccessModel[PrivateUser, User]):
|
||||
def update_password(self, session, id, password: str):
|
||||
def update_password(self, id, password: str):
|
||||
entry = self._query_one(match_value=id)
|
||||
entry.update_password(password)
|
||||
session.commit()
|
||||
self.session.commit()
|
||||
|
||||
return self.schema.from_orm(entry)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from mealie.core import root_logger
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.core.security import hash_password
|
||||
from mealie.db.data_access_layer.access_model_factory import Database
|
||||
|
||||
logger = root_logger.get_logger("init_users")
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
def dev_users() -> list[dict]:
|
||||
|
||||
@@ -2,7 +2,9 @@ import sqlalchemy as sa
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.config import get_app_settings
|
||||
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
def sql_global_init(db_url: str):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from mealie.core import root_logger
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.db.data_access_layer.access_model_factory import Database
|
||||
from mealie.db.data_initialization.init_units_foods import default_recipe_unit_init
|
||||
from mealie.db.data_initialization.init_users import default_user_init
|
||||
@@ -13,6 +13,8 @@ from mealie.services.group_services.group_utils import create_new_group
|
||||
|
||||
logger = root_logger.get_logger("init_db")
|
||||
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
def create_all_models():
|
||||
import mealie.db.models._all_models # noqa: F401
|
||||
|
||||
@@ -2,7 +2,7 @@ import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.db.models.group.invite_tokens import GroupInviteToken
|
||||
|
||||
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||
@@ -13,6 +13,8 @@ from .cookbook import CookBook
|
||||
from .mealplan import GroupMealPlan
|
||||
from .preferences import GroupPreferencesModel
|
||||
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
class Group(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "groups"
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
from .password_reset import *
|
||||
from .user_to_favorite import *
|
||||
from .users import *
|
||||
|
||||
15
mealie/db/models/users/password_reset.py
Normal file
15
mealie/db/models/users/password_reset.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from sqlalchemy import Column, ForeignKey, Integer, String, orm
|
||||
|
||||
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||
|
||||
|
||||
class PasswordResetModel(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "password_reset_tokens"
|
||||
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||
user = orm.relationship("User", back_populates="password_reset_tokens", uselist=False)
|
||||
token = Column(String(64), unique=True, nullable=False)
|
||||
|
||||
def __init__(self, user_id, token, **_):
|
||||
self.user_id = user_id
|
||||
self.token = token
|
||||
@@ -1,11 +1,13 @@
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, orm
|
||||
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.config import get_app_settings
|
||||
|
||||
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||
from ..group import Group
|
||||
from .user_to_favorite import users_to_favorites
|
||||
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
class LongLiveToken(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "long_live_tokens"
|
||||
@@ -48,6 +50,10 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
"RecipeComment", back_populates="user", cascade="all, delete, delete-orphan", single_parent=True
|
||||
)
|
||||
|
||||
password_reset_tokens = orm.relationship(
|
||||
"PasswordResetModel", back_populates="user", cascade="all, delete, delete-orphan", single_parent=True
|
||||
)
|
||||
|
||||
owned_recipes_id = Column(Integer, ForeignKey("recipes.id"))
|
||||
owned_recipes = orm.relationship("RecipeModel", single_parent=True, foreign_keys=[owned_recipes_id])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user