mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-01 16:12:02 +00:00
fix: answer for a group mailbox as the group when the group address is one of your identities #634
This commit is contained in:
@@ -45,6 +45,13 @@ describe('resolveAnswerTargets', () => {
|
||||
expect(view.targets[0].sentBy).toBeUndefined();
|
||||
});
|
||||
|
||||
it('answers as the group also when the member has the group address as an identity', () => {
|
||||
const view = resolveAnswerTargets(base(invitation(['team@example.org'], { accountId: 'team' }), {
|
||||
owner: TEAM, userEmails: ['bob@example.org', 'team@example.org'], canRsvpSelf: true,
|
||||
}));
|
||||
expect(view.targets.map((t) => [t.kind, t.participantId, t.sentBy])).toEqual([['owner', 'team', undefined]]);
|
||||
});
|
||||
|
||||
it('offers no answer for the owner without edit access, and says why', () => {
|
||||
for (const rights of [CALENDAR_PRESETS.read, { ...CALENDAR_PRESETS.read, mayRSVP: true }]) {
|
||||
const view = resolveAnswerTargets(base(invitation(['alice@example.org']), { calendar: { isShared: true, myRights: rights } }));
|
||||
|
||||
@@ -99,27 +99,31 @@ export function resolveAnswerTargets(input: ResolveAnswerInput): AnswerView {
|
||||
|
||||
if (calendar?.isShared && owner) {
|
||||
const ownerId = getUserParticipantId(event, owner.emails);
|
||||
if (ownerId && ownerId !== selfId && !isOrganizer(event, owner.emails) && !eventHasNoOwner(event)) {
|
||||
const participant = event.participants![ownerId];
|
||||
// Members of a group often have the group's address as an identity of
|
||||
// their own: the group's participant is still answered as the group.
|
||||
const ownersOwn = ownerId && (ownerId !== selfId || owner.isGroup);
|
||||
if (ownersOwn && !isOrganizer(event, owner.emails) && !eventHasNoOwner(event)) {
|
||||
const participant = event.participants![ownerId!];
|
||||
const answeredBy = addressOf(participant.sentBy);
|
||||
if (!calendar.myRights?.mayWriteAll) {
|
||||
return { targets: selfTarget(), note: { kind: 'no_write', owner: owner.name }, answeredBy };
|
||||
}
|
||||
if (input.server016 && selfId) {
|
||||
const alsoInvited = !!selfId && selfId !== ownerId;
|
||||
if (input.server016 && alsoInvited) {
|
||||
return { targets: ownCopyTarget(), note: { kind: 'also_invited', owner: owner.name }, answeredBy };
|
||||
}
|
||||
const delegate = userEmails[0]?.trim().toLowerCase();
|
||||
const ownerTarget: AnswerTarget = {
|
||||
kind: 'owner',
|
||||
eventId: event.id,
|
||||
participantId: ownerId,
|
||||
participantId: ownerId!,
|
||||
status: participant.participationStatus ?? null,
|
||||
ownerName: owner.name,
|
||||
// Always the mailto: form: Stalwart passes sentBy through unchecked,
|
||||
// and RFC 5545's SENT-BY needs a cal-address.
|
||||
...(!owner.isGroup && delegate ? { sentBy: `mailto:${delegate}` } : {}),
|
||||
};
|
||||
return { targets: [ownerTarget, ...(selfId ? ownCopyTarget() : [])], note: null, answeredBy };
|
||||
return { targets: [ownerTarget, ...(alsoInvited ? ownCopyTarget() : [])], note: null, answeredBy };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user