Несколько ящиков у одного логина, общие ящики, кто ответил, вход ящик*логин
continuous-integration/drone/pr Build is passing
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>
This commit is contained in:
@@ -31,7 +31,8 @@ class ServiceControllerTest {
|
||||
private final UserService users = mock(UserService.class);
|
||||
private final MailLists lists = mock(MailLists.class);
|
||||
private final MailDomains domains = new MailDomains("jambocheck.com", "");
|
||||
private final MailDirectory directory = new MailDirectory(users, lists, domains);
|
||||
private final com.mailserver.service.MailboxAccess access = mock(com.mailserver.service.MailboxAccess.class);
|
||||
private final MailDirectory directory = new MailDirectory(users, lists, domains, access);
|
||||
private final User existing = user(7L, "jambotronpw@jambocheck.com");
|
||||
|
||||
ServiceControllerTest() {
|
||||
@@ -40,6 +41,7 @@ class ServiceControllerTest {
|
||||
when(lists.exists(anyString())).thenReturn(Mono.just(false));
|
||||
when(lists.listsOf(anyLong())).thenReturn(Flux.just("alerts-prod@jambocheck.com"));
|
||||
when(lists.removeEverywhere(anyLong())).thenReturn(Mono.just(1L));
|
||||
when(access.removeEverywhere(anyLong())).thenReturn(Mono.just(1L));
|
||||
when(users.register(anyString(), anyString(), any())).thenAnswer(i -> Mono.just(user(8L, i.getArgument(0))));
|
||||
when(users.setActive(any(), any(Boolean.class))).thenAnswer(i -> {
|
||||
User u = i.getArgument(0);
|
||||
@@ -50,7 +52,7 @@ class ServiceControllerTest {
|
||||
}
|
||||
|
||||
private ServiceController api(String token) {
|
||||
return new ServiceController(token, users, lists, directory);
|
||||
return new ServiceController(token, users, lists, directory, access);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,6 +86,7 @@ class ServiceControllerTest {
|
||||
Mono.just(new ServiceController.AccountRequest(null, false))).block();
|
||||
assertThat(off.getBody().account().active()).isFalse();
|
||||
verify(lists).removeEverywhere(7L);
|
||||
verify(access).removeEverywhere(7L);
|
||||
|
||||
var reset = api("s3cret-token").password(AUTH, "jambotronpw@jambocheck.com").block();
|
||||
assertThat(reset.password()).isNotBlank();
|
||||
|
||||
Reference in New Issue
Block a user