Documentation ¶
Overview ¶
Package store communicates with API and caches metadata in a local database.
Index ¶
- Constants
- Variables
- func RemoveStore(cache *Cache, path, userID string) error
- type Address
- func (storeAddress *Address) APIAddress() *pmapi.Address
- func (storeAddress *Address) AddressID() string
- func (storeAddress *Address) AddressString() string
- func (storeAddress *Address) CreateMailbox(name string) error
- func (storeAddress *Address) GetMailbox(name string) (*Mailbox, error)
- func (storeAddress *Address) ListMailboxes() []*Mailbox
- type AddressInfo
- type BridgeUser
- type Cache
- type ChangeNotifier
- type Mailbox
- func (storeMailbox *Mailbox) Color() string
- func (storeMailbox *Mailbox) Delete() error
- func (storeMailbox *Mailbox) FetchMessage(apiID string) (*Message, error)
- func (storeMailbox *Mailbox) GetAPIIDsFromSequenceRange(start, stop uint32) (apiIDs []string, err error)
- func (storeMailbox *Mailbox) GetAPIIDsFromUIDRange(start, stop uint32) (apiIDs []string, err error)
- func (storeMailbox *Mailbox) GetCounts() (total, unread, unseenSeqNum uint, err error)
- func (storeMailbox *Mailbox) GetDeletedAPIIDs() (apiIDs []string, err error)
- func (storeMailbox *Mailbox) GetDelimiter() string
- func (storeMailbox *Mailbox) GetLatestAPIID() (apiID string, err error)
- func (storeMailbox *Mailbox) GetMessage(apiID string) (*Message, error)
- func (storeMailbox *Mailbox) GetNextUID() (uid uint32, err error)
- func (storeMailbox *Mailbox) GetUIDByHeader(header *mail.Header) (foundUID uint32)
- func (storeMailbox *Mailbox) GetUIDList(apiIDs []string) *uidplus.OrderedSeq
- func (storeMailbox *Mailbox) ImportMessage(enc []byte, seen bool, labelIDs []string, flags, time int64) (string, error)
- func (storeMailbox *Mailbox) IsFolder() bool
- func (storeMailbox *Mailbox) IsLabel() bool
- func (storeMailbox *Mailbox) IsSystem() bool
- func (storeMailbox *Mailbox) LabelID() string
- func (storeMailbox *Mailbox) LabelMessages(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesDeleted(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesRead(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesStarred(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesUndeleted(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesUnread(apiIDs []string) error
- func (storeMailbox *Mailbox) MarkMessagesUnstarred(apiIDs []string) error
- func (storeMailbox *Mailbox) Name() string
- func (storeMailbox *Mailbox) RemoveDeleted(apiIDs []string) error
- func (storeMailbox *Mailbox) Rename(newName string) error
- func (storeMailbox *Mailbox) UIDValidity() uint32
- func (storeMailbox *Mailbox) UnlabelMessages(apiIDs []string) error
- type Message
- func (message *Message) GetBodyStructure() (bs *pkgMsg.BodyStructure, err error)
- func (message *Message) GetHeader() []byte
- func (message *Message) GetMIMEHeader() textproto.MIMEHeader
- func (message *Message) ID() string
- func (message *Message) IncreaseBuildCount() (times uint32, err error)
- func (message *Message) IsFullHeaderCached() bool
- func (message *Message) IsMarkedDeleted() bool
- func (message *Message) Message() *pmapi.Message
- func (message *Message) SequenceNumber() (uint32, error)
- func (message *Message) SetBodyStructure(bs *pkgMsg.BodyStructure) error
- func (message *Message) SetContentTypeAndHeader(mimeType string, header mail.Header) errordeprecated
- func (message *Message) SetHeader(header []byte) error
- func (message *Message) SetSize(size int64) error
- func (message *Message) UID() (uint32, error)
- type PanicHandler
- type Store
- func (store *Store) Close() error
- func (store *Store) CloseEventLoop()
- func (store *Store) CreateDraft(kr *crypto.KeyRing, message *pmapi.Message, attachmentReaders []io.Reader, ...) (*pmapi.Message, []*pmapi.Attachment, error)
- func (store *Store) GetAddress(addressID string) (*Address, error)
- func (store *Store) GetAddressID(addr string) (id string, err error)
- func (store *Store) GetAddressInfo() (addrs []AddressInfo, err error)
- func (store *Store) GetMaxUpload() (int64, error)
- func (store *Store) GetSpace() (usedSpace, maxSpace uint, err error)
- func (store *Store) IsCombinedMode() bool
- func (store *Store) RebuildMailboxes() (err error)
- func (store *Store) Remove() (err error)
- func (store *Store) SendMessage(messageID string, req *pmapi.SendMessageReq) error
- func (store *Store) SetChangeNotifier(notifier ChangeNotifier)
- func (store *Store) TestDumpDB(tb assert.TestingT)
- func (store *Store) TestGetEventLoop() *eventLoop
- func (store *Store) TestGetLastEvent() *pmapi.Event
- func (store *Store) TestGetStoreFilePath() string
- func (store *Store) TestIsSyncRunning() bool
- func (store *Store) TestPollNow()
- func (store *Store) TestSync()
- func (store *Store) UseCombinedMode(useCombined bool) (err error)
- func (store *Store) UserID() string
Constants ¶
const ( // PathDelimiter for IMAP. PathDelimiter = "/" // UserLabelsMailboxName for IMAP. UserLabelsMailboxName = "Labels" // UserLabelsPrefix contains name with delimiter for IMAP. UserLabelsPrefix = UserLabelsMailboxName + PathDelimiter // UserFoldersMailboxName for IMAP. UserFoldersMailboxName = "Folders" // UserFoldersPrefix contains name with delimiter for IMAP. UserFoldersPrefix = UserFoldersMailboxName + PathDelimiter )
Variables ¶
var ( // ErrNoSuchAPIID when mailbox does not have API ID. ErrNoSuchAPIID = errors.New("no such api id") //nolint[gochecknoglobals] // ErrNoSuchUID when mailbox does not have IMAP UID. ErrNoSuchUID = errors.New("no such uid") //nolint[gochecknoglobals] // ErrNoSuchSeqNum when mailbox does not have IMAP ID. ErrNoSuchSeqNum = errors.New("no such sequence number") //nolint[gochecknoglobals] )
var ErrAllMailOpNotAllowed = errors.New("operation not allowed for 'All Mail' folder")
ErrAllMailOpNotAllowed is error user when user tries to do unsupported operation on All Mail folder.
Functions ¶
func RemoveStore ¶
RemoveStore removes the database file and clears the cache file.
Types ¶
type Address ¶
type Address struct {
// contains filtered or unexported fields
}
Address holds mailboxes for IMAP user (login address). In combined mode there is only one address, in split mode there is one object per address.
func (*Address) APIAddress ¶
APIAddress returns the `pmapi.Address` struct.
func (*Address) AddressString ¶
AddressString returns the address.
func (*Address) CreateMailbox ¶
CreateMailbox creates the mailbox by calling an API. Mailbox is created in the structure by processing event.
func (*Address) GetMailbox ¶
GetMailbox returns mailbox with the given IMAP name.
func (*Address) ListMailboxes ¶
ListMailboxes returns all mailboxes.
type AddressInfo ¶
type AddressInfo struct {
Address, AddressID string
}
AddressInfo is the format of the data held in the addresses bucket in the store. It allows us to easily keep an address and its ID together and serialisation/deserialisation to []byte.
type BridgeUser ¶
type BridgeUser interface { ID() string GetAddressID(address string) (string, error) IsConnected() bool IsCombinedAddressMode() bool GetPrimaryAddress() string GetStoreAddresses() []string GetClient() pmapi.Client UpdateUser(context.Context) error CloseAllConnections() CloseConnection(string) Logout() error }
BridgeUser is subset of bridge.User for use by the Store.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache caches the last event IDs for all accounts (there should be only one instance).
type ChangeNotifier ¶
type ChangeNotifier interface { Notice(address, notice string) UpdateMessage( address, mailboxName string, uid, sequenceNumber uint32, msg *pmapi.Message, hasDeletedFlag bool) DeleteMessage(address, mailboxName string, sequenceNumber uint32) MailboxCreated(address, mailboxName string) MailboxStatus(address, mailboxName string, total, unread, unreadSeqNum uint32) CanDelete(mailboxID string) (bool, func()) }
type Mailbox ¶
type Mailbox struct {
// contains filtered or unexported fields
}
Mailbox is mailbox for specific address and mailbox.
func (*Mailbox) Delete ¶
Delete deletes the mailbox by calling an API. Deletion has to be propagated to all the same mailboxes in all addresses. The propagation is processed by the event loop.
func (*Mailbox) FetchMessage ¶
FetchMessage fetches the message with the given `apiID`, stores it in the database, and returns a new store message wrapping it.
func (*Mailbox) GetAPIIDsFromSequenceRange ¶
func (storeMailbox *Mailbox) GetAPIIDsFromSequenceRange(start, stop uint32) (apiIDs []string, err error)
GetAPIIDsFromSequenceRange returns API IDs by IMAP sequence number range.
func (*Mailbox) GetAPIIDsFromUIDRange ¶
GetAPIIDsFromUIDRange returns API IDs by IMAP UID range.
API IDs are the long base64 strings that the API uses to identify messages. UIDs are unique increasing integers that must be unique within a mailbox.
func (*Mailbox) GetCounts ¶
GetCounts returns numbers of total and unread messages in this mailbox bucket.
func (*Mailbox) GetDeletedAPIIDs ¶
GetDeletedAPIIDs returns API IDs in this mailbox for message ID.
func (*Mailbox) GetDelimiter ¶
GetDelimiter returns the path separator.
func (*Mailbox) GetLatestAPIID ¶
GetLatestAPIID returns the latest message API ID which still exists. Info: not the latest IMAP UID which can be already removed.
func (*Mailbox) GetMessage ¶
GetMessage returns the `pmapi.Message` struct wrapped in `StoreMessage` tied to this mailbox.
func (*Mailbox) GetNextUID ¶
GetNextUID returns the next IMAP UID.
func (*Mailbox) GetUIDByHeader ¶
GetUIDByHeader returns UID of message existing in mailbox or zero if no match found.
func (*Mailbox) GetUIDList ¶
func (storeMailbox *Mailbox) GetUIDList(apiIDs []string) *uidplus.OrderedSeq
GetUIDList returns UID list corresponding to messageIDs in a requested order.
func (*Mailbox) ImportMessage ¶
func (*Mailbox) IsFolder ¶
IsFolder returns whether the mailbox is a folder (has "Folders/" prefix).
func (*Mailbox) IsSystem ¶
IsSystem returns whether the mailbox is one of the specific system mailboxes (has no prefix).
func (*Mailbox) LabelMessages ¶
LabelMessages adds the label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.
func (*Mailbox) MarkMessagesDeleted ¶
MarkMessagesDeleted adds local flag \Deleted. This is not propagated to API until RemoveDeleted is called.
func (*Mailbox) MarkMessagesRead ¶
MarkMessagesRead marks the message read by calling an API. It has to be propagated to metadata mailbox which is done by the event loop.
func (*Mailbox) MarkMessagesStarred ¶
MarkMessagesStarred adds the Starred label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.
func (*Mailbox) MarkMessagesUndeleted ¶
MarkMessagesUndeleted removes local flag \Deleted. This is not propagated to API.
func (*Mailbox) MarkMessagesUnread ¶
MarkMessagesUnread marks the message unread by calling an API. It has to be propagated to metadata mailbox which is done by the event loop.
func (*Mailbox) MarkMessagesUnstarred ¶
MarkMessagesUnstarred removes the Starred label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.
func (*Mailbox) RemoveDeleted ¶
RemoveDeleted sends request to API to remove message from mailbox. If the mailbox is All Mail or All Sent, it does nothing. If the mailbox is Trash or Spam and message is not in any other mailbox, messages is deleted. In all other cases the message is only removed from the mailbox. If nil is passed, all messages with \Deleted flag are removed. In other cases only messages with \Deleted flag and included in the passed list.
func (*Mailbox) Rename ¶
Rename updates the mailbox by calling an API. Change has to be propagated to all the same mailboxes in all addresses. The propagation is processed by the event loop.
func (*Mailbox) UIDValidity ¶
UIDValidity returns the current value of structure version.
func (*Mailbox) UnlabelMessages ¶
UnlabelMessages removes the label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.
type Message ¶
type Message struct {
// contains filtered or unexported fields
}
Message is wrapper around `pmapi.Message` with connection to a specific mailbox with helper functions to get IMAP UID, sequence numbers and similar.
func (*Message) GetBodyStructure ¶ added in v1.6.3
func (message *Message) GetBodyStructure() (bs *pkgMsg.BodyStructure, err error)
GetBodyStructure deserializes body structure from database. If body structure is not in database it returns nil error and nil body structure. If error occurs it returns nil body structure.
func (*Message) GetMIMEHeader ¶ added in v1.8.0
func (message *Message) GetMIMEHeader() textproto.MIMEHeader
GetMIMEHeader will return cached header from DB, parsed as a textproto.MIMEHeader.
func (*Message) IncreaseBuildCount ¶ added in v1.7.0
func (*Message) IsFullHeaderCached ¶ added in v1.7.0
IsFullHeaderCached will check that valid full header is stored in DB.
func (*Message) IsMarkedDeleted ¶
IsMarkedDeleted returns true if message is marked as deleted for specific mailbox.
func (*Message) SequenceNumber ¶
SequenceNumber returns index of message in used mailbox.
func (*Message) SetBodyStructure ¶ added in v1.6.3
func (message *Message) SetBodyStructure(bs *pkgMsg.BodyStructure) error
SetBodyStructure stores serialized body structure in database.
func (*Message) SetContentTypeAndHeader
deprecated
SetContentTypeAndHeader updates the information about content type and header of decrypted message. This should not trigger any IMAP update. NOTE: Content type depends on details of decrypted message which we want to cache.
Deprecated: Use SetHeader instead.
func (*Message) SetHeader ¶ added in v1.7.0
SetHeader checks header can be parsed and if yes it stores header bytes in database.
func (*Message) SetSize ¶
SetSize updates the information about size of decrypted message which can be used for IMAP. This should not trigger any IMAP update. NOTE: The size from the server corresponds to pure body bytes. Hence it should not be used. The correct size has to be calculated from decrypted and built message.
type PanicHandler ¶
type PanicHandler interface {
HandlePanic()
}
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is local user storage, which handles the synchronization between IMAP and PM API.
func New ¶
func New( sentryReporter *sentry.Reporter, panicHandler PanicHandler, user BridgeUser, events listener.Listener, path string, cache *Cache, ) (store *Store, err error)
New creates or opens a store for the given `user`.
func (*Store) CloseEventLoop ¶
func (store *Store) CloseEventLoop()
CloseEventLoop stops the eventloop (if it is present).
func (*Store) CreateDraft ¶
func (store *Store) CreateDraft( kr *crypto.KeyRing, message *pmapi.Message, attachmentReaders []io.Reader, attachedPublicKey, attachedPublicKeyName string, parentID string) (*pmapi.Message, []*pmapi.Attachment, error)
CreateDraft creates draft with attachments. If `attachedPublicKey` is passed, it's added to attachments. Both draft and attachments are encrypted with passed `kr` key.
func (*Store) GetAddress ¶
GetAddress returns the store address by given ID.
func (*Store) GetAddressID ¶
GetAddressID returns the ID of the given address.
func (*Store) GetAddressInfo ¶
func (store *Store) GetAddressInfo() (addrs []AddressInfo, err error)
GetAddressInfo returns information about all addresses owned by the user. The first element is the user's primary address and the rest (if present) are aliases. It tries to source the information from the store but if the store doesn't yet have it, it fetches it from the API and caches it for later.
func (*Store) GetMaxUpload ¶
GetMaxUpload returns max size of message + all attachments in bytes.
func (*Store) IsCombinedMode ¶
IsCombinedMode returns whether the store is set to combined mode.
func (*Store) RebuildMailboxes ¶
RebuildMailboxes truncates all mailbox buckets and recreates them from the metadata bucket again.
func (*Store) SendMessage ¶
func (store *Store) SendMessage(messageID string, req *pmapi.SendMessageReq) error
SendMessage sends the message.
func (*Store) SetChangeNotifier ¶
func (store *Store) SetChangeNotifier(notifier ChangeNotifier)
SetChangeNotifier sets notifier to be called once mailbox or message changes.
func (*Store) TestDumpDB ¶
TestDumpDB will dump store database content.
func (*Store) TestGetEventLoop ¶
func (store *Store) TestGetEventLoop() *eventLoop
TestGetEventLoop returns the store's event loop.
func (*Store) TestGetLastEvent ¶
TestGetLastEvent returns last event processed by the store's event loop.
func (*Store) TestGetStoreFilePath ¶
TestGetStoreFilePath returns the filepath of the store's database file.
func (*Store) TestIsSyncRunning ¶
TestIsSyncRunning returns whether the sync is currently ongoing.
func (*Store) TestPollNow ¶
func (store *Store) TestPollNow()
TestPollNow triggers a loop of the event loop.
func (*Store) UseCombinedMode ¶
UseCombinedMode sets whether the store should be set to combined mode.
Source Files ¶
- address.go
- address_mailbox.go
- address_message.go
- cache.go
- change.go
- convert.go
- cooldown.go
- event_loop.go
- mailbox.go
- mailbox_counts.go
- mailbox_ids.go
- mailbox_message.go
- message.go
- store.go
- store_address_mode.go
- store_structure_version.go
- store_test_exports.go
- sync.go
- sync_state.go
- types.go
- ulimit.go
- user.go
- user_address.go
- user_address_info.go
- user_mailbox.go
- user_message.go
- user_sync.go