-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat(23UG-41): добавляет API и серверную часть форума #53
Conversation
const { themes, currentMessages } = useSelector(forumSelect); | ||
const user = useSelector(authSelect).user as User; | ||
const themeId = useParams().themeId as string; | ||
const { user_id, title } = themes.find((theme) => theme.id === +themeId) as ThemeType; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
При перезагрузке страницы здесь ошибка выходит
TypeError: Cannot destructure property 'user_id' of 'themes.find(...)' as it is undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вчера до поздней ночи не мог понять происхождение этой ошибки - точки останова, debagger и console.log почему-то не отрабатывали. Когда попробовал решить с помощью sessionStorage и увидел ошибку: sessionStorage - undefined, понял, что код выполняется в node и вспомнил про SSR.
В общем, ошибка возникала из-за того, что при SSR мы, на тот момент, ещё не делали запрос за всеми темами.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Без SSR была бы та же ошибка, только не на странице выведена, а в консоли, поскольку и на клиенте мы еще не делали запрос за всеми темами. Просто SSR раньше отработал - раньше сломался. Точки останова и прочие прелести не работали, т.к. скрипт не загрузился в браузер - в HTML только ошибка с сервера распечатана.
И по итогу, после приделывания авторизации ошибка сохраняется ))
router.get("/themes/", Forum.getThemes); | ||
router.post("/themes/", Forum.postTheme); | ||
router.delete("/themes/:theme_id", Forum.deleteTheme); | ||
// сообщения | ||
router.get("/messages/:theme_id", Forum.getMessages); | ||
router.post("/messages/", Forum.postMessage); | ||
// реакции | ||
router.get("/reactions/:theme_id", Forum.getReactions); | ||
router.post("/reactions/", Forum.postReaction); | ||
router.delete("/reactions/:reaction_id", Forum.deleteReaction); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот это вот все я могу делать не будучи авторизованным. Мне кажется, что это нехорошо ))
Пруф. Сейчас уже реализована возможность получить пользователя и есть пример в routes/index
. Возможно в этом же PR имеет смысл приделать проверку пользователя.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Видел твой роут с проверкой авторизации, но почему-то подумал, что он каким-то магическим образом уже работает)))
Спасибо, за наглядное видео и за то, что всё для меня подготовил, подключил эту проверку.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А когда будет проверка авторизации, пользователя, для которого создается тема/сообщение/реакция, надо будет брать не из req.body а из данных авторизации
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Извиняюсь, но этот момент не понял..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Первую часть вопроса я тоже не понял - проверка сделана через мидлвару и если пользователь не пользователь, то работать с темами/реакциями/сообщениями возможности не будет.
Что касается второй части вопроса. Возможно речь о том, что сейчас пользователь, для которого создается тема, берется из req.body
, а должен из пользователя, которого получили с помощью аутентификационной куки. В этом случае в мидлваре нужно сохранить куда-то пользователя и в местах, где он нужен работать с этим сохраненным пользователем.
@Olegas, поясните пожалуйста подробнее по этому пункту
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Что касается второй части вопроса. Возможно речь о том, что сейчас пользователь, для которого создается тема, берется из
req.body
, а должен из пользователя, которого получили с помощью аутентификационной куки. В этом случае в мидлваре нужно сохранить куда-то пользователя и в местах, где он нужен работать с этим сохраненным пользователем.
@cap-Bernardito @EAbashin да, речь именно об этом. Если у вас действие выполняется для авторизованного пользователя, то надо брать это из достоверного источника. Параметры в запросе - не достоверный источник. Верно - мидлвара должна куда-то в request сохранить данные текущего пользователя и дальше контроллеры должны брать оттуда
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Понял, спасибо! Изменил.
packages/client/src/entry-server.tsx
Outdated
|
||
await loadUser(store.dispatch); | ||
await getThemes(store.dispatch); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут темы для форума нездорово получать, т.к. они не для всех страниц нужны (а пользователь для всех). Для этой цели ниже добавлена обработка метода load
для роутов.
Ну и оно так просто не работает, нужно добавлять методы в UserService
, аналогично работе с пользователем. Отправлю коммит, как я думал, это должно работать. Посмотри в нем TODO по типам - нужно дописать
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Исправил
parent_message_id, | ||
parent_message_text, | ||
}; | ||
dispatch(forumThunks.postMessage(data)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А что если достать все нужные данные (типа данных о пользователе) внутри action creator'а, а передать в него только данные о посте (родитель, текст).
Кстати, а зачем нужен текст родительского поста?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В данном случае, мы ранее уже получили данные user для сравнения id создателя темы и id текущего пользователя и, на мой взгляд, будет лишним дополнительно получать данные user ещё и в санке, удобнее сразу передать уже готовые данные с диспатчем.
Нужен для отображения при ответе на это сообщение, чтобы не делать лишний запрос. Очень удобно - например, если на странице 20 сообщений с ответами, то не нужно делать 20 лишних запросов.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Про родительский пост. Так это я тогда могу писать ответы на то чего не было (опять же подложить в вызов какой-то свой текст и будет выглядеть как будто это был текст поста, на который я пишу ответ). Плохая история. А где там 20 запросов? Почему нельзя вытянуть все одним запросом? Вроде даже ORM позволяет связанные сущности вытаскивать.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не учёл эту уязвимость и, наверное, уставший был, когда писал про запросы)) У нас же в стейте уже есть все сообщения выбранной темы, надо просто найти нужное по id.
Исправил.
packages/client/src/pages/ForumPage/MessageItem/MessageItem.tsx
Outdated
Show resolved
Hide resolved
packages/client/src/pages/ForumPage/MessageItem/MessageItem.tsx
Outdated
Show resolved
Hide resolved
res.status(400).json({ error: (error as Error).message }); | ||
} | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А где сделана проверка что я могу удалять только свои сообщения/темы/реакции?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
На фронте:
- если теме не твоя, то не увидишь кнопку удаления.
{user_id && user?.id === user_id && ( <IconButton aria-label="delete" color="error" onClick={handleClickOpen}> <DeleteIcon /> </IconButton> )}
- если ещё не оставлял реакцию, то сердечко без фона и при клике на него отправляется запрос на добавление реакции, если уже оставлял, то при клике - удаление реакции.
`const likesCount = useSelector(
(state) =>
state.forum.currentReactions.filter(
(reaction) => reaction.message_id === messageData.id && reaction.reaction === "like"
).length
);
const myLike = useSelector((state) =>
state.forum.currentReactions.filter(
(reaction) =>
reaction.message_id === messageData.id &&
reaction.reaction === "like" &&
reaction.user_id === user.id
)
)[0];
.....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Проверка на фронте это ок, но еще проверка должна быть на стороне бэка, т.к. я могу сформировать запрос к API руками и, если проверки нет, удалить чужую тему.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Согласен. Сделал дополнительную проверку на беке.
router.get("/themes/", Forum.getThemes); | ||
router.post("/themes/", Forum.postTheme); | ||
router.delete("/themes/:theme_id", Forum.deleteTheme); | ||
// сообщения | ||
router.get("/messages/:theme_id", Forum.getMessages); | ||
router.post("/messages/", Forum.postMessage); | ||
// реакции | ||
router.get("/reactions/:theme_id", Forum.getReactions); | ||
router.post("/reactions/", Forum.postReaction); | ||
router.delete("/reactions/:reaction_id", Forum.deleteReaction); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А когда будет проверка авторизации, пользователя, для которого создается тема/сообщение/реакция, надо будет брать не из req.body а из данных авторизации
…мы/сообщения/реакции, при добавлении сообщения имя пользователя и аватар берёт из данных авторизации, добавляет поиск и мемоизацию текста родительского сообщения
Все замечания исправлены. |
Какую задачу решаем