feat: add im group mention flows
This commit is contained in:
@@ -1052,6 +1052,14 @@ func (t *Topic) saveAndBroadcastMessage(msg *ClientComMessage, asUid types.Uid,
|
||||
return types.ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
if t.cat == types.TopicCatGrp && head != nil && msg.sess != nil && msg.sess.authLvl != auth.LevelRoot {
|
||||
normalized, err := t.validateAndNormalizeMentions(asUid, head)
|
||||
if err != nil {
|
||||
msg.sess.queueOut(ErrPermissionDenied(msg.Id, t.original(asUid), msg.Timestamp))
|
||||
return err
|
||||
}
|
||||
head = normalized
|
||||
}
|
||||
if t.cat == types.TopicCatP2P && msg.sess != nil && msg.sess.authLvl != auth.LevelRoot &&
|
||||
store.Relations != nil && store.Store != nil && store.Store.IsOpen() {
|
||||
peer := t.p2pOtherUser(asUid)
|
||||
@@ -1196,6 +1204,67 @@ func (t *Topic) handlePubBroadcast(msg *ClientComMessage) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Topic) validateAndNormalizeMentions(asUid types.Uid, head map[string]any) (map[string]any, error) {
|
||||
mentionAll, _ := head["mention_all"].(bool)
|
||||
rawMentions, hasMentions := head["mentions"]
|
||||
if !mentionAll && !hasMentions {
|
||||
return head, nil
|
||||
}
|
||||
pud := t.perUser[asUid]
|
||||
access := pud.modeGiven & pud.modeWant
|
||||
if mentionAll && !access.IsAdmin() {
|
||||
return nil, types.ErrPermissionDenied
|
||||
}
|
||||
validMembers := make(map[string]struct{}, len(t.perUser))
|
||||
for uid, pud := range t.perUser {
|
||||
mode := pud.modeGiven & pud.modeWant
|
||||
if !pud.deleted && mode.IsJoiner() && mode.IsReader() {
|
||||
validMembers[uid.UserId()] = struct{}{}
|
||||
}
|
||||
}
|
||||
normalized := make(map[string]any, len(head))
|
||||
for key, value := range head {
|
||||
normalized[key] = value
|
||||
}
|
||||
if hasMentions {
|
||||
filtered := filterValidMentions(rawMentions, validMembers)
|
||||
if len(filtered) == 0 {
|
||||
delete(normalized, "mentions")
|
||||
} else {
|
||||
normalized["mentions"] = filtered
|
||||
}
|
||||
}
|
||||
return normalized, nil
|
||||
}
|
||||
|
||||
func filterValidMentions(raw any, validMembers map[string]struct{}) []map[string]any {
|
||||
mentions, ok := raw.([]any)
|
||||
if !ok {
|
||||
if typed, ok := raw.([]map[string]any); ok {
|
||||
mentions = make([]any, 0, len(typed))
|
||||
for _, item := range typed {
|
||||
mentions = append(mentions, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(mentions) == 0 {
|
||||
return nil
|
||||
}
|
||||
filtered := make([]map[string]any, 0, len(mentions))
|
||||
for _, item := range mentions {
|
||||
mention, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
userID, _ := mention["user_id"].(string)
|
||||
if _, ok = validMembers[userID]; !ok {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, mention)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
// handleNoteBroadcast fans out {note} -> {info} messages to recipients in a master topic.
|
||||
// This is a NON-proxy broadcast (at master topic).
|
||||
func (t *Topic) handleNoteBroadcast(msg *ClientComMessage) {
|
||||
|
||||
Reference in New Issue
Block a user