0.13.23 : return the caller's conversations without opening private messages
Build release Docker image / Build Docker Images (push) Successful in 7m47s
Build release Docker image / Build Docker Images (push) Successful in 7m47s
La messagerie affichait des conversations vides : ni nom, ni interlocuteur, ni message. Le front peuplait `conversation` et ses `messages` via l'API REST, dont le sanitizer retire toute relation vers un content-type que le rôle ne peut pas lire — or ni `chat-conversation.find` ni `chat-message.find` ne sont accordées. Les accorder aurait suffi, mais aurait ouvert la lecture de TOUTES les conversations et de TOUS les messages privés à n'importe quel compte connecté. On ajoute donc une action dédiée : - GET /api/chat-conversation-members/mine — conversations du seul appelant, avec interlocuteurs et messages, renvoyées via ctx.send - mot de passe et jetons retirés des utilisateurs peuplés - permission `mine` déclarée dans permissions-sync, avec la raison pour laquelle les deux `find` restent volontairement absentes Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,85 @@
|
||||
* chat-conversation-member controller
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi'
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController('api::chat-conversation-member.chat-conversation-member');
|
||||
export default factories.createCoreController(
|
||||
"api::chat-conversation-member.chat-conversation-member",
|
||||
({ strapi }) => ({
|
||||
/**
|
||||
* Conversations de l'utilisateur courant, avec leurs interlocuteurs et
|
||||
* leurs messages.
|
||||
*
|
||||
* Pourquoi une action dédiée plutôt que le `find` générique : le front
|
||||
* peuplait `conversation` et ses `messages` à travers l'API REST, dont le
|
||||
* sanitizer retire toute relation vers un content-type que le rôle n'a pas
|
||||
* le droit de lire. Les conversations revenaient donc vides — ni nom, ni
|
||||
* interlocuteur, ni message.
|
||||
*
|
||||
* Accorder `chat-conversation.find` et `chat-message.find` aurait suffi à
|
||||
* lever le filtrage, mais aurait ouvert la lecture de **toutes** les
|
||||
* conversations et de **tous** les messages privés à n'importe quel compte
|
||||
* connecté. Cette action retourne les données via `ctx.send`, en les
|
||||
* limitant à l'appelant.
|
||||
*/
|
||||
async mine(ctx) {
|
||||
const userId = ctx.state.user?.id;
|
||||
|
||||
if (!userId) {
|
||||
return ctx.unauthorized();
|
||||
}
|
||||
|
||||
const members = await strapi.db
|
||||
.query("api::chat-conversation-member.chat-conversation-member")
|
||||
.findMany({
|
||||
where: { user: { id: userId } },
|
||||
populate: {
|
||||
user: true,
|
||||
conversation: {
|
||||
populate: {
|
||||
users: { populate: { avatar: true } },
|
||||
messages: {
|
||||
populate: {
|
||||
sender: { populate: { avatar: true } },
|
||||
media: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Les entités portent le mot de passe et les jetons des utilisateurs
|
||||
// peuplés : on ne renvoie jamais ces champs au navigateur.
|
||||
const stripUser = (user: any) => {
|
||||
if (!user) return user;
|
||||
const {
|
||||
password,
|
||||
resetPasswordToken,
|
||||
confirmationToken,
|
||||
...safeUser
|
||||
} = user;
|
||||
return safeUser;
|
||||
};
|
||||
|
||||
const sanitized = members.map((member: any) => ({
|
||||
...member,
|
||||
user: stripUser(member.user),
|
||||
conversation: member.conversation
|
||||
? {
|
||||
...member.conversation,
|
||||
users: (member.conversation.users ?? []).map(stripUser),
|
||||
messages: (member.conversation.messages ?? []).map(
|
||||
(message: any) => ({
|
||||
...message,
|
||||
sender: stripUser(message.sender),
|
||||
})
|
||||
),
|
||||
}
|
||||
: null,
|
||||
}));
|
||||
|
||||
ctx.send(sanitized);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Routes personnalisées de chat-conversation-member.
|
||||
*/
|
||||
|
||||
export default {
|
||||
routes: [
|
||||
{
|
||||
method: "GET",
|
||||
path: "/chat-conversation-members/mine",
|
||||
handler: "chat-conversation-member.mine",
|
||||
},
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user