continuous-integration/drone/pr Build is passing
DELETE /api/admin/mailboxes/{id} (только администратор, не свой ящик):
файлы вложений, затем строка users — папки, письма, исходники, контакты,
участие в рассылках и доступы уходят каскадом. Кнопка с подтверждением.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
120 lines
6.4 KiB
TypeScript
120 lines
6.4 KiB
TypeScript
import { Injectable, inject } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { Observable } from 'rxjs';
|
|
import { Attachment, BlacklistEntry, Contact, Draft, Folder, MailList, Mailbox, MailboxCreated, MailboxEntry, Message, Profile, ServerConfig } from './models';
|
|
|
|
/** The mail server REST API (same origin, /api). */
|
|
@Injectable({ providedIn: 'root' })
|
|
export class ApiService {
|
|
private http = inject(HttpClient);
|
|
|
|
config(): Observable<ServerConfig> { return this.http.get<ServerConfig>('/api/config'); }
|
|
|
|
// profile
|
|
me(): Observable<Profile> { return this.http.get<Profile>('/api/me'); }
|
|
updateMe(displayName: string): Observable<Profile> { return this.http.put<Profile>('/api/me', { displayName }); }
|
|
changePassword(currentPassword: string, newPassword: string): Observable<unknown> {
|
|
return this.http.put('/api/me/password', { currentPassword, newPassword });
|
|
}
|
|
|
|
// mailboxes — administrators only
|
|
mailboxes(): Observable<Mailbox[]> { return this.http.get<Mailbox[]>('/api/admin/mailboxes'); }
|
|
createMailbox(email: string, displayName: string, password: string, shared = false): Observable<MailboxCreated> {
|
|
return this.http.post<MailboxCreated>('/api/admin/mailboxes', { email, displayName, password, shared });
|
|
}
|
|
setMailboxMembers(id: number, members: string[]): Observable<Mailbox> {
|
|
return this.http.put<Mailbox>(`/api/admin/mailboxes/${id}/members`, { members });
|
|
}
|
|
// the logged-in user's mailboxes (left menu)
|
|
myMailboxes(): Observable<MailboxEntry[]> { return this.http.get<MailboxEntry[]>('/api/mailboxes'); }
|
|
mailboxSession(email: string): Observable<{ token: string; email: string }> {
|
|
return this.http.post<{ token: string; email: string }>(`/api/mailboxes/${encodeURIComponent(email)}/session`, {});
|
|
}
|
|
attachMailbox(email: string, password: string): Observable<MailboxEntry> {
|
|
return this.http.post<MailboxEntry>('/api/mailboxes/attach', { email, password });
|
|
}
|
|
leaveMailbox(email: string): Observable<void> {
|
|
return this.http.delete<void>(`/api/mailboxes/${encodeURIComponent(email)}`);
|
|
}
|
|
newMailboxPassword(id: number): Observable<MailboxCreated> {
|
|
return this.http.post<MailboxCreated>(`/api/admin/mailboxes/${id}/password`, {});
|
|
}
|
|
openMailbox(id: number): Observable<{ token: string; email: string }> {
|
|
return this.http.post<{ token: string; email: string }>(`/api/admin/mailboxes/${id}/open`, {});
|
|
}
|
|
mailLists(): Observable<MailList[]> { return this.http.get<MailList[]>('/api/admin/mailboxes/lists'); }
|
|
saveMailList(address: string, list: { folder: string; description: string; openToOutside: boolean; members: string[] }): Observable<MailList> {
|
|
return this.http.put<MailList>(`/api/admin/mailboxes/lists/${encodeURIComponent(address)}`, list);
|
|
}
|
|
deleteMailList(address: string): Observable<void> {
|
|
return this.http.delete<void>(`/api/admin/mailboxes/lists/${encodeURIComponent(address)}`);
|
|
}
|
|
setMailboxTrap(id: number, trap: boolean): Observable<Mailbox> {
|
|
return this.http.put<Mailbox>(`/api/admin/mailboxes/${id}/trap`, { trap });
|
|
}
|
|
setMailboxActive(id: number, active: boolean): Observable<Mailbox> {
|
|
return this.http.put<Mailbox>(`/api/admin/mailboxes/${id}/active`, { active });
|
|
}
|
|
deleteMailbox(id: number): Observable<void> {
|
|
return this.http.delete<void>(`/api/admin/mailboxes/${id}`);
|
|
}
|
|
|
|
// folders
|
|
folders(): Observable<Folder[]> { return this.http.get<Folder[]>('/api/folders'); }
|
|
createFolder(name: string): Observable<Folder> { return this.http.post<Folder>('/api/folders', { name }); }
|
|
renameFolder(id: number, name: string): Observable<unknown> { return this.http.put(`/api/folders/${id}`, { name }); }
|
|
deleteFolder(id: number): Observable<unknown> { return this.http.delete(`/api/folders/${id}`); }
|
|
emptyFolder(id: number): Observable<{ deleted: number }> {
|
|
return this.http.delete<{ deleted: number }>(`/api/folders/${id}/messages`);
|
|
}
|
|
|
|
// messages
|
|
messages(folderId: number): Observable<Message[]> {
|
|
return this.http.get<Message[]>('/api/messages', { params: { folderId } });
|
|
}
|
|
search(folderId: number, keyword: string): Observable<Message[]> {
|
|
return this.http.get<Message[]>('/api/messages/search', { params: { folderId, keyword } });
|
|
}
|
|
message(id: number): Observable<Message> { return this.http.get<Message>(`/api/messages/${id}`); }
|
|
updateMessage(id: number, change: { read?: boolean; flagged?: boolean; folderId?: number }): Observable<Message> {
|
|
return this.http.patch<Message>(`/api/messages/${id}`, change);
|
|
}
|
|
deleteMessage(id: number): Observable<unknown> { return this.http.delete(`/api/messages/${id}`); }
|
|
|
|
// compose
|
|
createDraft(draft: Draft): Observable<Message> { return this.http.post<Message>('/api/drafts', draft); }
|
|
updateDraft(id: number, draft: Draft): Observable<Message> { return this.http.put<Message>(`/api/drafts/${id}`, draft); }
|
|
send(draft: Draft, draftId: number | null, replyToId: number | null = null): Observable<Message> {
|
|
return this.http.post<Message>('/api/send', { ...draft, draftId, replyToId });
|
|
}
|
|
|
|
// attachments
|
|
attachments(messageId: number): Observable<Attachment[]> {
|
|
return this.http.get<Attachment[]>(`/api/messages/${messageId}/attachments`);
|
|
}
|
|
upload(messageId: number, file: File): Observable<Attachment> {
|
|
const form = new FormData();
|
|
form.append('file', file, file.name);
|
|
return this.http.post<Attachment>(`/api/messages/${messageId}/attachments`, form);
|
|
}
|
|
deleteAttachment(id: number): Observable<unknown> { return this.http.delete(`/api/attachments/${id}`); }
|
|
download(id: number): Observable<Blob> {
|
|
return this.http.get(`/api/attachments/${id}/download`, { responseType: 'blob' });
|
|
}
|
|
|
|
// contacts
|
|
contacts(): Observable<Contact[]> { return this.http.get<Contact[]>('/api/contacts'); }
|
|
addContact(contact: Contact): Observable<unknown> { return this.http.post('/api/contacts', contact); }
|
|
updateContact(id: number, contact: Contact): Observable<unknown> { return this.http.put(`/api/contacts/${id}`, contact); }
|
|
deleteContact(id: number): Observable<unknown> { return this.http.delete(`/api/contacts/${id}`); }
|
|
|
|
// blacklist
|
|
blacklist(): Observable<BlacklistEntry[]> { return this.http.get<BlacklistEntry[]>('/api/spam/blacklist'); }
|
|
block(senderEmail: string, reason: string): Observable<unknown> {
|
|
return this.http.post('/api/spam/blacklist', { senderEmail, reason });
|
|
}
|
|
unblock(senderEmail: string): Observable<unknown> {
|
|
return this.http.delete('/api/spam/blacklist', { params: { senderEmail } });
|
|
}
|
|
}
|