diff --git a/components/email/__tests__/calendar-invitation-banner.test.tsx b/components/email/__tests__/calendar-invitation-banner.test.tsx
index 036eba6df..41672acdd 100644
--- a/components/email/__tests__/calendar-invitation-banner.test.tsx
+++ b/components/email/__tests__/calendar-invitation-banner.test.tsx
@@ -97,6 +97,7 @@ vi.mock('next-intl', () => ({
actor_note: 'Note: {comment}',
actor_unknown: 'Someone',
sender_mismatch_unverified_info: 'This invitation was sent from {sender}, while the organizer listed in the calendar data is {organizer}, and the message could not be verified.',
+ attendee_mismatch_unverified_info: 'This response was sent from {sender}, while the attendee answering in the calendar data is {attendee}, and the message could not be verified.',
action_failed: 'Could not complete that calendar action.',
proposal_applied: 'Proposed changes applied.',
proposed_changes: 'Proposed changes',
@@ -890,6 +891,32 @@ describe('CalendarInvitationBanner', () => {
expect(mocks.calendarState.updateEvent).not.toHaveBeenCalled();
});
+ it("checks a reply's sender against the attendee who answers, not the organizer", async () => {
+ const reply = {
+ uid: 'uid-14', title: 'Sync', start: '2026-03-27T09:00:00Z', duration: 'PT1H',
+ organizerCalendarAddress: 'mailto:user@example.com',
+ participants: {
+ a: { '@type': 'Participant', calendarAddress: 'mailto:user@example.com', roles: { owner: true, attendee: true }, participationStatus: 'accepted' },
+ b: { '@type': 'Participant', calendarAddress: 'mailto:alice@example.com', roles: { attendee: true }, participationStatus: 'accepted' },
+ },
+ };
+ mocks.clientMock.parseCalendarEvents.mockResolvedValue([reply]);
+ const replyFrom = (id: string, from: string) => makeEmail({
+ id, from: [{ email: from }],
+ attachments: [{ partId: '1', blobId: `blob-${id}`, size: 256, type: 'text/calendar; method=REPLY', name: 'reply.ics' }],
+ });
+
+ const { unmount } = render();
+ await waitFor(() => expect(screen.getByRole('heading', { name: 'Sync' })).toBeInTheDocument());
+ expect(screen.queryByText(/was sent from/)).toBeNull();
+ unmount();
+
+ render();
+ await waitFor(() => expect(screen.getByText(
+ 'This response was sent from mallory@evil.example, while the attendee answering in the calendar data is alice@example.com, and the message could not be verified.',
+ )).toBeInTheDocument());
+ });
+
it('lets a proposal from an attendee Stalwart lists by calendar address be applied', async () => {
mocks.calendarState.updateEvent = vi.fn().mockResolvedValue(true);
// As 0.16 and 1.0 store and parse them: mailto: calendar addresses, no email.
diff --git a/components/email/calendar-invitation-banner.tsx b/components/email/calendar-invitation-banner.tsx
index 0ba4b332f..a002851c0 100644
--- a/components/email/calendar-invitation-banner.tsx
+++ b/components/email/calendar-invitation-banner.tsx
@@ -155,6 +155,16 @@ function getTrustMessage(
sender: trustAssessment.senderEmail ?? '',
organizer: trustAssessment.organizerEmail ?? '',
});
+ case 'attendee_mismatch':
+ return t('attendee_mismatch_info', {
+ sender: trustAssessment.senderEmail ?? '',
+ attendee: trustAssessment.attendeeEmail ?? '',
+ });
+ case 'attendee_mismatch_unverified':
+ return t('attendee_mismatch_unverified_info', {
+ sender: trustAssessment.senderEmail ?? '',
+ attendee: trustAssessment.attendeeEmail ?? '',
+ });
default:
return null;
}
diff --git a/lib/__tests__/calendar-invitation.test.ts b/lib/__tests__/calendar-invitation.test.ts
index 12b268fbc..d033a69db 100644
--- a/lib/__tests__/calendar-invitation.test.ts
+++ b/lib/__tests__/calendar-invitation.test.ts
@@ -478,6 +478,28 @@ describe('getInvitationTrustAssessment', () => {
expect(result.reason).toBeNull();
});
+ // A reply comes from the attendee, and the organizer is the user reading
+ // it: comparing with the organizer warned on every genuine reply, and a
+ // forged one looked just the same.
+ it.each(['reply', 'counter', 'refresh'] as const)('compares the sender of a %s with the attendee who answers', (method) => {
+ const event: Partial = {
+ participants: {
+ // As Stalwart parses it: the organizer is an attendee too, addresses as mailto:.
+ org: makeParticipant({ roles: { owner: true, attendee: true }, email: undefined, calendarAddress: 'mailto:me@example.com', participationStatus: 'accepted' }),
+ bob: makeParticipant({ roles: { attendee: true }, email: undefined, calendarAddress: 'mailto:Bob@example.net', participationStatus: 'accepted' }),
+ },
+ };
+ const aligned = { dkim: { result: 'pass', domain: 'example.net', selector: 's' } } as const;
+
+ const genuine = getInvitationTrustAssessment(event, makeEmail({ from: [{ email: 'bob@example.net' }], authenticationResults: aligned }), method);
+ expect(genuine.level).toBe('trusted');
+
+ const forged = getInvitationTrustAssessment(event, makeEmail({ from: [{ email: 'mallory@evil.example' }] }), method);
+ expect(forged).toMatchObject({
+ level: 'warning', reason: 'attendee_mismatch_unverified', senderEmail: 'mallory@evil.example', attendeeEmail: 'bob@example.net',
+ });
+ });
+
it('does not trust an SPF or DKIM pass for a domain other than the From domain', () => {
// MAIL FROM at the attacker's domain (SPF pass there), From and ORGANIZER
// at the victim's; the victim publishes no DMARC policy, so dmarc=none.
diff --git a/lib/calendar-invitation.ts b/lib/calendar-invitation.ts
index 2ff7a22ea..ab95bdf51 100644
--- a/lib/calendar-invitation.ts
+++ b/lib/calendar-invitation.ts
@@ -21,9 +21,13 @@ export interface InvitationTrustAssessment {
| 'authentication_missing'
| 'sender_mismatch'
| 'sender_mismatch_unverified'
+ | 'attendee_mismatch'
+ | 'attendee_mismatch_unverified'
| null;
senderEmail: string | null;
organizerEmail: string | null;
+ /** The attendee who answers in a reply, counter or refresh. */
+ attendeeEmail: string | null;
}
export interface InvitationActorSummary {
@@ -399,17 +403,22 @@ export function getInvitationTrustAssessment(
): InvitationTrustAssessment {
const organizerEmail = getOrganizerEmail(event);
const senderEmail = getPrimaryAddressEmail(email?.from) || getPrimaryAddressEmail(email?.replyTo);
+ // A reply, counter or refresh is sent by the attendee who answers; the
+ // organizer is usually the user reading it.
+ const fromAttendee = method === 'reply' || method === 'counter' || method === 'refresh';
+ const attendeeEmail = fromAttendee ? getInvitationActorSummary(event, method)?.email ?? null : null;
+ const expectedEmail = fromAttendee ? attendeeEmail : organizerEmail;
const verifiedAuthentication = hasVerifiedAuthentication(email);
const authenticationFailure = hasAuthenticationFailure(email);
- const senderMismatch = Boolean(senderEmail && organizerEmail && senderEmail !== organizerEmail);
+ const senderMismatch = Boolean(senderEmail && expectedEmail && senderEmail !== expectedEmail);
const expectsAuthenticatedTransport = method !== 'unknown';
+ const addresses = { senderEmail, organizerEmail, attendeeEmail };
if (senderMismatch && (authenticationFailure || !verifiedAuthentication)) {
return {
level: 'warning',
- reason: 'sender_mismatch_unverified',
- senderEmail,
- organizerEmail,
+ reason: fromAttendee ? 'attendee_mismatch_unverified' : 'sender_mismatch_unverified',
+ ...addresses,
};
}
@@ -417,17 +426,15 @@ export function getInvitationTrustAssessment(
return {
level: 'warning',
reason: 'authentication_failed',
- senderEmail,
- organizerEmail,
+ ...addresses,
};
}
if (senderMismatch) {
return {
level: 'caution',
- reason: 'sender_mismatch',
- senderEmail,
- organizerEmail,
+ reason: fromAttendee ? 'attendee_mismatch' : 'sender_mismatch',
+ ...addresses,
};
}
@@ -435,16 +442,14 @@ export function getInvitationTrustAssessment(
return {
level: 'caution',
reason: 'authentication_missing',
- senderEmail,
- organizerEmail,
+ ...addresses,
};
}
return {
level: 'trusted',
reason: null,
- senderEmail,
- organizerEmail,
+ ...addresses,
};
}
diff --git a/locales/ar/common.json b/locales/ar/common.json
index 9e71b7d94..35b26f728 100644
--- a/locales/ar/common.json
+++ b/locales/ar/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "لا تتضمن هذه الدعوة مصادقة بريد موثّقة. تأكد من التفاصيل مع المنظّم إذا بدا أي شيء غير معتاد.",
"sender_mismatch_info": "أُرسلت هذه الدعوة من {sender}، بينما المنظّم المدرج في بيانات التقويم هو {organizer}.",
"sender_mismatch_unverified_info": "أُرسلت هذه الدعوة من {sender}، بينما المنظّم المدرج في بيانات التقويم هو {organizer}، ولم يتم التحقق من الرسالة.",
+ "attendee_mismatch_info": "أُرسل هذا الرد من {sender}، بينما الحاضر المجيب في بيانات التقويم هو {attendee}.",
+ "attendee_mismatch_unverified_info": "أُرسل هذا الرد من {sender}، بينما الحاضر المجيب في بيانات التقويم هو {attendee}، ولم يتم التحقق من الرسالة.",
"organizer_role": "أنت منظّم هذا الحدث",
"your_response": "ردّك: {status}",
"response_needed": "بحاجة إلى رد",
diff --git a/locales/ca/common.json b/locales/ca/common.json
index ea9fe96ff..ec2b94af8 100644
--- a/locales/ca/common.json
+++ b/locales/ca/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Aquesta invitació no inclou autenticació de correu verificada. Confirmeu els detalls amb l'organitzador si alguna cosa sembla estranya.",
"sender_mismatch_info": "Aquesta invitació s'ha enviat des de {sender}, mentre que l'organitzador indicat a les dades del calendari és {organizer}.",
"sender_mismatch_unverified_info": "Aquesta invitació s'ha enviat des de {sender}, mentre que l'organitzador indicat a les dades del calendari és {organizer}, i no s'ha pogut verificar el missatge.",
+ "attendee_mismatch_info": "Aquesta resposta s'ha enviat des de {sender}, mentre que l'assistent que respon a les dades del calendari és {attendee}.",
+ "attendee_mismatch_unverified_info": "Aquesta resposta s'ha enviat des de {sender}, mentre que l'assistent que respon a les dades del calendari és {attendee}, i no s'ha pogut verificar el missatge.",
"organizer_role": "Vós organitzeu aquest esdeveniment",
"your_response": "La vostra resposta: {status}",
"response_needed": "Cal resposta",
diff --git a/locales/cs/common.json b/locales/cs/common.json
index df339741b..5101b52f7 100644
--- a/locales/cs/common.json
+++ b/locales/cs/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "Tato pozvánka neobsahuje ověření zprávy. Pokud se vám cokoli zdá neobvyklé, potvrďte si podrobnosti s organizátorem.",
"sender_mismatch_info": "Tato pozvánka byla odeslána od {sender}, zatímco organizátor v datech kalendáře je {organizer}.",
"sender_mismatch_unverified_info": "Tato pozvánka byla odeslána od {sender}, zatímco organizátor v datech kalendáře je {organizer}, a zprávu se nepodařilo ověřit.",
+ "attendee_mismatch_info": "Tato odpověď byla odeslána od {sender}, zatímco odpovídající účastník v datech kalendáře je {attendee}.",
+ "attendee_mismatch_unverified_info": "Tato odpověď byla odeslána od {sender}, zatímco odpovídající účastník v datech kalendáře je {attendee}, a zprávu se nepodařilo ověřit.",
"organizer_role": "Jste organizátorem této události",
"your_response": "Vaše odpověď: {status}",
"response_needed": "Vyžaduje odpověď",
diff --git a/locales/da/common.json b/locales/da/common.json
index 00fe3b0f9..dadb5b8e5 100644
--- a/locales/da/common.json
+++ b/locales/da/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Denne invitation inkluderer ikke bekræftet mailgodkendelse. Bekræft detaljerne med organisatoren, hvis noget ser usædvanligt ud.",
"sender_mismatch_info": "Denne invitation blev sendt fra {sender}, mens organisatoren i kalenderdataene er {organizer}.",
"sender_mismatch_unverified_info": "Denne invitation blev sendt fra {sender}, mens organisatoren i kalenderdataene er {organizer}, og beskeden kunne ikke bekræftes.",
+ "attendee_mismatch_info": "Dette svar blev sendt fra {sender}, mens deltageren, der svarer i kalenderdataene, er {attendee}.",
+ "attendee_mismatch_unverified_info": "Dette svar blev sendt fra {sender}, mens deltageren, der svarer i kalenderdataene, er {attendee}, og beskeden kunne ikke bekræftes.",
"organizer_role": "Du organiserer denne begivenhed",
"your_response": "Dit svar: {status}",
"response_needed": "Kræver svar",
diff --git a/locales/de/common.json b/locales/de/common.json
index 3fe99327e..216751562 100644
--- a/locales/de/common.json
+++ b/locales/de/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Diese Einladung enthält keine verifizierte Mail-Authentifizierung. Bestätigen Sie die Details mit dem Organisator, wenn etwas ungewöhnlich wirkt.",
"sender_mismatch_info": "Diese Einladung wurde von {sender} gesendet, während der in den Kalenderdaten angegebene Organisator {organizer} ist.",
"sender_mismatch_unverified_info": "Diese Einladung wurde von {sender} gesendet, während der in den Kalenderdaten angegebene Organisator {organizer} ist, und die Nachricht konnte nicht verifiziert werden.",
+ "attendee_mismatch_info": "Diese Antwort wurde von {sender} gesendet, während der antwortende Teilnehmer in den Kalenderdaten {attendee} ist.",
+ "attendee_mismatch_unverified_info": "Diese Antwort wurde von {sender} gesendet, während der antwortende Teilnehmer in den Kalenderdaten {attendee} ist, und die Nachricht konnte nicht verifiziert werden.",
"organizer_role": "Sie organisieren dieses Ereignis",
"your_response": "Ihre Antwort: {status}",
"response_needed": "Antwort ausstehend",
diff --git a/locales/en/common.json b/locales/en/common.json
index b9d547a9c..f2bf8ecdd 100644
--- a/locales/en/common.json
+++ b/locales/en/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "This invitation does not include verified mail authentication. Confirm the details with the organizer if anything looks unusual.",
"sender_mismatch_info": "This invitation was sent from {sender}, while the organizer listed in the calendar data is {organizer}.",
"sender_mismatch_unverified_info": "This invitation was sent from {sender}, while the organizer listed in the calendar data is {organizer}, and the message could not be verified.",
+ "attendee_mismatch_info": "This response was sent from {sender}, while the attendee answering in the calendar data is {attendee}.",
+ "attendee_mismatch_unverified_info": "This response was sent from {sender}, while the attendee answering in the calendar data is {attendee}, and the message could not be verified.",
"organizer_role": "You organize this event",
"your_response": "Your response: {status}",
"response_needed": "Needs response",
diff --git a/locales/es/common.json b/locales/es/common.json
index 305b43674..37b41a8e8 100644
--- a/locales/es/common.json
+++ b/locales/es/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Esta invitación no incluye autenticación de correo verificada. Confirma los detalles con el organizador si algo parece inusual.",
"sender_mismatch_info": "Esta invitación se envió desde {sender}, mientras que el organizador indicado en los datos del calendario es {organizer}.",
"sender_mismatch_unverified_info": "Esta invitación se envió desde {sender}, mientras que el organizador indicado en los datos del calendario es {organizer}, y el mensaje no pudo verificarse.",
+ "attendee_mismatch_info": "Esta respuesta se envió desde {sender}, mientras que el asistente que responde en los datos del calendario es {attendee}.",
+ "attendee_mismatch_unverified_info": "Esta respuesta se envió desde {sender}, mientras que el asistente que responde en los datos del calendario es {attendee}, y el mensaje no pudo verificarse.",
"organizer_role": "Organizas este evento",
"your_response": "Tu respuesta: {status}",
"response_needed": "Pendiente de respuesta",
diff --git a/locales/et/common.json b/locales/et/common.json
index c6253c0c7..7be101509 100644
--- a/locales/et/common.json
+++ b/locales/et/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Sellel kutsel puudub kinnitatud e-posti autentimine. Kui midagi tundub kahtlane, kontrolli üksikasju korraldajaga.",
"sender_mismatch_info": "See kutse saadeti aadressilt {sender}, kuid kalendriandmetes märgitud korraldaja on {organizer}.",
"sender_mismatch_unverified_info": "See kutse saadeti aadressilt {sender}, kuid kalendriandmetes märgitud korraldaja on {organizer}, ning kirja ei õnnestunud kinnitada.",
+ "attendee_mismatch_info": "See vastus saadeti aadressilt {sender}, kuid kalendriandmetes vastav osaleja on {attendee}.",
+ "attendee_mismatch_unverified_info": "See vastus saadeti aadressilt {sender}, kuid kalendriandmetes vastav osaleja on {attendee}, ning kirja ei õnnestunud kinnitada.",
"organizer_role": "Sina oled selle sündmuse korraldaja",
"your_response": "Sinu vastus: {status}",
"response_needed": "Vajab vastust",
diff --git a/locales/fa/common.json b/locales/fa/common.json
index 15f0843c5..f06930529 100644
--- a/locales/fa/common.json
+++ b/locales/fa/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "این دعوتنامه فاقد احراز هویت ایمیل است.",
"sender_mismatch_info": "این دعوتنامه از {sender} ارسال شده ولی برگزارکننده {organizer} است.",
"sender_mismatch_unverified_info": "از {sender} ارسال شده ولی برگزارکننده {organizer} است و پیام تأیید نشد.",
+ "attendee_mismatch_info": "این پاسخ از {sender} ارسال شده ولی شرکتکنندهی پاسخدهنده {attendee} است.",
+ "attendee_mismatch_unverified_info": "این پاسخ از {sender} ارسال شده ولی شرکتکنندهی پاسخدهنده {attendee} است و پیام تأیید نشد.",
"organizer_role": "شما برگزارکننده این رویداد هستید",
"your_response": "پاسخ شما: {status}",
"response_needed": "نیاز به پاسخ",
diff --git a/locales/fr/common.json b/locales/fr/common.json
index 0bd1ee8b6..54fc124d8 100644
--- a/locales/fr/common.json
+++ b/locales/fr/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Cette invitation ne comporte pas d'authentification de messagerie vérifiée. Vérifiez les détails avec l'organisateur si quelque chose semble inhabituel.",
"sender_mismatch_info": "Cette invitation a été envoyée depuis {sender}, alors que l'organisateur indiqué dans les données du calendrier est {organizer}.",
"sender_mismatch_unverified_info": "Cette invitation a été envoyée depuis {sender}, alors que l'organisateur indiqué dans les données du calendrier est {organizer}, et le message n'a pas pu être vérifié.",
+ "attendee_mismatch_info": "Cette réponse a été envoyée depuis {sender}, alors que le participant qui répond dans les données du calendrier est {attendee}.",
+ "attendee_mismatch_unverified_info": "Cette réponse a été envoyée depuis {sender}, alors que le participant qui répond dans les données du calendrier est {attendee}, et le message n'a pas pu être vérifié.",
"organizer_role": "Vous organisez cet événement",
"your_response": "Votre réponse : {status}",
"response_needed": "Réponse requise",
diff --git a/locales/he/common.json b/locales/he/common.json
index f7323b901..0f9ee1090 100644
--- a/locales/he/common.json
+++ b/locales/he/common.json
@@ -488,6 +488,8 @@
"authentication_missing_info": "הזמנה זו אינה כוללת אימות דואר מאומת. אשר את הפרטים עם המארגן אם משהו נראה חריג.",
"sender_mismatch_info": "הזמנה זו נשלחה מ-{sender}, בעוד שהמארגן הרשום בנתוני היומן הוא{organizer}.",
"sender_mismatch_unverified_info": "הזמנה זו נשלחה מ-{sender}, בעוד שהמארגן הרשום בנתוני היומן הוא{organizer}, ולא ניתן לאמת את ההודעה.",
+ "attendee_mismatch_info": "תגובה זו נשלחה מ-{sender}, בעוד שהמשתתף המשיב בנתוני היומן הוא {attendee}.",
+ "attendee_mismatch_unverified_info": "תגובה זו נשלחה מ-{sender}, בעוד שהמשתתף המשיב בנתוני היומן הוא {attendee}, ולא ניתן לאמת את ההודעה.",
"organizer_role": "אתה מארגן את האירוע הזה",
"your_response": "תגובתך:{status}",
"response_needed": "צריך תגובה",
diff --git a/locales/hu/common.json b/locales/hu/common.json
index aa004a92e..29d372a2b 100644
--- a/locales/hu/common.json
+++ b/locales/hu/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Ez a meghívó nem tartalmaz ellenőrzött e-mail hitelesítést. Ha bármi szokatlannak tűnik, erősítsd meg a részleteket a szervezővel.",
"sender_mismatch_info": "Ezt a meghívót {sender} küldte, míg a naptár adatokban szereplő szervező {organizer}.",
"sender_mismatch_unverified_info": "Ezt a meghívót {sender} küldte, míg a naptár adatokban szereplő szervező {organizer}, és az üzenet nem volt hitelesíthető.",
+ "attendee_mismatch_info": "Ezt a választ {sender} küldte, míg a naptár adatokban válaszoló résztvevő {attendee}.",
+ "attendee_mismatch_unverified_info": "Ezt a választ {sender} küldte, míg a naptár adatokban válaszoló résztvevő {attendee}, és az üzenet nem volt hitelesíthető.",
"organizer_role": "Te szervezed ezt az eseményt",
"your_response": "Válaszod: {status}",
"response_needed": "Válasz szükséges",
diff --git a/locales/it/common.json b/locales/it/common.json
index 528d5f530..733a7f3c4 100644
--- a/locales/it/common.json
+++ b/locales/it/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Questo invito non include un'autenticazione email verificata. Conferma i dettagli con l'organizzatore se qualcosa sembra insolito.",
"sender_mismatch_info": "Questo invito è stato inviato da {sender}, mentre l'organizzatore indicato nei dati del calendario è {organizer}.",
"sender_mismatch_unverified_info": "Questo invito è stato inviato da {sender}, mentre l'organizzatore indicato nei dati del calendario è {organizer}, e il messaggio non ha potuto essere verificato.",
+ "attendee_mismatch_info": "Questa risposta è stata inviata da {sender}, mentre il partecipante che risponde nei dati del calendario è {attendee}.",
+ "attendee_mismatch_unverified_info": "Questa risposta è stata inviata da {sender}, mentre il partecipante che risponde nei dati del calendario è {attendee}, e il messaggio non ha potuto essere verificato.",
"organizer_role": "Sei l'organizzatore di questo evento",
"your_response": "La tua risposta: {status}",
"response_needed": "Risposta richiesta",
diff --git a/locales/ja/common.json b/locales/ja/common.json
index 0d90ce2aa..250372613 100644
--- a/locales/ja/common.json
+++ b/locales/ja/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "この招待には検証済みのメール認証がありません。不審な点があれば主催者に詳細を確認してください。",
"sender_mismatch_info": "この招待は {sender} から送信されましたが、カレンダーデータ上の主催者は {organizer} です。",
"sender_mismatch_unverified_info": "この招待は {sender} から送信されましたが、カレンダーデータ上の主催者は {organizer} であり、メッセージも検証できませんでした。",
+ "attendee_mismatch_info": "この返信は {sender} から送信されましたが、カレンダーデータ上で返信している参加者は {attendee} です。",
+ "attendee_mismatch_unverified_info": "この返信は {sender} から送信されましたが、カレンダーデータ上で返信している参加者は {attendee} であり、メッセージも検証できませんでした。",
"organizer_role": "あなたがこのイベントの主催者です",
"your_response": "あなたの返答: {status}",
"response_needed": "返答が必要です",
diff --git a/locales/ko/common.json b/locales/ko/common.json
index 2f9f59c95..52b10e67d 100644
--- a/locales/ko/common.json
+++ b/locales/ko/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "이 초대장에는 확인된 메일 인증 정보가 없어요. 이상한 점이 있다면 주최자에게 확인해 보세요.",
"sender_mismatch_info": "초대장은 {sender}님이 보냈지만, 캘린더에 등록된 주최자는 {organizer}님이에요.",
"sender_mismatch_unverified_info": "초대장은 {sender}님이 보냈지만 캘린더의 주최자는 {organizer}님이며, 메시지를 검증할 수 없어요.",
+ "attendee_mismatch_info": "이 응답은 {sender}님이 보냈지만 캘린더에서 응답한 참석자는 {attendee}님이에요.",
+ "attendee_mismatch_unverified_info": "이 응답은 {sender}님이 보냈지만 캘린더에서 응답한 참석자는 {attendee}님이며, 메시지를 검증할 수 없어요.",
"organizer_role": "내가 주최하는 일정이에요",
"your_response": "내 응답: {status}",
"response_needed": "응답이 필요해요",
diff --git a/locales/lv/common.json b/locales/lv/common.json
index 8784a9859..65dcff2c9 100644
--- a/locales/lv/common.json
+++ b/locales/lv/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "Šim uzaicinājumam nav apstiprinātas autentifikācijas.",
"sender_mismatch_info": "Uzaicinājumu nosūtīja {sender}, bet organizators ir {organizer}.",
"sender_mismatch_unverified_info": "Uzaicinājumu nosūtīja {sender}, bet norādītais organizators ir {organizer}, un ziņojumu nevarēja pārbaudīt.",
+ "attendee_mismatch_info": "Atbildi nosūtīja {sender}, bet atbildošais dalībnieks ir {attendee}.",
+ "attendee_mismatch_unverified_info": "Atbildi nosūtīja {sender}, bet atbildošais dalībnieks ir {attendee}, un ziņojumu nevarēja pārbaudīt.",
"organizer_role": "Jūs esat šī pasākuma organizators",
"your_response": "Jūsu atbilde: {status}",
"response_needed": "Nepieciešama atbilde",
diff --git a/locales/mn/common.json b/locales/mn/common.json
index 9bd741777..565ce6cda 100644
--- a/locales/mn/common.json
+++ b/locales/mn/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Энэ урилгад баталгаажуулсан имэйлийн баталгаажуулалт ороогүй болно. Ер бусын зүйл байвал зохион байгуулагчтай дэлгэрэнгүй мэдээллийг баталгаажуулна уу.",
"sender_mismatch_info": "Энэ урилгыг {sender}-с илгээсэн бол хуанлийн өгөгдөлд жагсаасан зохион байгуулагч нь {organizer} байна.",
"sender_mismatch_unverified_info": "Энэ урилгыг {sender}-с илгээсэн бөгөөд хуанлийн өгөгдөлд жагсаасан зохион байгуулагч нь {organizer} бөгөөд мессежийг баталгаажуулж чадсангүй.",
+ "attendee_mismatch_info": "Энэ хариуг {sender}-с илгээсэн бөгөөд хуанлийн өгөгдөлд хариулж буй оролцогч нь {attendee}.",
+ "attendee_mismatch_unverified_info": "Энэ хариуг {sender}-с илгээсэн бөгөөд хуанлийн өгөгдөлд хариулж буй оролцогч нь {attendee} бөгөөд мессежийг баталгаажуулж чадсангүй.",
"organizer_role": "Та энэ арга хэмжээг зохион байгуулна",
"your_response": "Таны хариулт: {status}",
"response_needed": "Хариулт хэрэгтэй",
diff --git a/locales/nb/common.json b/locales/nb/common.json
index a5800c956..bc7fa2837 100644
--- a/locales/nb/common.json
+++ b/locales/nb/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Denne invitasjonen har ingen bekreftet e-postautentisering. Avklar detaljene med arrangøren hvis noe ser uvanlig ut.",
"sender_mismatch_info": "Denne invitasjonen ble sendt fra {sender}, mens arrangøren som er oppført i kalenderdataene er {organizer}.",
"sender_mismatch_unverified_info": "Denne invitasjonen ble sendt fra {sender}, mens arrangøren som er oppført i kalenderdataene er {organizer}, og meldingen kunne ikke bekreftes.",
+ "attendee_mismatch_info": "Dette svaret ble sendt fra {sender}, mens deltakeren som svarer i kalenderdataene er {attendee}.",
+ "attendee_mismatch_unverified_info": "Dette svaret ble sendt fra {sender}, mens deltakeren som svarer i kalenderdataene er {attendee}, og meldingen kunne ikke bekreftes.",
"organizer_role": "Du er arrangør for denne hendelsen",
"your_response": "Ditt svar: {status}",
"response_needed": "Svar kreves",
diff --git a/locales/nl/common.json b/locales/nl/common.json
index a48711b70..66344bf22 100644
--- a/locales/nl/common.json
+++ b/locales/nl/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Deze uitnodiging bevat geen geverifieerde mailauthenticatie. Controleer de details bij de organisator als iets ongewoon lijkt.",
"sender_mismatch_info": "Deze uitnodiging is verzonden vanaf {sender}, terwijl de organisator in de kalendergegevens {organizer} is.",
"sender_mismatch_unverified_info": "Deze uitnodiging is verzonden vanaf {sender}, terwijl de organisator in de kalendergegevens {organizer} is, en het bericht kon niet worden geverifieerd.",
+ "attendee_mismatch_info": "Dit antwoord is verzonden vanaf {sender}, terwijl de antwoordende deelnemer in de kalendergegevens {attendee} is.",
+ "attendee_mismatch_unverified_info": "Dit antwoord is verzonden vanaf {sender}, terwijl de antwoordende deelnemer in de kalendergegevens {attendee} is, en het bericht kon niet worden geverifieerd.",
"organizer_role": "U organiseert dit evenement",
"your_response": "Uw reactie: {status}",
"response_needed": "Reactie vereist",
diff --git a/locales/pl/common.json b/locales/pl/common.json
index 296afebe8..70de9c21b 100644
--- a/locales/pl/common.json
+++ b/locales/pl/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "To zaproszenie nie zawiera zweryfikowanego uwierzytelniania poczty. Potwierdź szczegóły z organizatorem, jeśli cokolwiek wygląda nietypowo.",
"sender_mismatch_info": "To zaproszenie zostało wysłane z {sender}, podczas gdy organizator w danych kalendarza to {organizer}.",
"sender_mismatch_unverified_info": "To zaproszenie zostało wysłane z {sender}, podczas gdy organizator w danych kalendarza to {organizer}, a wiadomość nie mogła zostać zweryfikowana.",
+ "attendee_mismatch_info": "Ta odpowiedź została wysłana z {sender}, podczas gdy odpowiadający uczestnik w danych kalendarza to {attendee}.",
+ "attendee_mismatch_unverified_info": "Ta odpowiedź została wysłana z {sender}, podczas gdy odpowiadający uczestnik w danych kalendarza to {attendee}, a wiadomość nie mogła zostać zweryfikowana.",
"organizer_role": "Jesteś organizatorem tego wydarzenia",
"your_response": "Twoja odpowiedź: {status}",
"response_needed": "Wymaga odpowiedzi",
diff --git a/locales/pt/common.json b/locales/pt/common.json
index d624dcf1f..4cebf2fdb 100644
--- a/locales/pt/common.json
+++ b/locales/pt/common.json
@@ -540,6 +540,8 @@
"authentication_missing_info": "Este convite não inclui autenticação de email verificada. Confirme os detalhes com o organizador se algo parecer incomum.",
"sender_mismatch_info": "Este convite foi enviado por {sender}, enquanto o organizador indicado nos dados do calendário é {organizer}.",
"sender_mismatch_unverified_info": "Este convite foi enviado por {sender}, enquanto o organizador indicado nos dados do calendário é {organizer}, e a mensagem não pôde ser verificada.",
+ "attendee_mismatch_info": "Esta resposta foi enviada por {sender}, enquanto o participante que responde nos dados do calendário é {attendee}.",
+ "attendee_mismatch_unverified_info": "Esta resposta foi enviada por {sender}, enquanto o participante que responde nos dados do calendário é {attendee}, e a mensagem não pôde ser verificada.",
"organizer_role": "Você organiza este evento",
"your_response": "Sua resposta: {status}",
"response_needed": "Resposta necessária",
diff --git a/locales/ro/common.json b/locales/ro/common.json
index e3390e866..97b650500 100644
--- a/locales/ro/common.json
+++ b/locales/ro/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Această invitație nu include autentificarea verificată a adresei de e-mail. Confirmați detaliile cu organizatorul dacă ceva pare neobișnuit.",
"sender_mismatch_info": "Această invitație a fost trimisă de la {sender}, în timp ce organizatorul menționat în datele din calendar este {organizer}.",
"sender_mismatch_unverified_info": "Această invitație a fost trimisă de la adresa {sender}, în timp ce organizatorul menționat în datele din calendar este {organizer}, iar mesajul nu a putut fi verificat.",
+ "attendee_mismatch_info": "Acest răspuns a fost trimis de la adresa {sender}, în timp ce participantul care răspunde în datele din calendar este {attendee}.",
+ "attendee_mismatch_unverified_info": "Acest răspuns a fost trimis de la adresa {sender}, în timp ce participantul care răspunde în datele din calendar este {attendee}, iar mesajul nu a putut fi verificat.",
"organizer_role": "Tu organizezi acest eveniment",
"your_response": "Răspunsul dvs.: {status}",
"response_needed": "Necesită răspuns",
diff --git a/locales/ru/common.json b/locales/ru/common.json
index 1fa117545..0f08f8f1d 100644
--- a/locales/ru/common.json
+++ b/locales/ru/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "Это приглашение не содержит подтверждённой аутентификации почты. Если что-то кажется необычным, уточните детали у организатора.",
"sender_mismatch_info": "Это приглашение отправлено от {sender}, тогда как организатором в данных календаря указан {organizer}.",
"sender_mismatch_unverified_info": "Это приглашение отправлено от {sender}, тогда как организатором указан {organizer}, и сообщение не удалось проверить.",
+ "attendee_mismatch_info": "Этот ответ отправлен от {sender}, тогда как отвечающим участником указан {attendee}.",
+ "attendee_mismatch_unverified_info": "Этот ответ отправлен от {sender}, тогда как отвечающим участником указан {attendee}, и сообщение не удалось проверить.",
"organizer_role": "Вы являетесь организатором этого события",
"your_response": "Ваш ответ: {status}",
"response_needed": "Требуется ответ",
diff --git a/locales/sk/common.json b/locales/sk/common.json
index 090c74190..253b3eeff 100644
--- a/locales/sk/common.json
+++ b/locales/sk/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "Táto pozvánka neobsahuje overené overenie správ. Potvrdte podrobnosti s organizátorom.",
"sender_mismatch_info": "Táto pozvánka bola odoslaná od {sender}, zatiaľčo organizátor v dátach kalendára je {organizer}.",
"sender_mismatch_unverified_info": "Táto pozvánka bola odoslaná od {sender}, zatiaľčo organizátor v dátach kalendára je {organizer}, a správu sa nepodarilo overiť.",
+ "attendee_mismatch_info": "Táto odpoveď bola odoslaná od {sender}, zatiaľ čo odpovedajúci účastník v dátach kalendára je {attendee}.",
+ "attendee_mismatch_unverified_info": "Táto odpoveď bola odoslaná od {sender}, zatiaľ čo odpovedajúci účastník v dátach kalendára je {attendee}, a správu sa nepodarilo overiť.",
"organizer_role": "Ste organizátorom tejto udalosti",
"your_response": "Vaša odpoveď: {status}",
"response_needed": "Vyžaduje odpoveď",
diff --git a/locales/tr/common.json b/locales/tr/common.json
index b669457e3..ad5cbf2ca 100644
--- a/locales/tr/common.json
+++ b/locales/tr/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "Bu davet doğrulanmış posta kimlik doğrulaması içermiyor. Bir şey olağandışı görünüyorsa ayrıntıları organizatörle teyit edin.",
"sender_mismatch_info": "Bu davet {sender} tarafından gönderildi; ancak takvim verisinde organizatör olarak {organizer} listeleniyor.",
"sender_mismatch_unverified_info": "Bu davet {sender} tarafından gönderildi; ancak takvim verisinde organizatör olarak {organizer} listeleniyor ve ileti doğrulanamadı.",
+ "attendee_mismatch_info": "Bu yanıt {sender} tarafından gönderildi; ancak takvim verisinde yanıtlayan katılımcı olarak {attendee} listeleniyor.",
+ "attendee_mismatch_unverified_info": "Bu yanıt {sender} tarafından gönderildi; ancak takvim verisinde yanıtlayan katılımcı olarak {attendee} listeleniyor ve ileti doğrulanamadı.",
"organizer_role": "Bu etkinliği siz düzenliyorsunuz",
"your_response": "Yanıtınız: {status}",
"response_needed": "Yanıt gerekiyor",
diff --git a/locales/uk/common.json b/locales/uk/common.json
index 02bc6fffe..4782b754b 100644
--- a/locales/uk/common.json
+++ b/locales/uk/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "Це запрошення не включає перевірену автентифікацію електронної пошти. Уточнюйте деталі в організатора, якщо щось виглядає незвичним.",
"sender_mismatch_info": "Це запрошення надіслано з {sender}, а організатор, зазначений у даних календаря, {organizer}.",
"sender_mismatch_unverified_info": "Це запрошення було надіслано з {sender}, а організатором, указаним у даних календаря, є {organizer}, і повідомлення не вдалося перевірити.",
+ "attendee_mismatch_info": "Цю відповідь було надіслано з {sender}, а учасником, який відповідає, у даних календаря є {attendee}.",
+ "attendee_mismatch_unverified_info": "Цю відповідь було надіслано з {sender}, а учасником, який відповідає, у даних календаря є {attendee}, і повідомлення не вдалося перевірити.",
"organizer_role": "Ви організовуєте цю подію",
"your_response": "Ваша відповідь: {status}",
"response_needed": "Потребує відповіді",
diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json
index 865e600b2..42a78d48f 100644
--- a/locales/zh-TW/common.json
+++ b/locales/zh-TW/common.json
@@ -567,6 +567,8 @@
"authentication_missing_info": "這封邀請未包含已驗證的郵件身分驗證資訊。若有任何可疑之處,請向主辦人確認詳細資料。",
"sender_mismatch_info": "這封邀請是由 {sender} 傳送,但行事曆資料中列出的主辦人是 {organizer}。",
"sender_mismatch_unverified_info": "這封邀請是由 {sender} 傳送,但行事曆資料中列出的主辦人是 {organizer},而且無法驗證這封郵件。",
+ "attendee_mismatch_info": "這則回覆是由 {sender} 傳送,但行事曆資料中回覆的參與者是 {attendee}。",
+ "attendee_mismatch_unverified_info": "這則回覆是由 {sender} 傳送,但行事曆資料中回覆的參與者是 {attendee},而且無法驗證這封郵件。",
"organizer_role": "您是此活動的主辦人",
"your_response": "您的回覆:{status}",
"response_needed": "待回覆",
diff --git a/locales/zh/common.json b/locales/zh/common.json
index fc53f5be2..e7bedf805 100644
--- a/locales/zh/common.json
+++ b/locales/zh/common.json
@@ -542,6 +542,8 @@
"authentication_missing_info": "此邀请不包括经过验证的邮件身份验证。如果有任何异常情况,请与组织者确认详细信息。",
"sender_mismatch_info": "此邀请是从 {sender} 发送的,而日历数据中列出的组织者是 {organizer}。",
"sender_mismatch_unverified_info": "此邀请是从 {sender} 发送的,而日历数据中列出的组织者是 {organizer},且无法验证该消息。",
+ "attendee_mismatch_info": "此回复是从 {sender} 发送的,而日历数据中作出回复的参与者是 {attendee}。",
+ "attendee_mismatch_unverified_info": "此回复是从 {sender} 发送的,而日历数据中作出回复的参与者是 {attendee},且无法验证该消息。",
"organizer_role": "您是此活动的组织者",
"your_response": "您的回复:{status}",
"response_needed": "待回复",