continuous-integration/drone/pr Build is passing
- V7: users.is_shared, mailbox_access (MEMBER от админа/Jambotron, ATTACHED по паролю ящика), messages.answered_by
- /api/mailboxes: мои ящики с непрочитанными, сессия другого ящика (JWT с claim by), подключить по паролю
(LoginGuard), убрать из меню
- общий ящик: без своего входа (веб/SMTP/IMAP), участники открывают; «прочитано» общее; ответ из веба → answered_by
- SMTP/IMAP: ящик*логин + пароль логина (как master user в Dovecot)
- открытый чужой ящик (общий, подключённый, OPEN админа): профиль и пароль не меняются (403)
- админ: создать shared, участники ящика (PUT /{id}/members); служебное API: PUT /shared/{address};
выключение аккаунта убирает и из общих ящиков
- UI: MAILBOXES в левом меню (переключение, ⊕ подключить, × убрать), shared/участники в настройках,
«Answered by» у письма
- 88 тестов; живой прогон на Postgres 17 (апгрейд V6→V7 на данных), скриншоты UI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
109 lines
3.2 KiB
Java
109 lines
3.2 KiB
Java
package com.mailserver.domain;
|
|
|
|
import org.springframework.data.annotation.Id;
|
|
import org.springframework.data.relational.core.mapping.Column;
|
|
import org.springframework.data.relational.core.mapping.Table;
|
|
|
|
import java.time.Instant;
|
|
|
|
@Table("messages")
|
|
public class Message {
|
|
|
|
@Id
|
|
private Long id;
|
|
|
|
@Column("folder_id")
|
|
private Long folderId;
|
|
|
|
@Column("sender_email")
|
|
private String senderEmail;
|
|
|
|
@Column("sender_name")
|
|
private String senderName;
|
|
|
|
@Column("recipient_email")
|
|
private String recipientEmail;
|
|
|
|
@Column("cc_email")
|
|
private String ccEmail;
|
|
|
|
@Column("subject")
|
|
private String subject;
|
|
|
|
@Column("body")
|
|
private String body;
|
|
|
|
@Column("is_html")
|
|
private boolean isHtml = false;
|
|
|
|
@Column("is_read")
|
|
private boolean isRead = false;
|
|
|
|
@Column("is_flagged")
|
|
private boolean isFlagged = false;
|
|
|
|
@Column("is_spam")
|
|
private boolean isSpam = false;
|
|
|
|
@Column("message_size")
|
|
private Long messageSize;
|
|
|
|
@Column("received_at")
|
|
private Instant receivedAt;
|
|
|
|
@Column("message_id")
|
|
private String messageId;
|
|
|
|
/** Who answered it from the web client (V7) — the login, also for a shared mailbox. */
|
|
@Column("answered_by")
|
|
private String answeredBy;
|
|
|
|
public String getAnsweredBy() { return answeredBy; }
|
|
public void setAnsweredBy(String answeredBy) { this.answeredBy = answeredBy; }
|
|
|
|
public Long getId() { return id; }
|
|
public void setId(Long id) { this.id = id; }
|
|
|
|
public Long getFolderId() { return folderId; }
|
|
public void setFolderId(Long folderId) { this.folderId = folderId; }
|
|
|
|
public String getSenderEmail() { return senderEmail; }
|
|
public void setSenderEmail(String senderEmail) { this.senderEmail = senderEmail; }
|
|
|
|
public String getSenderName() { return senderName; }
|
|
public void setSenderName(String senderName) { this.senderName = senderName; }
|
|
|
|
public String getRecipientEmail() { return recipientEmail; }
|
|
public void setRecipientEmail(String recipientEmail) { this.recipientEmail = recipientEmail; }
|
|
|
|
public String getCcEmail() { return ccEmail; }
|
|
public void setCcEmail(String ccEmail) { this.ccEmail = ccEmail; }
|
|
|
|
public String getSubject() { return subject; }
|
|
public void setSubject(String subject) { this.subject = subject; }
|
|
|
|
public String getBody() { return body; }
|
|
public void setBody(String body) { this.body = body; }
|
|
|
|
public boolean isHtml() { return isHtml; }
|
|
public void setHtml(boolean html) { isHtml = html; }
|
|
|
|
public boolean isRead() { return isRead; }
|
|
public void setRead(boolean read) { isRead = read; }
|
|
|
|
public boolean isFlagged() { return isFlagged; }
|
|
public void setFlagged(boolean flagged) { isFlagged = flagged; }
|
|
|
|
public boolean isSpam() { return isSpam; }
|
|
public void setSpam(boolean spam) { isSpam = spam; }
|
|
|
|
public Long getMessageSize() { return messageSize; }
|
|
public void setMessageSize(Long messageSize) { this.messageSize = messageSize; }
|
|
|
|
public Instant getReceivedAt() { return receivedAt; }
|
|
public void setReceivedAt(Instant receivedAt) { this.receivedAt = receivedAt; }
|
|
|
|
public String getMessageId() { return messageId; }
|
|
public void setMessageId(String messageId) { this.messageId = messageId; }
|
|
}
|